资讯专栏INFORMATION COLUMN

基于webpack构建的angular 1.x工程(angular篇)

jerry / 700人阅读

摘要:基于构建的工程篇上一篇基于构建的工程一篇里我们已经成功构建了整个项目的打包配置。不同的模块之间都会有标识来标志,所以不会说存在干扰和污染的问题。但是对于我这个重构的项目,就会有麻烦要改写的文件有太多了。然而还有一种情况。

基于webpack构建的angular 1.x工程(angular篇)

  上一篇基于webpack构建的angular 1.x 工程(一)webpack篇里我们已经成功构建了整个项目的打包配置。接下来我们要继续让angular在工程里跑起来。

首先要知道怎么改写

之前的工程由于是用gulp打包的,具体原理我不太懂,不过貌似会把所有的js自动注入到index.html中。由于js很多,所以为了不互相干扰,产生全局变量污染的问题,它里面所有angular都是用立即执行函数表达式(IIFE)来写的:

(function(){
    "use strict";

    angular.module("app.core",[ 
        "ngCookies",
        "angular-cache"
    ]);
})();

  这样的写法在webpack是不必要的了,webpack是根据js之间的依赖关系来加载打包项目的。不同的模块之间webpack都会有标识来标志,所以不会说存在干扰和污染的问题。那我们应该怎么写呢?要写成AMD/CMD规范形式的。为了方便理解,我们把立即执行函数表达式去掉,改成这样的:

const ngCookies = require("angular-cookies")
const ngCache = require("angular-cache")
module.exports = angular.module("app.core",[ 
                         ngCookies,
                         ngCache
                     ]);

  这个是符合webpack要求的写法。首先先引入我们需要的模块,然后编写我们的模块,最后输出我们要暴露给外部调用的接口。于是我就把所有IIFE都改成了这种形式。

controller那些要怎么办?

接下来问题就来了,在同一个angular应用模块(module)中,各个控制器(controller)、过滤器(filters)、服务(services)等之间都是并列的兄弟关系,都是从属于模块。那我们应该来处理这些关系呢?经过查阅过别人的项目之后,我发现其实有两种写法:

把各个从属的具体方法都写成一个模块,然后在模块声明时进行引入并声明,就像这样:

main.controller.js

module.exports =function mainCtrl($scope, $http, $stateParams, $state, $rootScope, $filter) {
    // your controller goes here
}

index.js

angular.module("app",[])
    .controller("mainCtrl",  [$scope, $http, $stateParams, $state, $rootScope, $filter,require("./main.controller")]);

  这样的其实也可以输出一个数组,像这样:

main.controller.js

module.exports =[[$scope, $http, $stateParams, $state, $rootScope, $filter, function mainCtrl($scope, $http, $stateParams, $state, $rootScope, $filter) {
    // your controller goes here
}]

  相对应的,主要入口要这样写:

index.js

angular.module("app",[])
    .controller("mainCtrl",  require("./main.controller"));

  这样的写法适合从头开始的项目,好处是分的比较清晰。
但是对于我这个重构的项目,就会有麻烦:要改写的文件有太多了。
这么麻烦,我只能抛弃这种方式。

每个模块都直接输出的是模块声明,然后只要把这个文件引入即可。
  熟悉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

有什么问题或者不对的地方欢迎指出,谢谢阅读!

本文原创,未经授权请勿转载。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/89468.html

相关文章

  • 基于webpack构建angular 1.x 工程(一)webpack

    摘要:基于构建的工程一篇现在都已经出到的版本了,可我对它的认识还是停留在的版本。然后是写启动的命令行,也就是上面的这样写的意思是,当你输入你的命令名字就会让执行你对应命令的语句。我们首先把基本的配置引进来。 基于webpack构建的angular 1.x 工程(一)webpack篇   现在AngularJS都已经出到4.x的版本了,可我对它的认识还是停留在1.x的版本。   之前用它是为...

    Anleb 评论0 收藏0
  • 前端每周清单半年盘点之 Angular

    摘要:延伸阅读学习与实践资料索引与前端工程化实践前端每周清单半年盘点之篇前端每周清单半年盘点之与篇前端每周清单半年盘点之篇 前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点;分为新闻热点、开发教程、工程实践、深度阅读、开源项目、巅峰人生等栏目。欢迎关注【前端之巅】微信公众号(ID:frontshow),及时获取前端每周清单;本文则是对于半年来发布的前端每周清单...

    LeviDing 评论0 收藏0
  • Angular 1.x 跟上时代步伐

    摘要:所以说的模块机制没有解决文件依赖关系和文件异步加载的问题。大部分团队还是停留在第二第三阶段,每个阶段的实现都有很多种选择。希望这篇文章能够激起大家永远保持积极向前追求完美代码的心,不仅对自己的成长也会对公司带来无限的价值。 本篇技术博客来自有着化腐朽为神奇能力的,Worktile 技术牛人Web 总监 @徐海峰 大神的分享~满满的干货,你值得拥有! Worktile 的前端构建之路 2...

    李增田 评论0 收藏0
  • 前端每周清单半年盘点之 PWA

    摘要:前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点分为新闻热点开发教程工程实践深度阅读开源项目巅峰人生等栏目。 前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点;分为新闻热点、开发教程、工程实践、深度阅读、开源项目、巅峰人生等栏目。欢迎关注【前端之巅】微信公众号(ID:frontshow),及时获取前端每周清单;本文则是对于...

    崔晓明 评论0 收藏0

发表评论

0条评论

jerry

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<