Статьи

Гибкие и легко обслуживаемые приложения Laravel + Angular Material

В этой статье мы собираемся настроить API Laravel с Angular Material для внешнего интерфейса. Мы также собираемся следовать рекомендациям, которые помогут нам масштабироваться с учетом количества разработчиков, работающих над проектом, и сложности, стоящей за ним. Большинство уроков освещают эту тему с другой точки зрения — они полностью забывают о масштабировании. Хотя это руководство не предназначено для небольших приложений, оно чрезвычайно полезно, если вы планируете работать с другими разработчиками над большим проектом.

Laravel angular material

Вот демо, построенное из Laravel и Angular Material.

Настройка Laravel

Создание проекта

Мы собираемся начать с добавления последней версии Laravel — 5.1 на момент написания статьи.

composer create - project laravel / laravel myapp -- prefer - dist 

Конфигурирование среды

Все последующие команды будут выполняться внутри каталога myapp . В оставшейся части этого урока мы будем предполагать, что вы работаете в среде Linux, если следите за ней. Если нет, рекомендуется установить Homestead Improved в качестве виртуальной среды Linux, в которой можно следовать.

 cd myapp 

Далее мы собираемся обновить наш файл .env с учетными данными для подключения к базе данных:

 DB_HOST = localhost DB_DATABASE = your - db - name DB_USERNAME = your - username DB_PASSWORD = your - password 

Как только ваше приложение будет настроено, вы должны увидеть страницу приветствия Laravel 5.

Laravel 5

DebugBar

Панель отладки Laravel — один из самых полезных пакетов Laravel.

Debugbar позволяет легко отлаживать любое из следующего:

  • исключения
  • взгляды
  • Сообщения
  • запросы
  • почты
  • авт
  • маршруты
  • Аякса
  • и более

Laravel debugbar

Итак, давайте продолжим и установим его с помощью композитора

 composer require barryvdh / laravel - debugbar 

Далее нам нужно открыть config/app.php и:

  • добавить Barryvdh\Debugbar\ServiceProvider::class, в список providers
  • добавить 'Debugbar' => Barryvdh\Debugbar\Facade::class, в список aliases

Обновите страницу, и вы увидите debugbar внизу страницы!

Debugbar запускается автоматически, если в вашем файле APP_DEBUG включен флаг .env .

Автоматизация сборки

Эликсир Laravel — это слой поверх gulp который облегчает написание глоточных задач.

Настроить

Начнем с установки gulp по всему миру. Обратите внимание, что для этого раздела вам необходимо установить nodeJS.

 npm install - g gulp 

и затем нам нужно взять несколько пакетов, которые облегчат нашу жизнь, поэтому замените ваш package.json следующим:

 { 
   "dependencies" :   { 
     "gulp-concat" :   "^2.6.0" , 
     "gulp-concat-sourcemap" :   "^1.3.1" , 
     "gulp-filter" :   "^1.0.2" , 
     "gulp-if" :   "^1.2.5" , 
     "gulp-jshint" :   "^1.9.0" , 
     "gulp-minify-css" :   "^0.3.11" , 
     "gulp-ng-annotate" :   "^1" , 
     "gulp-notify" :   "^2.0.0" , 
     "gulp-sourcemaps" :   "^1" , 
     "gulp-uglify" :   "^1" , 
     "jshint-stylish" :   "^2" , 
     "laravel-elixir" :   "^3.0.0" , 
     "laravel-elixir-livereload" :   "^1.1.1" , 
     "main-bower-files" :   "^2.1.0" 
   }, 
   "devDependencies" :   { 
     "gulp" :   "^3.9.0" 
   } 
 } 

Затем установите эти пакеты.

 npm install 

Управление внешними зависимостями

Мне нравится использовать Bower из-за его плоского дерева зависимостей , но это действительно ваше предпочтение.
Вы можете использовать npm, requirejs или просто старую версию: просмотрите и загрузите, а потом вручную проверяйте обновления .

