需求 此前的《Webpack 资源拆分方案 》已经正式应用到线上生产环境,企业版、手机版和 API 文档的代码已移入各自的仓库中,但不久后很快出现了一些问题:
企业版有多个进行中的开发任务,是混在一个 PR 中一起测试,还是为他们分配互不影响的版本号分别测试?
多个与企业版相关的 PR 测试通过后,需要在企业版仓库中合并这些 PR,然后发布新版本供测试和上线,这流程太麻烦
npmjs.org 服务器出现故障 ,在发布新版本后,服务器端未更新版本信息,导致相关开发任务无法继续
发版前的全量构建时间较长,上传压缩包需要时间,等待 taobao 源同步新版本包也需要时间,拖慢开发效率
核心问题是发版、上传和镜像同步都需要手动操作,既耗时又麻烦,用 CI 服务代替人工操作是个可行的办法,但在 Gitee 上接入 CI 服务也很麻烦。
解决方案 撤销之前的方案,将拆分出去的代码移入主仓库内。
实现 移动子项目至主仓库 原先的 app/assets/javascripts/webpack
目录太深,可以乘此次改动顺便调整目录结构,把子仓库代码都放根级 webpack 目录中,结构如下:
1 2 3 4 webpack/ api-doc/ mobile/ enterprise/
调整子项目的 Webpack 配置 在 webpack 目录中新建 webpack.projects.config.js,用于引入子项目的配置文件。
1 2 3 4 5 6 7 8 webpack/ api-doc/ webpack.config.js mobile/ webpack.config.js enterprise/ webpack.config.js webpack.projects.config.js
构建性能优化 每次线上更新时都会构建全部资源,耗时很长,像手机版、API 文档这类更新频率低的项目没必要也一起构建。为此,可以实现按需构建的功能,只构建有改动的前端代码,未改动的则用上次的资源。
一开始的方案是动态生成 entry 配置,过滤掉未改动的打包项,但这会使生成的 manifest.json 文件不会包含未打包的资源信息。
现在的方案是:
给每个子项目输出 manifest.json 文件
将 webpack/webpack.config.js
作为主配置,用于将子项目的 manifest.json 文件合并成一个,供服务器读取
构建生产版本资源时,先构建子项目的资源,webpack.projects.config.js 会先读取 build-state.json 文件,对比子项目版本,然后返回有改动的子项目的 Webpack 配置列表给 Webpack 使用
构建完生产版本资源后,运行一个 js 脚本,将各个子项目目录最后的 commit id 作为它们的版本号,然后保存至 build-state.json 文件中
相关脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 { "scripts" : { "webpack:projects" : "NODE_OPTIONS=--max_old_space_size=4096 webpack --config webpack/webpack.projects.config.js" , "webpack:main" : "webpack --config webpack/webpack.config.js" , "dev:projects" : "npm run webpack:projects -- --progress --watch" , "dev:mobile" : "WEBPACK_BUILD_TARGET=mobile npm run dev:projects" , "dev:enterprise" : "WEBPACK_BUILD_TARGET=enterprise npm run dev:projects" , "dev:main" : "npm run webpack:main -- --progress --watch" , "build:projects" : "NODE_ENV=production npm run webpack:projects -- --bail" , "build:main" : "NODE_ENV=production npm run webpack:main -- --bail" , "build" : "npm run build:projects && npm run build:main && node ./webpack/save-build-state.js" , } }
开发的时候,可以选择只构建相关项目的资源,节省时间。以企业版为例,先运行:
然后再开个终端运行以下命令更新 manifest.json: