资讯专栏INFORMATION COLUMN

angular 1.x多项目共享子项目实践之路

mist14 / 3457人阅读

摘要:可发布这一部分会在下一章管理对子项目引用中详细说明。总结本文总结了多项目共享子项目工程化方面的一些实践,并不涉及到复杂的代码,主要涉及到的概念,使用进行包管理,使用作为自动化工具等工程化的知识。

背景

公司的产品线涵盖多个产品,这些产品中会有一些相同的功能,如登录,认证等,为了保持这些功能在各个产品中的一致性,我们在各个产品中维护一份相同的代码。这带来了很大的不便:当出现新的需求时,不得不同时在多个产品中更改代码,使它们保持一致。为了解决这个问题,我们可以将这些公共部分抽取出来放在一个多带带的子项目中,其他项目只是引用该子项目,当出现新的需求时,我们只要改变该子项目即可。

在这个思路的基础上,有两个问题需要解决:

以何种方式维护子项目

如何维护产品对子项目的引用

我们先从一个正常的angular项目说起。例如,如果你想在你的项目中引入Angular UI Bootstrap组件,通常你会怎么做?

在bower.json中添加所需要的dependencies:

{
  "name": "your project",
  "version": "0.0.1",
  "dependencies": {
    "angularJS": "1.4.x",
    "angular-animate": "1.4.x",
    ....
  }
}

使用bower install命令,安装dependencies,并引用:


在你的项目中声明dependencies:

angular.module("myModule", ["ui.bootstrap"]);

通过以上的例子我们可以得到一定的启示:

子项目最终应该以angular module的形式出现

使用bower去维护对包的引用

模块化 模块需求分析

可配置,当使用该模块时可以对该模块传递参数

可构建,将分离的多个文件构建成一个文件

可测试,保证模块的鲁棒性

可发布,供其他项目引用

包含完整的事例代码,供其他人参考

概念分析 可配置

我们在代码层面上可以通过provider来实现。例如:

angular.module("myModule")
    .provider("myProvider", function() {
        var name = null;
        
        // setName can be called duaring module init
        this.setName = function (newName) {
            name = newName;
        }; 
        
        return {
            handleName : function() {
            // do something with name
            }
        };
    })

在另一个module中引入该module时,我们可以改变该module中name的值:

angular.module("anotherModule", ["myModule"])
    .config(function(myProviderProvider){
        myProviderProvider.setName("name");
    });

provider是模块之间交流的桥梁,它可以使模块达到可配置。

可构建

在angular中,一个模块的本质就是一个命名空间,在该命名空间中我们可以增加provider, directive, factory, constant等,它实际上就是一个功能的集合。声明形式通常如下:

angular.module("myModule", [dependencies])
    .directive("myDirective", ...)
    .factory("myFactory", ...);
    ...

directive是angular中最重要的概念,它是angular 1.x中实现组件化的基础。factory通常是为了完成一些辅助功能,如与后端进行数据交互或提供一些util方法等。但是为了代码的可维护性,通常它们会将它们放在一个多带带的文件中, 如:

file1.js为模块的声明文件:

angular.module("myModule", [dependencies]);

file2.js为一个directive声明文件:

angular.module("myModule")
    .directive("mydirective", function() {
        ...
    });

file2.js为一个factory的声明文件:

angular.module("myModule")
    .factory("myfactory", function() {
        ...
    });

但是在发布版本中,我们希望所有的这些文件合并在同一个js文件中,这就是构建的过程。我们可以使用gulp构建工具实现该目的。directive中有时会包含模板html文件,我们将html文件通过angular的$templateCache服务也打包进js中。

可测试

通常前端的测试分为两种: 单元测试和集成测试(又叫做E2E测试)。单元测试的目的是为了测试一个接口或者功能是否能得到预期的结果,测试对象通常为一个函数,但是前端最大的问题就是浏览器的兼容问题,可能在一个浏览器中能跑的代码在另一个浏览器中出现错误,所以我们需要在多个浏览器中去进行测试,我们可以使用gulp搭配测试框架karma去简单的完成在多浏览器下的单元测试。集成测试是站在用户的角度上去执行各种操作,看产品是否稳定等。由于该模块中只是出现一些简单的UI组件,并非一个完整的产品,所以并没有做相关的集成测试。

可发布

这一部分会在下一章bower管理对子项目引用中详细说明。

包含事例代码

由于模块会在多个项目中被不同的人使用,对于这些人最快熟悉该模块的方法就是通过一些demo去了解,所以每个模块中应该包含一定的事例代码供模块的使用者参考。

模块实现

目录结构如下:

javascript-modules
    - module1
        - lib
            - myproject.module.js
            - component
                - mydirective.directive.js
                - template.html
                - templateStyle.scss
            - myfactory.factory.js
            - myprovider.provider.js
            - ....spec.js
            ...
        - release
            - myproject.bundle.js
            - myproject.bundle.css
        - example
            - example1
            - example2
    - gulp
        - task1.js
        - task2.js
        ...
    - gulpfile.js
    - karma.js
    - package.json

