一、优先使用CDN
二、动态导入
1、两种方式:
// 有两种方式供我们实现动态导入
1.import() //ES的提案,返回以一个promise,导入的模块在then中拿到
2.require.ensure() //webpack在编译时会静态地解析代码中的require.ensure(),将里面require的模块添加到一个分开的chunk中。这个新chunk会被webpack通过jsonp来按需加载。
2、import()实现:
npm install babel-plugin-syntax-dynamic-import --save-dev
// .babelrc
{
"presets": [
...
],
"plugins": ["syntax-dynamic-import"]
}
// webpack.config.js:
module.exports = {
mode: 'production',
entry: {
index: path.resolve(root_path, 'index.js'),
},
output: {
filename: '[name].bundle.js',
// chunkFilename:指定非entry chunk的文件名,比如import()引入的模块不打包进entry中,而会作为单独的chunk打包,其文件名就由该属性决定
chunkFilename: 'MaterialsCenter/js/[name].min.js',
path: path.resolve(root_path, 'dist')
},
module: {
rules: []
}
}
index.js:点击按钮才异步加载lodash
// index.js
let btn = document.getElementById('btn');
btn.addEventListener('click', () => {
import(
/* webpackChunkName: "lodash" */
/* webpackMode: "lazy" */
'lodash').then(
_ => {
var app = document.getElementById('app');
app.textContent = _.join(['Index', 'Module', 'Loaded!'], ' ');
}
).catch(
err => {
console.log('loading module error occur', err);
}
)
});
3、魔法注释 还有一些其他项,如:
import(
/* webpackInclude: /\.json$/ */
/* webpackExclude: /\.noimport\.json$/ */
/* webpackChunkName: "my-chunk-name" */
/* webpackMode: "lazy" */
/* webpackPrefetch: true */
/* webpackPreload: true */
`./locale/${language}`
);
三、webpack打包压缩处理
1、先使用webpack-bundle-analyzer
插件查看包体大小
npm install --save-dev webpack-bundle-analyzer
// webpack.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
}
2、HtmlWebpackPlugin
- 将JS文件放在body的最后
默认情况下,build后的index.html中,js的引入是在head中。
使用html-webpack-plugin插件,将inject的值改成body。就可以将js引入放到body最后。
npm install --save-dev html-webpack-plugin
3、TerserJSPlugin
- 处理 js 的压缩和混淆
npm install terser-webpack-plugin --save-dev
const TerserJSPlugin = require('terser-webpack-plugin');
optimization: {
minimizer: [
new TerserJSPlugin({
parallel: true,
terserOptions: {
compress: {
warnings: false,
keep_infinity: true,
drop_console: true,
drop_debugger: true,
pure_funcs: ['console.log'] // 去除console
},
},
}),
]
},
4、splitChunks
- 切割chunks
optimization: {
splitChunks: {
// chunks: 'all',
chunks: 'async',
minSize: 20000,
// minRemainingSize: 0,
minChunks: 1,
maxAsyncRequests: 30,
maxInitialRequests: 30,
enforceSizeThreshold: 50000,
cacheGroups: {
R3: {
test: /[\\/]node_modules[\\/](@syman)[\\/]/,
name: 'R3',
chunks: 'all',
},
BC: {
test: /[\\/]node_modules[\\/](@burgeon)[\\/](business-components)[\\/]/,
name: 'businessComponents',
chunks: 'all',
},
I18n: {
test: /[\\/]node_modules[\\/](@burgeon)[\\/](internationalization)[\\/]/,
name: 'internationalization',
chunks: 'all',
},
commonLib: {
test: /[\\/]node_modules[\\/]/,
name: 'commonLib',
chunks: 'all',
},
},
},
},
5、MiniCssExtractPlugin + OptimizeCSSAssetsPlugin 或 CssMinimizerWebpackPlugin
用MiniCssExtractPlugin之前:
用MiniCssExtractPlugin之后:
用OptimizeCSSAssetsPlugin之后:
CssMinimizerWebpackPlugin存在版本问题,压缩效果大致同上(基于卡宾当前webpack暂未找到相对应版本
6、productionSourceMap
- 去除.map文件
在webpack打包的过程中,打包后每个js文件都有一个map文件,将该多余文件去掉。
map文件的作用:项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错。 有了map就可以像未加密的代码一样,准确的输出是哪一行哪一列有错。
7、UglifyJsPlugin - 压缩代码并移除console (废弃!!!使用TerserJSPlugin
)
至少需要 Node v6.9.0 和 Webpack v4.0.0 版本
npm install uglifyjs-webpack-plugin --save-dev
//webpack.config.js
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {
mangle: true, // 注意 `mangle.properties` 的默认值是 `false`。
output: {
comments: false, // 构建时去除注释
},
},
compress: {
warnings: false,
drop_console: true,
pure_funcs: ['console.log']
},
sourceMap: true, // 使用源映射将错误信息位置映射到模块(这将会减慢编译速度)
extractComments: true, // 是否提取注释到单独的文件中
test: /.js(?.*)?$/i, //测试匹配文件,
include: //includes/, //包含哪些文件
excluce: //excludes/, //不包含哪些文件
//允许过滤哪些块应该被uglified(默认情况下,所有块都是uglified)。
//返回true以uglify块,否则返回false。
chunkFilter: (chunk) => {
// `vendor` 模块不压缩
if (chunk.name === 'vendor') {
return false;
}
return true;
}
}),
cache: false, //是否启用文件缓存,默认缓存在node_modules/.cache/uglifyjs-webpack-plugin.目录
parallel: true, //使用多进程并行运行来提高构建速度
],
},
};
四、Nginx 开启 gzip
...
http {
...
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
#gzip_http_version 1.1;
gzip_comp_level 2; # 压缩级别
# 要压缩的mine类型
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/xml+rss image/jpeg image/gif image/png image/svg+xml;
gzip_vary off;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\."; # IE6不支持gzip
...
}