上一篇基於webpack構建的angular 1.x 工程(一)webpack篇裏咱們已經成功構建了整個項目的打包配置。接下來咱們要繼續讓angular在工程裏跑起來。html
以前的工程因爲是用gulp打包的,具體原理我不太懂,不過貌似會把全部的js自動注入到index.html中。因爲js不少,因此爲了避免互相干擾,產生全局變量污染的問題,它裏面全部angular都是用當即執行函數表達式(IIFE)來寫的:webpack
(function(){ 'use strict'; angular.module("app.core",[ 'ngCookies', 'angular-cache' ]); })();
這樣的寫法在webpack是沒必要要的了,webpack是根據js之間的依賴關係來加載打包項目的。不一樣的模塊之間webpack都會有標識來標誌,因此不會說存在干擾和污染的問題。那咱們應該怎麼寫呢?要寫成AMD/CMD規範形式的。爲了方便理解,咱們把當即執行函數表達式去掉,改爲這樣的:git
const ngCookies = require('angular-cookies') const ngCache = require('angular-cache') module.exports = angular.module("app.core",[ ngCookies, ngCache ]);
這個是符合webpack要求的寫法。首先先引入咱們須要的模塊,而後編寫咱們的模塊,最後輸出咱們要暴露給外部調用的接口。因而我就把全部IIFE都改爲了這種形式。github
接下來問題就來了,在同一個angular應用模塊(module)中,各個控制器(controller)、過濾器(filters)、服務(services)等之間都是並列的兄弟關係,都是從屬於模塊。那咱們應該來處理這些關係呢?通過查閱過別人的項目以後,我發現其實有兩種寫法:web
main.controller.jsnpm
module.exports =function mainCtrl($scope, $http, $stateParams, $state, $rootScope, $filter) { // your controller goes here }
index.jsgulp
angular.module("app",[]) .controller("mainCtrl", [$scope, $http, $stateParams, $state, $rootScope, $filter,require('./main.controller')]);
這樣的其實也能夠輸出一個數組,像這樣:segmentfault
main.controller.js數組
module.exports =[[$scope, $http, $stateParams, $state, $rootScope, $filter, function mainCtrl($scope, $http, $stateParams, $state, $rootScope, $filter) { // your controller goes here }]
相對應的,主要入口要這樣寫:cookie
index.js
angular.module("app",[]) .controller("mainCtrl", require('./main.controller'));
這樣的寫法適合從頭開始的項目,好處是分的比較清晰。
可是對於我這個重構的項目,就會有麻煩:要改寫的文件有太多了。
這麼麻煩,我只能拋棄這種方式。
每一個模塊在angular裏註冊以後,都會在angular裏找獲得。
這樣的話,只要確保運行下面這段代碼便可:
angular.module("app") .controller("mainCtrl", [$scope,mainCtrl($scope){ // your controller goes here }]);
也就是說,我只要引用了這段代碼,也算把這段代碼運行了。
那這樣的我就能夠這樣寫:
main.controller.js
module.exports = angular.module("app") .controller("mainCtrl", [$scope,mainCtrl($scope){ // your controller goes here }]);
index.js
angular.module("app",[]) require('./main.controller')
在main.controller.js
我直接輸出的是angular聲明app模塊的controller,而後在index.js
定義模塊以後,把這個文件引入以後,就至關於同時聲明瞭這個controller,免去大量改動代碼的麻煩。不過另外一個問題出現了:我這裏雖然免去了大量改動代碼的麻煩,可是我那麼多的controller,真的要一一寫路徑來引用嗎?這樣仍是麻煩啊。不要驚慌。webpack已經預想到你這有這個問題了,特地寫了一個能夠引用大量文件的方法給你:require.context
。這個方法可讓你查詢指定路徑的指定文件類型,而後引用進來。咱們這裏因爲已經分類放好了,全部的controller都放在/app/module
目錄下面,所以查找也是垂手可得的事。因此咱們的index.js
能夠寫成這樣:
module.exports = angular.module("app",[]); //把全部js文件引入 function importAll (r) { r.keys().forEach(r); } importAll(require.context('./', true, /\.js$/));
這樣就解決了那些controller,filters等的問題。具體require.context
的用法[參考這裏]()
當咱們往咱們的模塊注入其餘模塊(本身寫的或者angular插件)的時候,這個環節也有些要注意的地方。
首先,咱們知道,angular注入其餘模塊的時候,其實只須要寫注入模塊的名字就能夠了,angular能夠自行去尋找相應的模塊。這樣的話,咱們像上面那樣寫的模塊聲明,直接輸出其實會有問題:
app.core.module.js
module.exports = angular.module("app.core",[])
這裏其實輸出的是angular的模塊,並非模塊的名字。若是咱們直接引用的話,像這樣:
index.js
var appCore = require('./modules/appCore.module.js') module.exports = angular.module("app",[appCore]);
這樣的話,angular就會報錯:
Error: [ng:areq] Argument 'module' is not a function, got Object
要解決這個問題其實很簡單,只要調用angular的.name
方法就能夠了,因此上面能夠改寫成這樣:
app.core.module.js
module.exports = angular.module("app.core",[]).name
或者這樣改:
index.js
var appCore = require('./modules/appCore.module.js') module.exports = angular.module("app",[appCore.name]);
兩種方法選一個執行便可。
其實若是是插件的話,你在npm
安裝的插件通常都不用擔憂這個問題,畢竟人家早就想到會有這個問題了。可是若是是其餘途徑弄來的話,這個就複雜了。
上面提到的是插件注入可能會遇到的問題之一。然而還有一種狀況。
這種狀況就是插件也使用了IIFE(當即執行函數表達式)。聽起來就很煩。本身的代碼,本身知道怎麼寫的,因此改起來不會怎麼出問題,可是別人的代碼的話就不必定了。爲了不錯誤,我選擇不改動插件的代碼。而是,直接在打包的時候分開打包,而後直接注入的時候寫上插件名字便可以注入成功。詳細能夠看個人webpack配置。
以上就是用webpack打包angular 1.x 的時候寫angular所須要注意的地方。若是想看webpack的配置能夠查看我前一篇文章:
基於webpack構建的angular 1.x 工程(一)webpack篇
用於參考的一位前輩的相似項目,讓你們也參考一下:
https://github.com/IamBusy/webpack-angular
想看詳細代碼,能夠訪問個人項目地址
https://github.com/homerious/angular-ionic-webpack
有什麼問題或者不對的地方歡迎指出,謝謝閱讀!
本文原創,未經受權請勿轉載。