懒加载
动态import使用最多的一个场景就是懒加载(比如路由懒加载)
- 封装一个component.js,返回一个component对象
- 我们可以在一个按钮点击时,加载这个对象
如下所示代码,通过import.then的方式加载异步模块
const button = document.createElement('button');
button.innerHTML = '加载元素';
button.addEventListener('click', () => {
import(
/* webpackChunkName:'element' */
/* webpackPreload: true */
'./element'
).then(({ default: element }) => {
document.body.appendChild(element);
});
});
document.body.appendChild(button);
重点是import中的配置
/* webpackPrefetch: true */
/* webpackPreload: true */
这两个都可以做到类似的功能,不过还是有些许不同
- prefetch(预获取):将来某些导航下可能需要的资源
- preload(预加载):当前导航下可能需要资源
与 prefetch 指令相比,preload 指令有许多不同之处:
- preload chunk 会在父 chunk 加载时,以并行方式开始加载。prefetch chunk 会在父 chunk 加载结束后开始加载。
- preload chunk 具有中等优先级,并立即下载。prefetch chunk 在浏览器闲置时下载。
- preload chunk 会在父 chunk 中立即请求,用于当下时刻。prefetch chunk 会用于未来的某个时刻。
- 浏览器支持程度不同。
optimization.runtimeChunk配置
配置runtime相关的代码是否抽取到一个单独的chunk中:
- runtime相关的代码指的是在运行环境中,对模块进行解析、加载、模块信息相关的代码
- 比如我们的component、bar两个通过import函数相关的代码加载,就是通过runtime代码完成的
runtimeChunk: {
name: 'runtime-why.js',
},
什么是CDN?
在开发中,我们使用CDN主要是两种方式:
配置publicPath
output: {
filename: '[name].bundle.js',
path: resolveApp('./build'),
chunkFilename: '[name].[hash:6].chunk.js',
publicPath: 'https://jujuul.com.cdn',
},
第三方库的CDN服务器
通常一些出名的开源框架都会将打包后的源码放到一些比较出名的、免费的CDN服务器上:
- 国际上使用比较多的是unpkg、JSDelivr、cdnjs
- 国内是bootcdn
如果项目中的第三方库我们不打算由自己的服务器提供,而是使用免费的CDN,那么可以如下配置
// 通过 externals 将我们项目中不打算打包的文件排除
externals: {
lodash: '_',
dayjs: 'dayjs',
},
// 然后通过这种方式引入CDN就可以了
<body>
<div id="app"></div>
<div id="root"></div>
<script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
</body>
shimming
shimming是一个概念,是某一类功能的统称:
- shimming翻译过来我们称之为垫片,相当于给我们的代码填充一些垫片来处理一些问题
- 比如我们现在依赖一个第三方的库,这个第三方库本身依赖loadash,但是默认没有对lodash进行导入(认为全局存在lodash),那么我们就可以通过 ProvidePlugin 来实现 shimming 的效果
以上情况是我们的项目中使用了axios,但是我们没有安装axios的依赖,这时可以通过这种方法配置使其获得axios库,我们项目中能使用axios而不报错 ```javascript axios.get(‘https://v2.jinrishici.com/info').then((res) => { console.log(res); });// 当在代码中遇到某一个变量找不到时,我们会通过ProvidePlugin,自动导入对应的库 new webpack.ProvidePlugin({ axios: 'axios', get: ['axios', 'get'], }),
get(‘https://v2.jinrishici.com/info').then((res) => { console.log(res); });
注意:webpack并不推荐随意的使用 shimming
- webpack背后的整个理念是使前端开发更加模块化
- 也就是说,需要编写具有良好的封闭性的、不存在隐含依赖(比如全局变量)的彼此隔离的模块
<a name="Ghx98"></a>
# MiniCssExtractPlugin
MiniCssExtractPlugin可以帮助我们将css提取到一个独立的css文件中,该插件需要在webpack4+才可以使用
<a name="ul1Tm"></a>
## 安装
` npm i mini-css-extract-plugin -D`
<a name="jz4s8"></a>
## 使用
```javascript
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const isProduction = true;
module.exports = {
mode: 'production',
plugins: [
// 生产环境
new CleanWebpackPlugin({}),
new MiniCssExtractPlugin({
filename: 'css/[name].[hash:8].css',
}),
],
};
在生产环境中webpack.prod.js中引入mini-css-extract-plugin并配置使用
{
test: /\.css$/,
use: [
isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
'css-loader',
],
},
配置loader,根据环境判断使用哪个loader
module.exports = function (env) {
const isProduction = env.production;
process.env.production = isProduction;
const config = isProduction ? prodConfig : devConfig;
return merge(commonConfig(isProduction), config);
};
获取到当前环境,传入config配置文件,决定是使用webpack.prod.js还是webpack.dev.js
Hash\ContentHash\ChunkHash
在我们给打包的文件进行命名的时候,会使用placeholder,placeholder中有几个属性比较相似:
- hash、chunkhash、contenthash
- hash本身是通过MD4的散列函数处理后,生成一个128位的hash值(32个十六进制)