1. config文件单独打包
- 在前端项目根目录建立文件webpack.config.js ,若存在,则在里面修改代码。
- webpack.config.js里面代码如下。
let webpack = require('webpack');
let path = require('path');
export default function (config, env) {
Object.assign(config.entry, {
//kpiCheckConfig 换成自己项目中的配置文件
'config': ['./src/config/kpiCheckConfig.js'],
})
config.plugins.push(new webpack.optimize.CommonsChunkPlugin({
name: 'config', // 这公共代码的chunk名为'config'
filename: 'config.js', // 生成后的文件名
minChunks: Infinity
}))
return config
}
2. 前端打包优化(使用webpackdll插件)
当项目的前端文件越来越多时,由于选用的框架版本 ( 主要是指 dva、roadhog ) 过于陈旧,会导致打包速度越来越慢,动辄十几分钟,到最后会导致内存溢出,打包失败,需要使用下面的 webpack 的 dllplugin 插件解决打包问题。
熟悉 Windows 的朋友就应该知道,DLL 所代表的含义。在 Windows 中有大量的 .dll 文件,称为动态链接
库。在我们的项目中,要做的也是将各个模块中公用的部分给打包成为一个公用的模块。这个模块就包含了
其他模块中需要的函数和数据(比如:其他组件所需的 React和dva 库等)。
使用 DllPlugin 的时候,会生成一个 manifest.json 这个文件,所存储的就是各个模块和所需公用模块的对应
关系。
- 根据各自项目依赖生成对应的 manifest.json 文件
以下步骤只需要操作一次,生成完公共依赖包后,即可删掉新增的配置文件和相关配置( 过河拆桥 )。
- 新建一个生成 dll 的配置文件: webpack.dll.config.js ,
const webpack = require('webpack')
module.exports = {
entry: {
bundle: [
'react',
'react-dom',
'react-router',
'dva',
'moment',
'antd'
//其他需要单独打出的公共库
],
},
output: {
path: './public',
filename: 'commons.js',
library: 'commons_library',
},
plugins: [
new webpack.DllPlugin({
path: './public/commons.manifest.json',
name: 'commons_library',
}),
//查看打包过后的文件组成, 发现moment的其它几十种语言包占用了大量空间, 我们的项目只需要保留中英文及可
new webpack.IgnorePlugin(/^\.\/(?!zh-cn|en-gb)/, /moment[\/\\]locale$/),
],
}
- 在 package.json 文件里,加以下运行命令:
"webpackdll": "webpack --config webpack.dll.config.js"
- 运行如下命令生成 commons.js 及 commons.manifest.json 文件( 在public目录下 )。
npm run webpackdll
- 在 webpack.config.js 中添加插件,依赖生成的公共文件
config.plugins.push(new webpack.DllReferencePlugin({
context: '.',
manifest: require("./public/commons.manifest.json"),
}),)
如果已经把 antd 打包在公共文件里, 就需要在 .roadhogrc 文件里删掉 antd 的按需加载,只保留 ewec 的按需加载,通过查看打包生成的文件结构,发现每个chunk都包含了整个的antd,导致文件过大内存溢出,取消antd的按需加载,大大减小了打包过后的文件体积,提高了打包及浏览器加载速度。
删掉
{
"libraryName": "antd",
"libraryDirectory": "lib",
"style": true
},
- 取消 antd 的按需加载之后, 就需要把 antd 的整个样式文件复制到 public 文件夹中, 然后直接挂载到 index.html 中, 顺序如下:
//antd的样式文件位于 node_modules\antd\dist\antd.css, 也可直接复制压缩版本 antd.min.css
<link rel="stylesheet" href="/antd.css" />
<link rel="stylesheet" href="/index.css" />
- 在 index.html 中手动添加 commons.js 依赖,顺序如下:
<script src="/config.js"></script>
<script src="/commons.js"></script>
<script src="/index.js"></script>
以上所有配置修改完成, 就可正常打包了
需要提交到 gitlab 的新文件有 public 下的 antd.css 、 commons.js和commons.manifest.json, 需要更新到 gitlab 的旧文件有 webpack.config.js 和 index.html。
3. 升级roadhog 版本解决前端打包缓存问题
升级完成后,需要联系运维修改前端部署配置,之前,运维是直接修改 config.js 里面的URL路径配置,需要改成修改以 config 开头的 JS 文件,例如 config.lkjsdf42545.js 里面的URL路径。
由于前端项目所采用的打包工具版本较老 (roadhog: 0.X.X) ,打包出来的文件名字统一为 1.1.js,2.2.js……,或者其它固定的名字,这样代码更新发布之后,用户的浏览器还是会从缓存取 JS,CSS 文件, 导致新的功能出不来,或者报错,严重影响客户使用。
roadhog 1.X 版本支持 hash 文件名配置, 编译后生成的文件如果内容有变化,会生成不同的文件名,这样就解决了缓存问题。roadhog 最新版本为 2.X,如果升级到 2.X ,需要对代码进行修改,影响范围较大,所以老项目升级到 1.X ,新的前端项目建议直接使用 2.X,热部署和打包编译速度会有很大提升。
下面进入简单的改造流程:
- 修改 roadhog 的依赖版本
"roadhog": "^1.2.2"
- 添加 hash 配置
- 在 .roadhogrc 里添加 hash 配置,使打包出来的普通文件( JS 和 CSS )带上 hash 码
"hash": true
- 修改单独打包的 config.js 文件名,加上 hash 码:
filename: 'config.[hash:7].js', // 生成带hash的config文件
- 3.由于生成的 JS 文件和 CSS 文件都带有 hash 码了,public/index.html 里面写死的文件引入肯定就会有问题,删掉它,在 src 下建一个 ejs 模板文件, roadhog 1.X 会默认找 src 根目录下的 index.ejs 文件,自动在里面引入 JS 和 CSS ,并生成需要的 index.html。
index.js 代码如下:
如果项目上有额外的 JS,CSS 引用,直接在 index.js 里面添加即可
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <title></title>
</head>
<body>
<div id="root"></div>
</body>
</html>
4.使用umi ,替换roadhog
4.1. 介绍
umi 是蚂蚁金服的底层前端框架,已直接或间接地服务了 600+ 应用,包括 java 、 node 、 H5 无线、离线
(Hybrid )应用、纯前端 assets 应用、 CMS 应用等。他已经很好地服务了我们的内部用户,同时希望他也能服务好外部用户。
4.2. 为什么使用 umi , 而不是 roadhog
- 这两个框架都是同一个作者, 而且该作者已经说明,工作重心在 umi 上, roadhog 的 issue 维护不太积极, 后面可能会放弃维护, 所以作者推荐使用 umi。
- roadhog 是比较纯粹的 webpack 封装工具,作为一个工具,他能做的就比较有限(限于 webpack
层)。而 umi 则等于 roadhog + 路由 + HTML 生成 + 完善的插件机制,所以能在提升开发者效率方面发挥出更大的价值。并且与 dva 数据流的深入融合,支持 duck directory 、 model 的自动加载、 code splitting 等等。 - 使用 umi 之前, dva 项目之前通常都是这种扁平的组织方式:
+models
-global.js
-a1.js
-a2.js
-b.js
+services
-a.js
-b.js
+routes
-PageA.js
-PageB.js
用了 umi 后,可以按页面维度进行组织:
+models/global.js
+pages
+ a
- index.js
+components
-A1.js
-A2.js
+models
-a1.js
-a2.js
+services
-a.js
+b
- index.js
- model.js
- service.js
好处是结构更加清晰了,减少耦合,方便阅读及查找代码,一删全删,方便 copy 和共享。
umi 的特点及使用方法(编码方式和 roadhog 版本并无二致, 只是有些配置变化和文件的路径不同)。
- routes 文件夹用 pages 代替, 即: routes/user/A.js -> pages/user/A.js
- 自动注入 model,无需手动在 router.js 里注入 model。
- 更少的配置文件
首先,我们的 package.json 里会少很多依赖,
dva-loading
dva-hmr
dva
react
react-dom
如果你用了 antd,那么还可以省掉
antd
antd-mobile
babel-plugin-import
然后,webpack.config.js、原 .roadhogrc.js、原 .roadhogrc.mock.js 也能大幅省略
- 更快的编译速度,以及热部署速度,提升开发效率。
5. 生产环境, 屏蔽代码中console.log
- 安装插件 babel-plugin-transform-remove-console
npm install babel-plugin-transform-remove-console --save-dev
- 配置 .roadhogrc
"production": {
"extraBabelPlugins": [
//添加下面这行代码即可, 生产环境只保留error级别的日志, log和warn级别的日志自动忽略
["transform-remove-console", {"exclude": ["error"]}],
"transform-runtime",
"dva-hmr",
["module-resolver", {
"alias": {
"@": "./src"
}
}],
["import", [
{
"libraryName": "ewec",
"libraryDirectory": "lib/components"
}
]]
]
}