上一篇基于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
有什么问题或者不对的地方欢迎指出,谢谢阅读!
本文原创,未经受权请勿转载。