Давайте установим беседку во всем мире.

 npm install - g bower 

Затем добавьте эту строку в .gitignore :

/bower_components

и запустите bower init чтобы создать новый файл bower.json который будет зафиксирован в хранилище.

Папка по функции

Затем мы хотим выбрать местоположение для Angular в нашей папке Laravel.

Большинство людей предпочитают добавлять его в resources/js но так как я предпочитаю иметь папку по архитектуре объектов , мы собираемся создать angular папку на корневом уровне.

Я выбрал эту настройку, потому что мы хотим, чтобы она могла масштабироваться в зависимости от количества разработчиков и сложности бизнеса.

Через несколько месяцев у нас будет папка для каждой функции. Вот пример папок, которые у нас будут внутри angular/app :

  • заголовок
    • header.html
    • header.js
    • header.less
  • авторизоваться
    • login.html
    • login.js
    • login.less
    • service.js
  • посадка
  • пользователи
  • изменить пароль
  • Сброс пароля
  • list_items
  • Добавьте предмет
  • item_details

Гораздо проще исправлять ошибки на странице list_items . Нам просто нужно открыть папку list_items где мы находим все связанные файлы для этой функции:

  • шаблоны
  • Меньше файлов
  • Угловой контроллер (ы)
  • Угловой сервис (ы).

Сравните это с необходимостью открыть папку для каждого из этих файлов при отладке одной функции.

Итак, давайте продолжим и создадим следующие папки:

  • angular
  • angular/app
  • angular/services
  • angular/filters
  • angular/directives
  • angular/config

Конфигурация эликсира

Теперь нам нужно настроить js/vendor.js для css/vendor.css файлов js/vendor.js и css/vendor.css из папки bower_components .

Затем нам нужно запустить нашу угловую папку через angular задание эликсира, которое выполняет следующее:

  • объединяет файлы нашего приложения в public/js/app.js
  • проверяется с помощью jshint (если файл .jshintrc доступен). Если файл доступен, он не будет перекомпилировать наш исходный код, если ваш код не прошел проверку.
  • автоматическая аннотация зависимостей с использованием ng-annotate

Нам нужно скомпилировать наши меньше файлов. Если вы используете Sass, вы, вероятно, знаете, как заставить его работать на Sass.

Нам также нужно скопировать наши представления из angular каталога в public каталог.

Наконец, мы собираемся настроить livereload. Мягкие перезагрузки используются для CSS, это означает, что более новая версия вашего CSS будет введена без перезагрузки страницы.

Давайте откроем gulpfile.js и заменим пример вызова функции Elixir следующим:

 var  elixir =  require ( 'laravel-elixir' ); require ( './tasks/angular.task.js' ); require ( './tasks/bower.task.js' ); require ( 'laravel-elixir-livereload' ); elixir ( function ( mix ){ mix . bower () 
         . angular ( './angular/' ) 
         . less ( './angular/**/*.less' ,   'public/css' ) 
         . copy ( './angular/app/**/*.html' ,   'public/views/app/' ) 
         . copy ( './angular/directives/**/*.html' ,   'public/views/directives/' ) 
         . copy ( './angular/dialogs/**/*.html' ,   'public/views/dialogs/' ) 
         . livereload ([ 
             'public/js/vendor.js' , 
             'public/js/app.js' , 
             'public/css/vendor.css' , 
             'public/css/app.css' , 
             'public/views/**/*.html' 
         ],   { liveCSS :   true }); 
 }); 

Если вы заметили, я загружаю несколько пользовательских задач, поэтому вам просто нужно создать папку tasks в корневом каталоге проекта и создать эти 2 файла:

