早前前端的开发工作在一些场景下被认为只是日常的一项简单工作,或只是某个项目的"附属品",并没有被当做一个"软件"而认真对待(无论是产品负责人还是开发者),都会有用完即丢的感觉,对于时间和成本的控制必然将导致最终产出倾向于出现"质量低"、"可维护性差"、"可用性差"等问题。
随着Web业务日益复杂化和多元化,工程复杂了就会产生许多问题,比如:如何进行高效的多人协作?如何保证项目的可维护性?如何提高项目的开发质量?
因此前端工程化体系的引入,让前端开发能和原生App应用项目开发一样“自成体系”,脱离了对后端项目的依赖。基于“约定优于配置”、“按照约定写代码”的原则对Node层功能的设定能够降低沟通协调成本,构建、部署等工作的规范化,使前端技术人员的开发重点回归到Web应用的交互体验本身,回归到“纯粹”的前端研发。
优化清单:
1.减少打包时间
2.减小包体积
3.提取公共代码
4.优化压缩规则
5.代码规范化(ESLint+Prettier)
6.自动化构建部署
优化工具:
"webpack": "^3.6.0"
"webpack-parallel-uglify-plugin": "^1.1.1"
"webpack-bundle-analyzer": "^2.13.1",
"prettier": "^1.18.2",
"babel-eslint": "^7.1.1",
"eslint": "^3.19.0",
"eslint-config-prettier": "^6.0.0",
"eslint-config-standard": "^10.2.1",
"eslint-friendly-formatter": "^3.0.0",
"eslint-loader": "^1.7.1",
"eslint-plugin-html": "^3.0.0",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-node": "^5.2.0",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^3.0.1",
"eslint-plugin-vuefix": "^0.2.1",
具体措施:
1.优化resolve.modules
原理:
webpack 的 resolve.modules 是用来配置模块库(即 node_modules)所在的位置。当 js 里出现 import 'vue' 这样不是相对、也不是绝对路径的写法时,它便会到 node_modules 目录下去找。
在默认配置下,webpack 会采用向上递归搜索的方式去寻找。但通常项目目录里只有一个 node_modules,且是在项目根目录。为了减少搜索范围,可我们以直接写明 node_modules 的全路径
所以平时在写 import 导入模块的时候引入指向的是具体的哪个文件,也对打包速度的提升又一定的影响
操作:
打开 build/webpack.base.conf.js 文件,添加如下 modules 代码块:
module.exports = {
resolve: {
...
modules: [
resolve('src'),
resolve('node_modules')
],
...
},
2.配置loader的 include & exclude
原理:
我们可以使用 include 更精确地指定要处理的目录,这可以减少不必要的遍历,从而减少性能损失。
同时使用 exclude 对于已经明确知道的,不需要处理的目录,予以排除,从而进一步提升性能。
操作:
打开 build/webpack.base.conf.js 文件,添加如下 include,exclude 配置:
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig,
include: [resolve('src')], // 添加配置
exclude: /node_modules\/(?!(autotrack|dom-utils))|vendor\.dll\.js/ // 添加配置
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')], // 添加配置
exclude: /node_modules/ // 添加配置
},
除此之外,如果我们选择开启缓存将转译结果缓存至文件系统,则至少可以将 babel-loader 的工作效率提升两倍。要做到这点,我们只需要为 loader 增加相应的参数设定:
loader: 'babel-loader?cacheDirectory=true'
3.使用 webpack-parallel-uglify-plugin 插件来压缩代码
原理:
默认情况下 webpack 使用 UglifyJS 插件进行代码压缩,但由于其采用单线程压缩,速度很慢。
我们可以改用 webpack-parallel-uglify-plugin 插件,它可以并行运行 UglifyJS 插件,从而更加充分、合理的使用 CPU 资源,从而大大减少构建时间,该插件能设置缓存,大大减小构建时间。
操作: 1.安装 webpack-parallel-uglify-plugin 插件
npm i webpack-parallel-uglify-plugin -D
2.打开 build/webpack.prod.conf.js 文件,并作如下修改
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
// 增加 webpack-parallel-uglify-plugin来替换
new ParallelUglifyPlugin({
cacheDir: '.cache/',
uglifyJS:{
output: {
comments: false
},
compress: {
warnings: false,
drop_debugger: true, // 去除生产环境的 debugger 和 console.log
drop_console: true
}
}
}),
4.使用 webpack.optimize.CommonsChunkPlugin提取公共代码
原理:
提取公共代码,根据配置,把基础库以及业务逻辑公共代码抽离提取出来,减少资源重复引用.配合路由器懒加载,达到资源重复利用,性能提升。
操作:
打开 build/webpack.prod.conf.js 文件,并作如下修改
new webpack.optimize.CommonsChunkPlugin({
name: "app",
// chunks: ['chunk-service','chunk-main','chunk-manage', 'chunk-good', 'chunk-statistic', 'chunk-quality', 'chunk-ukiUserSystem'],
minChunks: 2,
children: true,
async: true,
}),
5.使用webpack-bundle-analyzer分析包体积情况
原理
读取输出文件夹(通常是dist)中的stats.json文件,把该文件可视化展现的插件。便于直观地比较各个bundle文件的大小,以达到优化性能的目的。
操作:
1、先安装
npm install --save-dev webpack-bundle-analyzer
2.打开 build/webpack.prod.conf.js 文件,并作如下修改
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
plugins: [
new BundleAnalyzerPlugin(
{
analyzerMode: 'disabled',
analyzerHost: '127.0.0.1',
analyzerPort: 8889,
reportFilename: 'report.html',
defaultSizes: 'parsed',
openAnalyzer: true,
generateStatsFile: false,
statsFilename: 'stats.json',
statsOptions: null,
logLevel: 'info'
}
),
]
3、在package.json的scripts里加入下面这句话,就可以npm run build之后看到webpack-bundle-analyzer的效果:
"analyz": "NODE_ENV=production npm_config_report=true npm run buildPro"
6.使用aliyunoss-webpack-plugin部署到阿里云服务(配合运维)
作用:
用于自动上传静态资源到阿里的oss上,以便作为静态资源使用,当然也可以用于自动存储大文件。
操作:
1.安装npm install aliyunoss-webpack-plugin --save-dev
2.打开 build/webpack.prod.conf.js 文件,并作如下修改
var AliyunossWebpackPlugin = require('aliyunoss-webpack-plugin')
var webpackConfig = {
entry: 'index.js',
output: {
path: 'dist',
filename: 'index_bundle.js'
},
plugins: [new AliyunossWebpackPlugin({
buildPath:'your build path',
region: 'your region',
accessKeyId: 'your key',
accessKeySecret: 'your secret',
bucket: 'your bucket',
getObjectHeaders: function(filename) {
return {
Expires: 6000
}
}
})]
}
7.使用ESLint+Prettier统一代码规范
作用:
Prettier是一个能够完全统一团队代码风格,加分号还是不加分号?tab还是空格?一切以规范为准。ESLint是一个用来识别 ECMAScript 并且按照规则给出报告的代码检测工具,使用它可以避免低级错误和提示。
操作
1.安装 eslint 和 prettier
npm install eslint prettier -g --save-dev
// 这个是为了 eslint 跟 prettier 可以联合使用
npm install --save-dev eslint-plugin-prettier
// 这个是为了让 eslint 跟 prettier 兼容,关闭 prettier 跟 eslint 冲突的rules
npm install --save-dev eslint-config-prettier
nam -g install babel-eslint eslint-plugin-html --save-dev
2.配置eslint
.eslintrc 配置文件需要添加修改地方,主要是为了 prettier插件和eslint-config-prettier 插件和eslint-plugin-prettier插件使用的:
// 因为使用了 eslint 和 prettier,所以要加上他们
extends: [ 'eslint:recommended', 'plugin:prettier/recommended'],
// required to lint *.vue files 使用 html参数
plugins: ['html', 'prettier'],
// rules 规则
rules: {
'prettier/prettier': 'off',
// allow async-await
'generator-star-spacing': 'off',
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
// js语句结尾必须使用分号
'semi': ['off', 'always'],
// 三等号
'eqeqeq': 0,
// 强制在注释中 // 或 /* 使用一致的空格
'spaced-comment': 0,
// 关键字后面使用一致的空格
'keyword-spacing': 1,
// 强制在 function的左括号之前使用一致的空格
'space-before-function-paren': 1,
// 引号类型
'quotes': [0, 'single'],
// 禁止出现未使用过的变量
'no-unused-vars': 1,
// 要求或禁止末尾逗号
'comma-dangle': 0,
/* 常规性写法注意*/
'camelcase': 1, //没有驼峰命名警告
'no-dupe-keys': 1,
'no-unreachable': 1,
'no-undef': 1,
'no-throw-literal': 1,
'no-unsafe-finally': 1,
'no-extend-native': 1,
'one-var': 1,
'no-useless-escape': 1,
}
// "off" -> 0 关闭规则
// "warn" -> 1 开启警告规则
//"error" -> 2 开启错误规则
3. 配置prettier
prettier 的检查规则是通过配置文件.prettierrc 实现的,不过一般来说,只需要配置少部分规则即可
{
"trailingComma": "all",
"tabWidth": 4,
"semi": false,
"singleQuote": true,
"arrowParens": "avoid"
}
4.配置 editorconfig
.editorConfig可以帮助开发者在不同的编辑器和IDE之间定义和维护一致的代码风格。
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
优化后: