基於webpack構建的angular 1.x工程(angular篇)

基於webpack構建的angular 1.x工程(angular篇)

  上一篇基於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

controller那些要怎麼辦?

接下來問題就來了,在同一個angular應用模塊(module)中,各個控制器(controller)、過濾器(filters)、服務(services)等之間都是並列的兄弟關係,都是從屬於模塊。那咱們應該來處理這些關係呢?通過查閱過別人的項目以後,我發現其實有兩種寫法:web

  1. 把各個從屬的具體方法都寫成一個模塊,而後在模塊聲明時進行引入並聲明,就像這樣:

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'));

  這樣的寫法適合從頭開始的項目,好處是分的比較清晰。
可是對於我這個重構的項目,就會有麻煩:要改寫的文件有太多了。
這麼麻煩,我只能拋棄這種方式。

  1. 每一個模塊都直接輸出的是模塊聲明,而後只要把這個文件引入便可。
      熟悉angular的都知道,angular在整個應用中其實一個全局定義的對象。

每一個模塊在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

有什麼問題或者不對的地方歡迎指出,謝謝閱讀!

本文原創,未經受權請勿轉載。

相關文章
相關標籤/搜索