задачи / angular.task.js

 /*Elixir Task *copyrights to https://github.com/HRcc/laravel-elixir-angular */ 
 var  gulp =   require ( 'gulp' ); 
 var  concat =   require ( 'gulp-concat' ); 
 var  sourcemaps =   require ( 'gulp-sourcemaps' ); 
 var  jshint =   require ( 'gulp-jshint' ); 
 var  stylish =   require ( 'jshint-stylish' ); 
 var  uglify =   require ( 'gulp-uglify' ); 
 var  ngAnnotate =   require ( 'gulp-ng-annotate' ); 
 var  notify =   require ( 'gulp-notify' ); 
 var  gulpif =   require ( 'gulp-if' ); 

 var   Elixir   =   require ( 'laravel-elixir' ); 

 var   Task   =   Elixir . Task ; 

 Elixir . extend ( 'angular' ,   function ( src ,  output ,  outputFilename )   { 

     var  baseDir =  src ||   Elixir . config . assetsPath +   '/angular/' ; 

     new   Task ( 'angular in '   +  baseDir ,   function ()   { 
         // Main file has to be included first. 
         return  gulp . src ([ baseDir +   "main.js" ,  baseDir +   "**/*.js" ]) 
             . pipe ( jshint ()) 
             . pipe ( jshint . reporter ( stylish )) 
             //.pipe(jshint.reporter('fail')).on('error', onError) //enable this if you want to force jshint to validate 
             . pipe ( gulpif (!  config . production ,  sourcemaps . init ())) 
             . pipe ( concat ( outputFilename ||   'app.js' )) 
             . pipe ( ngAnnotate ()) 
             . pipe ( gulpif ( config . production ,  uglify ())) 
             . pipe ( gulpif (!  config . production ,  sourcemaps . write ())) 
             . pipe ( gulp . dest ( output ||  config . js . outputFolder )) 
             . pipe ( notify ({ title :   'Laravel Elixir' , subtitle :   'Angular Compiled!' , icon :  __dirname +   '/../node_modules/laravel-elixir/icons/laravel.png' , message :   ' ' 
             })); 
     }). watch ( baseDir +   '/**/*.js' ); 

 }); 

задачи / bower.task.js

 /*Elixir Task for bower * Upgraded from https://github.com/ansata-biz/laravel-elixir-bower */ 
 var  gulp =  require ( 'gulp' ); 
 var  mainBowerFiles =  require ( 'main-bower-files' ); 
 var  filter =  require ( 'gulp-filter' ); 
 var  notify =  require ( 'gulp-notify' ); 
 var  minify =  require ( 'gulp-minify-css' ); 
 var  uglify =  require ( 'gulp-uglify' ); 
 var  concat_sm =  require ( 'gulp-concat-sourcemap' ); 
 var  concat =  require ( 'gulp-concat' ); 
 var  gulpIf =  require ( 'gulp-if' ); 

 var   Elixir   =  require ( 'laravel-elixir' ); 

 var   Task   =   Elixir . Task ; 

 Elixir . extend ( 'bower' ,   function ( jsOutputFile ,  jsOutputFolder ,  cssOutputFile ,  cssOutputFolder )   { 

     var  cssFile =  cssOutputFile ||   'vendor.css' ; 
     var  jsFile =  jsOutputFile ||   'vendor.js' ; 

     if   (! Elixir . config . production ){ concat =  concat_sm ; 
     } 

     var  onError =   function   ( err )   { notify . onError ({ title :   "Laravel Elixir" , subtitle :   "Bower Files Compilation Failed!" , message :   "Error: <%= error.message %>" , icon :  __dirname +   '/../node_modules/laravel-elixir/icons/fail.png' 
         })( err ); 
         this . emit ( 'end' ); 
     }; 

     new   Task ( 'bower-js' ,   function ()   { 
         return  gulp . src ( mainBowerFiles ()) 
             . on ( 'error' ,  onError ) 
             . pipe ( filter ( '**/*.js' )) 
             . pipe ( concat ( jsFile ,   { sourcesContent :   true })) 
             . pipe ( gulpIf ( Elixir . config . production ,  uglify ())) 
             . pipe ( gulp . dest ( jsOutputFolder ||   Elixir . config . js . outputFolder )) 
             . pipe ( notify ({ title :   'Laravel Elixir' , subtitle :   'Javascript Bower Files Imported!' , icon :  __dirname +   '/../node_modules/laravel-elixir/icons/laravel.png' , message :   ' ' 
             })); 
     }). watch ( 'bower.json' ); 


     new   Task ( 'bower-css' ,   function (){ 
         return  gulp . src ( mainBowerFiles ()) 
             . on ( 'error' ,  onError ) 
             . pipe ( filter ( '**/*.css' )) 
             . pipe ( concat ( cssFile )) 
             . pipe ( gulpIf ( config . production ,  minify ())) 
             . pipe ( gulp . dest ( cssOutputFolder ||  config . css . outputFolder )) 
             . pipe ( notify ({ title :   'Laravel Elixir' , subtitle :   'CSS Bower Files Imported!' , icon :  __dirname +   '/../node_modules/laravel-elixir/icons/laravel.png' , message :   ' ' 
             })); 
     }). watch ( 'bower.json' ); 

 }); 