说明:

lib: 源代码目录

release: 发布版本目录(只包括js和css文件)

example: 事例代码目录,具体的事例代码目录下包含index.html文件,在该html文件中引入release版本的js和css,然后启动http-server命令打开本地服务器进行测试

gulp: gulp task目录

gulpfile.js: 用于执行gulp目录中的各种task

karma.js: karma配置文件

package.json: 配置文件

gulp中应包含以下task:

build: 合并所有的html文件到$templateCache中,合并所有的js文件,将scss等编译成css

test: 执行lib下的所有测试文件

release: 将打包后的最终代码上传到内部包管理服务器等

PS: 由于历史遗留问题,angular中component和directive之间的界限模糊不清。指令应只封装DOM操作,而组件代表一个自给自足的独立单元 - 有自己的视图和数据逻辑。在angular1.5中增加了component的概念,我们应该更加清晰的区别component和directive,在使用时directive只应该执行封装DOM的操作,而不应该去创造DOM节点,也就是说directive中的restrict应设置为A。

bower管理引用

模块版本发布应遵循semver(语义化版本)原则。
版本格式为:主版本号.次版本号.修订号(MAJOR.MINOR.PATCH)。版本号递增规则如下:

主版本号:当你做了不兼容的API修改,

次版本号:当你做了向下兼容的功能性新增,

修订号:当你做了向下兼容的问题修正。
版本号的管理应该包含在gulp release任务中。

通常我们希望我们开发出的模块只是对企业内部可见,对外部不可见。这就要求我们不能使用平常的方式去使用bower进行包的发布和依赖管理。在借鉴了后端的一些包管理思路后,我们将该包发布在企业内部的私有包管理服务器上,然后在bower.json中通过以下方式来引入包:

{
    "module":"address/module-version.zip"
}

每次当有新的版本的包发布时,我们只需要在bower.json中改变version号,然后使用bower install重新安装新版本的包即可达到更新包的目的。

总结

本文总结了angular 1.x多项目共享子项目工程化方面的一些实践,并不涉及到复杂的代码,主要涉及到angular module的概念,使用bower进行包管理,使用gulp作为自动化工具等工程化的知识。
上述方法也存在一定的问题,每次版本更新时,都要在引用它的各个项目中更新版本号并使用bower install重新安装该模块。
一种更好的思路是使用git submodule/subtree,由于并没有在这方面的实践经验,所以不再赘述。
本文主要是针对angular1.x版本的实践。由于当前angular2已经发布,它提供了强大的组件功能,所以针对angular2会有更好的组件化方式实现。

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

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

相关文章

  • Angular 8 中,我们可以期待些什么

    摘要:在理想的情况下,我们甚至可以立即将应用程序升级到。于是,在中,我们可以得到些什么正如我们所看到的,的新增特性除之外并不是很亮眼,尽管这些特性非常好用,但对于大多数应用程序来说并不重要。 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 本文由葡萄城翻译并发布 showImg(https://segmentfault.com/img/bVbrk...

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

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

    LeviDing 评论0 收藏0
  • 使用Angular CLI时的6个最佳实践和专业技巧

    摘要:在官方库的多主题中进行有效的使用。项目中默认选择使用可以假设是安全的。常规提交定义了强制类型可选范围其次是提交消息。标准版本将正确地撞击项目的主要版本,因为在提交主体中存在着关键字。 使用Angular CLI开发angular应用程序是一种非常愉快的体验!Angular团队为我们提供了令人惊叹的CLI,它支持了任何重要项目开箱即用所需的大部分东西。 规范化的项目结构与全面的测试能力(...

    atinosun 评论0 收藏0
  • 前端清单第 27 期:React Patent License 回复,Shopify WebVR 购

    摘要:新闻热点国内国外,前端最新动态就开源许可证风波进行回复数周前,基金会决定禁止旗下项目使用,因为其在标准的许可证之外添加了专利声明此举引发了社区的广泛讨论,希望能够更新其开源许可证。 showImg(https://segmentfault.com/img/remote/1460000010777089); 前端每周清单第 27 期:React Patent License 回复,Sho...

    jeffrey_up 评论0 收藏0
  • Angular学习资料

    摘要:目前稳定在,进入了版本状态,谷歌表示会长期进行支持。版本是谷歌开发的一款类型的框架,具有优越的性能和绝佳的跨平台性。于年月正式发布,目前已发布到版本。中文翻译与主站同步的非常及时。 Angular是一款面向企业级应用开发的前端框架,掌握好Angular相关技术,有助于我们提升开发效率,编写高质量的前端代码。 Angular 1.x版本 AngularJS 诞生于2009年,由Misko H...

    james 评论0 收藏0

发表评论

0条评论

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