tree shaking
- tree shaking 去掉我们没有使用的代码
满足条件自动开启- 使用ES6模块化语法
- 开启webpack生产环境配置
- 可以在配置文件中使用sideEffects,*号代表全选
"sideEffects": [
"*.css"
],
caching
- cacheing缓存,当我们设置强制缓存后使用contenthash值,这样修改文件就会让hash值变化,重而走服务器
- hash webpack每次打包都会生成一个唯一的hash值,问题:所有资源会共享同一个hash值,一个文件变化,会导致所有文件缓存失效
- chunkhash webpack每次打包生成的chunk(打包输出文件)分别生成一个唯一的hash值。 问题:如果文件一开始在一起,会是同一个hash值
- contenthash 每一个输出文件都会生成一个唯一的hash值,这个hash值是根据文件内容生成的, 解决:不同文件,使用不同的hash
filename: './js/[contenthash:10].js'
filename: 'css/[contenthash:10].css',
chunkFilename: 'css/[contenthash:10].css',//多个css文件走这个
code splitting
1. code splitting 就是提取出公共的代码部分成为单独文件,只有大于10kb左右的文件会被提取
entry: { // 多入口 并没有优化
main1: './src/js/index.js',
main2: './src/js/module1.js'
},
output: {
path: resolve(__dirname, 'build'),
filename: './js/[name].js'
},
- 多入口优化
entry: { // 多入口 并没有优化 不用下包
main1: './src/js/index.js',
main2: './src/js/module1.js'
},
output: {
path: resolve(__dirname, 'build'),
filename: './js/[name].js'
},
optimization: { //独立的不在基本的插件中
splitChunks: {
chunks: "all"
}
}
3.单入口优化
需要使用es10的动态引入
module.exports = {
entry: './src/js/index.js',
output: {
path: resolve(__dirname, 'build'),
filename: './js/[name].js',
chunkFilename: "./js/[name].chunk.js" //提取出来的代码的名字
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CleanWebpackPlugin()
],
mode: 'development',
};
import(/* webpackChunkName: "module1" */'./module1').then(({default: add}) => {
console.log(add(2, 2)); 提取代码的名字
});
lazy loading
1 ,预加载和懒加载
1. 预加载就是使用webpackPrefetch: true,这样会在浏览器空闲的时候偷偷加载.并且变成link标签加载,在事件和定时器中也是一样,但和强制加载兼容性都很差
2. 懒加载就是使用事件或定时器到了在加载
3. 和其对于的还有一个webpackPreload 不管空不空闲 都要强制加载而且不能在事件中.
document.getElementById('btn').onclick = function () { //得使用es10的新语法
import(/* webpackChunkName: "module1", webpackPrefetch: true */'./module1').then(({default: add}) => {
console.log(add(2, 2));
});
};
dll
- 单独打包,每次打包都会重新构建一些没有动过的代码这个时候使用这个就会快很多,性能优化在本地的打包速度.将一部分基本不会改动的代码或者库单独的打包.
配置一个单独的webpack.dll文件
const { resolve } = require('path');
const webpack = require('webpack');
module.exports = {
entry: {
jquery: ['jquery']
},
output: {
path: resolve(__dirname, '../dll'),
filename: '[name].js',
library: '[name]' // 向外暴露全局jquery, 当其他文件引入jquery时,引入的就是library暴露的jquery
},
plugins: [
new webpack.DllPlugin({
name: '[name]',
path: resolve(__dirname, '../dll/manifest.json')
})
],
mode: 'production',
};
//下载webpack包
new webpack.DllReferencePlugin({
manifest: resolve(__dirname, '../dll/manifest.json')
}),
new AddAssetHtmlPlugin({ // 加载提前打包好的jquery
filepath: resolve(__dirname, '../dll/jquery.js'),
outputPath: 'js',
publicPath: 'js',
}),
shimming
- 将一个库暴露成全局变量,这样在文件的任何地方都可以直接使用这个变量.
new webpack.ProvidePlugin({
$: 'jquery'
})
渐进式网络应用 workbox-webpack-plugin
1.在断网的情况下也可以访问页面,不会出现往网络错误的提示 需要开启服务器
下载 workbox-webpack-plugin
new WorkboxPlugin.GenerateSW({
clientsClaim: true,
skipWaiting: true
})
暴露出去的入口模块
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js').then(registration => {
console.log('SW registered: ', registration);
}).catch(registrationError => {
console.log('SW registration failed: ', registrationError);
});
});
}
多线程打包
- 主要针对耗时的打包任务如babel直接放置在他们的前面如第一位,下包
- 不耗时的任务可能会开启可能会增加时间
'thread-loader'
cache-loader
一般也是用在babel上,但babel有专门的选择,cacheDirectory:true
放在options中
oneof
我们打包编译时,会执行全部的loader,所以可以使用oneof,执行一个就不往下执行,遇到需要执行2个的可以拿出来一个,使用方法是直接oneof[各个loader] 格式为 rules:[ { oneOf: [ ] } ]