Эти 2 задания могут показаться немного сложными, но вам не нужно об этом беспокоиться. Вы здесь, чтобы ускорить процесс разработки, а не тратить время на настройку инструментов сборки.

Причина, по которой я не использую некоторые из доступных узловых модулей, которые доступны онлайн, заключается в том, что на момент написания они медленны и часто ограничены в функциональности. Наслаждайтесь!

Настройка AngularJS

Установка

Давайте начнем с загрузки последней версии Angular 1

 bower install angular #1 --save 

Не забудьте флаг --save потому что мы хотим, чтобы он был сохранен в bower.json

Теперь мы можем запустить gulp && gulp watch .

Настройка основного модуля

Давайте начнем с настройки angular/main.js

 ( function (){ 
 "use strict" ; 

 var  app =  angular . module ( 'app' , 
         [ 
         'app.controllers' , 
         'app.filters' , 
         'app.services' , 
         'app.directives' , 
         'app.routes' , 
         'app.config' 
         ]); angular . module ( 'app.routes' ,   []); angular . module ( 'app.controllers' ,   []); angular . module ( 'app.filters' ,   []); angular . module ( 'app.services' ,   []); angular . module ( 'app.directives' ,   []); angular . module ( 'app.config' ,   []); 
     })(); 

Соединение Laravel & Angular

Обслуживание приложения

Нам нужно создать новый контроллер с помощью ремесленника.

 php artisan make : controller AngularController   -- plain 
 AngularController . php public   function  serveApp (){ 
     return  view ( 'index' ); 
 } 

и затем замените существующий Route::get('/', ...) в routes.php следующим:

 Route :: get ( '/' ,   'AngularController@serveApp' ); 

Поначалу это кажется бесполезным, но мне нравится хранить логику вне файла Routes, поэтому я предпочитаю, чтобы там не было замыканий. В конце концов, мы собираемся использовать этот контроллер для других методов, таких как неподдерживаемая страница браузера.

Затем нам нужно создать view resources/views/index.blade.php и добавить этот HTML:

 <html   ng-app = "app" > 
 <head> 
     <link   rel = "stylesheet"   href = "/css/vendor.css" > 
     <link   rel = "stylesheet"   href = "/css/app.css" > 
 </head> 
 <body> 

     <md-button   class = "md-raised md-primary" > Welcome to Angular Material </md-button> 

     <script   src = "/js/vendor.js" ></script> 
     <script   src = "/js/app.js" ></script> 
 </body> 
 </html> 

Неподдерживаемый браузер

Angular Material предназначен для вечнозеленых браузеров, поэтому нам нужно добавить страницу для неподдерживаемых (IE <= 10).

Мы начнем с добавления следующего условного комментария в <head> нашего представления index.blade.php :

 <!--[if lte IE 10]> <script type="text/javascript">document.location.href ='/unsupported-browser'</script> <![endif]--> 

