如何工程化开发大型 angular2 项目(上篇) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Angular2Matser
V2EX    求职

如何工程化开发大型 angular2 项目(上篇)

  •  
  •   Angular2Matser 2016-11-29 21:56:13 +08:00 4282 次点击
    这是一个创建于 3293 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如何工程化开发大型 angular2 项目(上篇)

    前请提要

    目前前端项目越来越复杂,管理一个前端项目需要考虑的方面越来越多,例如工具选择、项目构建、代码自动 review 工具、代码打包上线、开发生产环境分离、项目结构管理以及第三库引入管理等等之类问题。所以下面是我开发 angular2 项目时遇到的一些问题以及自己的一些解决方案以及项目管理的思路。这些内容将会以一个系列展开。

    项目构建篇

    angular2 官方提供 ng cli 构建工具,但是投入使用后发现并不是符合我们需求。因为我们之前项目是基于 gulp 整套工作流,所以一直在寻找与 gulp 相结合的 ng2 案例。后来找到一个 angular-seed 项目,于是我将该项目设立为种子项目,依据该种子项目我们开发了 7 、 8 个 angular2 项目。下面简单介绍一下如何利用种子库创建衍生库,只要种子库保持更新,其他库可以同步保持更新.

    建立种子库

    管理流程图

    上面的图画得比较烂,我还是来好好解释一下。首先我们得有一个主心库,这个库十分重要,里面没有业务逻辑的代码,主要是平时开发时所需要的所有脚本,以及 npm 的一些基本依赖。另外一些共用组件,共用逻辑代码(例如登录验证等等)。主心库创 立完后,我们需要建立一个 upstream 的远端指向 angular-seed 项目

    git remote add upstream https://github.com/mgechev/angular-seed.git git fetch upstream git merge upstream/master 

    平时我们想要更新主仓库时,只要 git pull 一下 upstram 远端,就可以保持最新了。如果不想人工手动去更新的化可以交给 jenkins 定时去更新,这样主心仓库永远是最新的了。

    创建衍生库

    因为我们所有项目围绕主心库而衍生出来的,所以衍生库和主心库的关心和 angular-seed 关系一致。我们指定我们衍生库的远端 upstream 为我们的主心库,这样只要主心库是最新的,这样所有衍生库都可以保持同步更新。可以享受主心库提供的共用配置和 业务逻辑。看上去过程比较繁琐,其实只需要将整个操作过程的指令集合到 bash 脚本中,执行脚本是指定参数名为你的项目名称。这样快速就可以构建一个 angular2 项目,所以整套流程适合有复杂业务的项目。

    git remote add upstream [email protected]:/git/main-base git fetch upstream git merge upstream/master 

    项目开发篇

    既然我们构建完项目后,那么马上开工吧。随着前端项目越来越复杂,里面配置文件越来越多。因为开发环境和生产环境需要调用服务端接口地址又是不一样的,像我开发微信项目的,开发环境用测试的 appid 和生产环境的 appid 也是不一样的。情况更严重的是我们每个客户都有自己独立的配置信息(所以开始考虑多租户模式,不然下去是大坑)。理想情况下:

    gulp build.dev --color --env-config dev 

    执行上述命令,就是启动开发 dev 环境的配置。利用 yargs 这个 node 工具去接收我们传递过去的参数,以此来区分开是开发模式下还是 prod 模式下。下面贴一段代码举例一下:

    import { argv } from 'yargs'; ... export function templateLocals() { // 这里就是我们通过 env-config 变量获取参数 const cOnfigEnvName= argv['env-config'] || argv['config-env'] || 'dev'; const cOnfigPath= Config.getPluginConfig('environment-config'); const baseCOnfig= getConfig(configPath, 'base'); // 依据 dev 和 prod 以及对应的路径获取对应的配置文件 const cOnfig= getConfig(configPath, configEnvName); if (!config) { throw new Error('Invalid configuration name'); } return Object.assign(Config, { ENV_CONFIG: JSON.stringify(Object.assign(baseConfig, config)) }); } // 具体代码可以克隆 angular-seed 去查看 

    另外 angular2 提供enableProdMode接口能够优化打包出来的代码,但是我们开发时是不需要用到该接口如何去分离开来呢? gulp 有个好插件,完美解决该问题,gulp-template。我们只要在我们

    代码中加入类似<%= BUILD_TYPE %>,这样就可以赋值给BUILD_TYPE,我们可以合理得去控制。

    import { enableProdMode } from '@angular/core'; ... if (String('<%= BUILD_TYPE %>') === 'prod') { enableProdMode(); } 

    关于开发配置十分细碎,所以不做详述,可以日后咨询。

    下篇预告

    下篇会涉及项目目录结构管理,以及 angular2 在移动端开发的经验,项目打包上线的经验。

    PS : 正在找工作,有意请发我邮箱 [email protected]

    4 条回复    2016-12-03 10:14:06 +08:00
    hantsy
        1
    hantsy  
       2016-11-30 13:35:25 +08:00
    标题比较吸引人。

    mgechev 的 Angular Seed 不如用 AngularClass 的 angular2-webpack-starter, 不过现在官方的 Angular CLI 已经足够强大了。
    Angular2Matser
        2
    Angular2Matser  
    OP
       2016-12-02 19:24:03 +08:00 via Android
    @hantsy 目前已经转用 webpack2 了, webpack 的代码打包分析工具,很有帮助
    chenxinxing
        3
    chenxinxing  
       2016-12-02 21:41:31 +08:00
    @Angular2Matser 还在找工作么? 刚刚给你发了一个邮件,有兴趣聊一下么?
    hantsy
        4
    hantsy  
       2016-12-03 10:14:06 +08:00
    @Angular2Matser Angular CLI 早就开始用 Webpack2 了。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     908 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 22:57 PVG 06:57 LAX 14:57 JFK 17:57
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86