Это перенаправит пользователя с неподдерживаемым браузером на /unsupported-browser , маршрут, который мы должны обработать в routes.php :

 Route :: get ( '/unsupported-browser' ,   'AngularController@unsupported' ); 

Затем внутри AngularController мы создаем unsupported метод:

 public   function  unsupported (){ 
     return  view ( 'unsupported' ); 
 } 

Наконец, мы создаем представление unsupported.blade.php и выводим сообщение, сообщающее пользователю, что ему необходимо перейти на современный браузер.

Потянув в угловой материал

Angular Material — это реализация Material Design в Angular.js. Он предоставляет набор повторно используемых, хорошо протестированных и доступных компонентов пользовательского интерфейса на основе системы Material Design.

Установка

Сначала мы вытащим угловой материал, используя Bower:

 bower install angular - material -- save 

Затем мы добавляем модуль app.controllers модули app.controllers и app.config :

 angular . module ( 'app.controllers' ,   [ 'ngMaterial' ]); angular . module ( 'app.config' ,   [ 'ngMaterial' ]); 

Наконец, мы снова запускаем gulp watch .

Пользовательские темы

Возможно, вам нравится ощущение, которое Angular Material придает вашему приложению, но вы беспокоитесь, что оно будет выглядеть точно так же, как Angular Material.

Мы хотим применить некоторые рекомендации по брендингу к теме, поэтому нам нужно создать новый поставщик конфигурации для Angular Material, который позволит нам указать 3 основных цвета для нашей темы:

 /angular/ config / theme . js : 


 ( function (){ 
     "use strict" ; angular . module ( 'app.config' ). config (   function ( $mdThemingProvider )   { 
         /* For more info, visit https://material.angularjs.org/#/Theming/01_introduction */ $mdThemingProvider . theme ( 'default' ) 
         . primaryPalette ( 'teal' ) 
         . accentPalette ( 'cyan' ) 
         . warnPalette ( 'red' ); 
     }); 

 })(); 

Настройка UI-роутера

ui-router является де-факто решением для гибкой маршрутизации с вложенными представлениями.

Установка

Давайте начнем с использования этой беседки:

 bower install ui - router -- save 

Затем добавьте модуль app.controllers модули app.controllers и app.controllers :

 angular . module ( 'app.routes' ,   [ 'ui.router' ]); angular . module ( 'app.controllers' ,   [ 'ngMaterial' ,   'ui.router' ]); 

Затем мы снова запускаем gulp watch .

Настройка маршрутов

Теперь нам нужно настроить наш файл маршрутов. Давайте продолжим и создадим angular/routes.js

 ( function (){ 
     "use strict" ; angular . module ( 'app.routes' ). config (   function ( $stateProvider ,  $urlRouterProvider )   { 

         var  getView =   function (  viewName ){ 
             return   '/views/app/'   +  viewName +   '/'   +  viewName +   '.html' ; 
         }; $urlRouterProvider . otherwise ( '/' ); $stateProvider . state ( 'landing' ,   { url :   '/' , views :   { main :   { templateUrl :  getView ( 'landing' ) 
                 } 
             } 
         }). state ( 'login' ,   { url :   '/login' , views :   { main :   { templateUrl :  getView ( 'login' ) 
                 }, footer :   { templateUrl :  getView ( 'footer' ) 
                 } 
             } 
         }); 

     }   ); 
 })(); 

Мы создали 2 маршрута, один для целевой страницы, а другой для страницы входа. Обратите внимание, что у нас есть несколько именованных представлений. Нам нужно добавить это к нашему основному представлению внутри <body> :

 <div   ui-view = "main" ></div> 
 <div   ui-view = "footer" ></div> 

Затем мы создаем следующие папки и файлы внутри angular/app :

  • landing/landing.html с выводом Landing view
  • login/login.html с выводом login/login.html
  • footer/footer.html с выводом footer/footer.html Footer view

Теперь, когда вам нужно добавить новую страницу, вам просто нужно добавить новый .state() .

Настройка Restangular

Restangular — это служба AngularJS, которая упрощает обычные вызовы ajax для API RESTful.

Установка

Restangular идеально подходит для нашего Laravel API.

Давайте возьмем последнюю версию Restangular, выполнив следующее:

 bower install restangular -- save 

Затем добавьте модуль app.controllers модуль app.controllers :

 angular / main . js : angular . module ( 'app.controllers' ,   [ 'ngMaterial' ,   'ui.router' ,   'restangular' ]); 

Затем снова запустите gulp watch .

Давайте настроим пример конечной точки API.

 php artisan make : controller DataController   -- plain 
 DataController . php : 

 public   function  index (){ 
     return   [ 'data' ,   'here' ]; 
 } 
 app\Http\routes . php : 

 Route :: get ( '/data' ,   'DataController@index' ); 

Пример использования:

 Restangular . all ( 'data' ). doGET (). then ( function ( response ){ window . console . log ( response ); 
 }); 

Тост

Тост предоставляет простой отзыв об операции в небольшом всплывающем окне.

Toast

Так как мы собираемся использовать тосты в нашем приложении, мы собираемся создать сервис тостов angular/services/toast.js

 ( function (){ 
     "use strict" ; angular . module ( "app.services" ). factory ( 'ToastService' ,   function (  $mdToast ){ 

         var  delay =   6000 , position =   'top right' , action =   'OK' ; 

         return   { show :   function ( content )   { 
                 return  $mdToast . show ( $mdToast . simple () 
                     . content ( content ) 
                     . position ( position ) 
                     . action ( action ) 
                     . hideDelay ( delay ) 
                     ); 
             } 
         }; 
     }); 
 })(); 

А теперь вот как мы можем использовать это в нашем приложении:

 ( function (){ 
     "use strict" ; angular . module ( 'app.controllers' ). controller ( 'TestCtrl' ,   function (   ToastService   ){ 
                     ToastService . show ( 'User added successfully' ); 
             }; 

         }); 

 })(); 

Диалоги

Диалоги — одна из самых полезных функций, доступных в Angular Material. Они очень похожи на модалы в Twitter Bootstrap.

Material Dialog

Диалоги являются ключевым компонентом в /angular/services/dialog.js приложениях, поэтому мы напишем мощный диалоговый сервис /angular/services/dialog.js

 ( function (){ 
     "use strict" ; angular . module ( "app.services" ). factory ( 'DialogService' ,   function (  $mdDialog ){ 

         return   { fromTemplate :   function (  template ,  $scope )   { 

                 var  options =   { templateUrl :   '/views/dialogs/'   +  template +   '/'   +  template +   '.html' 
                 }; 

                 if   (  $scope ){ options . scope =  $scope . $new (); 
                 } 

                 return  $mdDialog . show ( options ); 
             }, hide :   function (){ 
                 return  $mdDialog . hide (); 
             }, alert :   function ( title ,  content ){ $mdDialog . show ( $mdDialog . alert () 
                     . title ( title ) 
                     . content ( content ) 
                     . ok ( 'Ok' ) 
                     ); 
             } 
         }; 
     }); 
 })(); 

Мы создали 3 метода внутри этого сервиса:

  • alert(title, content) позволяет нам отображать диалог с заголовком и сообщением. Полезно для сообщений об ошибках и успехах
  • hide() скрывает диалог
  • fromTemplate(template, $scope) создает диалог из шаблона, хранящегося в /angular/dialogs/ . Полезно для диалогов Login, Reigster и т. Д. Вы можете создать свой собственный компонент в каталоге /angular/dialogs/ используя одну и ту же папку, используя особый подход. Вы также можете передать $scope в диалоговое окно, которое даст вам доступ к $parent scope из контроллера диалогового окна.

Нам просто нужно исправить конфигурацию Elixir, чтобы посмотреть и скопировать папку /angular/dialogs :

   . copy ( 'angular/dialogs/**/*.html' ,   'public/views/dialogs/' ); 

А теперь вот как мы можем использовать это в нашем приложении:

 ( function   (){ 
     "use strict" ; angular . module ( 'app.controllers' ). controller ( 'DialogTestCtrl' ,   function   ( $scope ,   DialogService ){ $scope . addUser =   function (){ 
                 return   DialogService . fromTemplate ( 'add_user' ,  $scope ); 
             }; $scope . success =   function (){ 
                 return   DialogService . alert ( 'Success' ,   'User created successfully!' ); 
             }; 


         }); 

 })(); 

развертывание

Вот простой bash-скрипт, который мы собираемся использовать для развертывания. Вы можете сохранить его как deploy.sh .

Вам просто нужно добавить его с помощью команды ssh к вашему серверу ssh@your-domain .

 php artisan route : clear php artisan config : clear git pull php artisan migrate composer install php artisan route : cache php artisan config : cache php artisan optimize 

Первые две команды очищают кэш маршрута и конфигурации, который затем будет сгенерирован снова после извлечения нового кода. Это значительно повысит производительность вашего приложения при работе в производстве.

Не забывайте, что любое изменение конфигурации / маршрутизации не вступит в силу, пока вы снова не очистите кеш.

Качество кода

Обеспечение качества кода помогает поддерживать большие проекты. Вы не хотите в конечном итоге получить ужасную кодовую базу через несколько месяцев. Это совершенно необязательно, но я бы порекомендовал вам настроить некоторые автоматизированные инструменты качества кода.

Начнем с установки необходимых узловых модулей:

 npm install - g jshint jscs 

EditorConfig

EditorConfig помогает нам поддерживать согласованный стиль кодирования между различными редакторами и IDE.
Это особенно полезно, когда у вас есть много разработчиков / участников, работающих над одним и тем же проектом.

Вы не хотите, чтобы кто-то вставлял код с пробелами вместо табуляции или наоборот, CRLF в качестве окончания строки вместо LF, или наоборот.

Давайте создадим файл .editorconfig на корневом уровне. Вы можете переключаться между CRLF и LF, символами табуляции и пробелами и т. Д. Все зависит от вашего стиля кодирования.

 root =   true 

 [*] insert_final_newline =   false charset =  utf - 8 end_of_line =  lf [*.{ js , html }] indent_size =   4 indent_style =  tab trim_trailing_whitespace =   true 

 [{ package . json , bower . json ,. jscs . json }] indent_style =  space indent_size =   2 

 [*. sh ] end_of_line =  lf 

В зависимости от вашего редактора кода, вам может понадобиться скачать плагин для editorConfig.

Это также удобно, когда вы работаете над более чем одним проектом, используя один и тот же текстовый редактор, и у каждого проекта есть свои рекомендации по стилю кодирования.

JSHINT

Jshint — это инструмент качества кода Javascript, который помогает обнаруживать ошибки и потенциальные проблемы в коде Javascript.

Он также обеспечивает соблюдение правил кодирования в вашей команде.

Нам нужно создать файл .jshintrc на корневом уровне проекта.
Вы можете просмотреть доступные опции для jshint здесь .
Обратите внимание, что когда вы добавляете файл .jshintrc , angular задание, которое мы имеем в нашем gulpfile, не будет перекомпилировать наш код, если он не проверяется в соответствии с jshint.

Вот рекомендуемый jshintrc для нашего сценария. Не стесняйтесь изменять его в соответствии с вашим стилем кодирования.

 { 
   "browser" :   true , 
   "bitwise" :   true , 
   "immed" :   true , 
   "newcap" :   false , 
   "noarg" :   true , 
   "noempty" :   true , 
   "nonew" :   true , 
   "maxlen" :   140 , 
   "boss" :   true , 
   "eqnull" :   true , 
   "eqeqeq" :   true , 
   "expr" :   true , 
   "strict" :   true , 
   "loopfunc" :   true , 
   "sub" :   true , 
   "undef" :   true , 
   "globals" :   { 
     "angular" :   false , 
     "describe" :   false , 
     "it" :   false , 
     "expect" :   false , 
     "beforeEach" :   false , 
     "afterEach" :   false , 
     "module" :   false , 
     "inject" :   false 
   } 
 } 

ОНК

JSCS — это стиль кода для программного обеспечения вашего руководства по стилю.

Мы собираемся создать файл .jscs.json на корневом уровне.
Не стесняйтесь изменять его в зависимости от вашего стиля.

 { 
   "requireCurlyBraces" :   [ 
     "if" , 
     "else" , 
     "for" , 
     "while" , 
     "do" 
   ], 
   "requireSpaceAfterKeywords" :   [ 
     "if" , 
     "for" , 
     "while" , 
     "do" , 
     "switch" , 
     "return" 
   ], 
   "disallowSpacesInFunctionExpression" :   { 
     "beforeOpeningRoundBrace" :   true 
   }, 
   "disallowTrailingWhitespace" :   true , 
   "disallowMixedSpacesAndTabs" :   true , 
   "requireMultipleVarDecl" :   true , 
   "requireSpacesInsideObjectBrackets" :   "all" , 
   "requireSpaceBeforeBinaryOperators" :   [ 
     "+" , 
     "-" , 
     "/" , 
     "*" , 
     "=" , 
     "==" , 
     "===" , 
     "!=" , 
     "!==" 
   ], 
   "disallowSpaceAfterPrefixUnaryOperators" :   [ 
     "++" , 
     "--" , 
     "+" , 
     "-" 
   ], 
   "disallowSpaceBeforePostfixUnaryOperators" :   [ 
     "++" , 
     "--" 
   ], 
   "disallowKeywords" :   [ 
     "with" 
   ], 
   "disallowKeywordsOnNewLine" :   [ 
     "else" 
   ], 
   "excludeFiles" :   [ "node_modules/**" ] 
 } 

PHPCS

Как и в случае с jshint, нам необходимо обеспечить чистоту и согласованность кода для наших файлов PHP.

Давайте начнем с установки phpcs глобально:

 composer global require "squizlabs/php_codesniffer=*" 

Теперь мы можем использовать следующую команду для проверки папки app :

 phpcs -- standard = psr2 app / 

Крутая вещь в том, что мы можем использовать PSR2 в качестве стандарта кодирования, который используется Laravel, поэтому нам не нужно настраивать пользовательский файл конфигурации.

Git крючки

Jshint и jscs являются отличными инструментами, но их нужно применять автоматически, иначе мы забудем замкнуть наш код.

При желании вы можете установить соответствующие плагины линтера для вашего текстового редактора или IDE, но один из рекомендуемых способов сделать это — запустить эти линтеры как часть процесса git commit.

Создайте .git/hooks/pre-commit если он не существует, и добавьте следующее:

 #!/bin/sh jscs angular /**/*. js jshint angular /**/*. js phpcs -- standard = psr2 app / exec 1 >& 2 

Затем запустите chmod +x .git/hooks/pre-commit .

Не забудьте добавить это для каждого разработчика, который присоединяется к вашей команде, и каждый раз, когда кто-то толкает, он будет автоматически предупрежден о возможных проблемах.

Вывод

Эта статья помогла нам настроить масштабируемое приложение Laravel and Angular Material. Вы также можете получить исходный код этого руководства на github: laravel5-angular-material-starter . Если вы использовали Angular с Bootstrap, я бы порекомендовал вам попробовать Angular Material. У вас есть вопросы? Я хотел бы знать, что вы думаете. Просто дайте мне знать в комментариях!