webpack 公共引入模块代码分离及懒加载
导读
在该篇博文中,我们将分别部署生产和开发的webpack打包编译以及项目运行环境
项目地址:https://github.com/RiversCoder/webpack-test
基本的代码分离案例
- 在
src
目录下编辑index.js
如下:
import _ from 'lodash' // index.js中引入了lodash
import printMe from './project.js'
function component(){
var element = document.createElement("div")
element.innerHTML = _.join(['Hello ','webpack'], ' ')
element.classList.add('box')
// 新增点击按钮
var btn = document.createElement('button')
btn.innerHTML = '点击我会打印信息';
btn.onclick = printMe
element.appendChild(btn)
return element
}
document.body.appendChild(component())
- 在
src
目录下新建且编辑another-module.js
如下:
import _ from 'lodash'; // 再次引入 lodash
console.log(
_.join(['Another', 'module', 'loaded!'], ' ')
);
- 编辑
webpack.config.js
如下:
const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const webpack = require('webpack');
module.exports = {
entry: {
index: './src/index.js',
another: './src/another-module.js'
},
plugins: [
new CleanWebpackPlugin(),
new HTMLWebpackPlugin({
title: '公共引用模块分离'
}),
/* new webpack.optimize.CommonsChunkPlugin({ // 新版本webpack已失效
name: 'common' // 指定公共模块 bundle 的名称
})*/
],
optimization:{
splitChunks:{
cacheGroups: {
commons: {
name: "public", // 指定公共模块 bundle 的名称
chunks: "initial",
minChunks: 2
}
}
}
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
- 执行打包编译命令,运行如下:
D:\me\npm\test\webpack-test>npx webpack --config webpack.config.js
Hash: 1521ed06fe54bd80921e
Version: webpack 4.34.0
Time: 1192ms
Built at: 2019-06-18 2:40:14 PM
Asset Size Chunks Chunk Names
another.bundle.js 1.54 KiB 1 [emitted] another
index.bundle.js 1.8 KiB 2 [emitted] index
index.html 312 bytes [emitted]
public.bundle.js 69.4 KiB 0 [emitted] public
Entrypoint index = public.bundle.js index.bundle.js
Entrypoint another = public.bundle.js another.bundle.js
[1] (webpack)/buildin/global.js 472 bytes {0} [built]
[2] (webpack)/buildin/module.js 497 bytes {0} [built]
[3] ./src/another-module.js 88 bytes {1} [built]
[4] ./src/index.js + 1 modules 686 bytes {2} [built]
| ./src/index.js 571 bytes [built]
| ./src/project.js 110 bytes [built]
+ 1 hidden module
Child html-webpack-plugin for "index.html":
1 asset
Entrypoint undefined = index.html
[2] (webpack)/buildin/global.js 472 bytes {0} [built]
[3] (webpack)/buildin/module.js 497 bytes {0} [built]
+ 2 hidden modules
动态加载模块案例
当涉及到动态代码拆分时,webpack
对于动态导入,第一种,使用es6
的 import()
语法(优先)。第二种,则是使用 webpack
特定的 require.ensure
。让我们先尝试使用第一种:
使用import
引入的方法
function component(){
return import(/*webpackChunkName:"lodash"*/'lodash').then(lod => {
var element = document.createElement("div")
element.innerHTML = lod.join(['Hello ','webpack'], ' ') // 调用
return element
}).catch(err => '加载lodash错误')
}
component().then(c => {
document.body.appendChild(c)
})
async
和await
精简版
async function component(){
let lod = await import(/*webpackChunkName:"lodash"*/'lodash')
var element = document.createElement("div")
element.innerHTML = lod.join(['Hello ','webpack'], ' ') // 调用
return element
}
component().then(box => {
document.body.appendChild(box)
})
打包编译如下:
D:\me\npm\test\webpack-test>npx webpack --config webpack.config.js
Hash: e87e77b6f4cdf0d9895e
Version: webpack 4.34.0
Time: 1168ms
Built at: 2019-06-18 3:09:36 PM
Asset Size Chunks Chunk Names
index.bundle.js 2.31 KiB 0 [emitted] index
index.html 185 bytes [emitted]
vendors~lodash.bundle.js 69.4 KiB 1 [emitted] vendors~lodash
Entrypoint index = index.bundle.js
[0] ./src/index.js 530 bytes {0} [built]
[2] (webpack)/buildin/global.js 472 bytes {1} [built]
[3] (webpack)/buildin/module.js 497 bytes {1} [built]
+ 1 hidden module
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
Child html-webpack-plugin for "index.html":
1 asset
Entrypoint undefined = index.html
[2] (webpack)/buildin/global.js 472 bytes {0} [built]
[3] (webpack)/buildin/module.js 497 bytes {0} [built]
+ 2 hidden modules
使用require.ensure
引入的方法
async function component(){
let lod = await require.ensure([],()=>(require('lodash')),'lodash')
var element = document.createElement("div")
element.innerHTML = lod.join(['Hello ','webpack'], ' ') // 调用
return element
}
component().then(box => {
document.body.appendChild(box)
})
webpack
懒加载案例
懒加载又叫按需加载,是一种很好的优化网页或应用的方式。这种方式实际上是先把你的代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。这样加快了应用的初始加载速度,减轻了它的总体体积,因为某些代码块可能永远不会被加载。
- 编辑
src/index.js
如下:
import lod from 'lodash'
function component(){
var element = document.createElement("div")
element.innerHTML = lod.join(['Hello ','webpack'], ' ') // 调用
// new add +
var button = document.createElement('button');
var br = document.createElement('br');
button.innerHTML = '点击后将打印信息到控制台';
element.appendChild(br);
element.appendChild(button);
button.onclick = e => import(/* webpackChunkName: "print" */ './project').then(module => {
console.log(module)
var project = module.default;
project.printMe()
})
return element
}
document.body.appendChild(component())
- 编辑
src/project.js
如下:
console.log("The project.js module has loaded! See the network tab in dev tools...")
exports.printMe = function () {
console.log('我会打印这条信息123..')
}
- 打包编译运行:
D:\me\npm\test\webpack-test>npx webpack --config webpack.config.js
Hash: 7e5a47691287c4977989
Version: webpack 4.34.0
Time: 4671ms
Built at: 2019-06-18 3:40:52 PM
Asset Size Chunks Chunk Names
index.bundle.js 71.7 KiB 0 [emitted] index
index.html 185 bytes [emitted]
print.bundle.js 213 bytes 1 [emitted] print
Entrypoint index = index.bundle.js
[1] ./src/index.js 621 bytes {0} [built]
[2] (webpack)/buildin/global.js 472 bytes {0} [built]
[3] (webpack)/buildin/module.js 497 bytes {0} [built]
[4] ./src/project.js 155 bytes {1} [built]
+ 1 hidden module
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
Child html-webpack-plugin for "index.html":
1 asset
Entrypoint undefined = index.html
[2] (webpack)/buildin/global.js 472 bytes {0} [built]
[3] (webpack)/buildin/module.js 497 bytes {0} [built]
+ 2 hidden modules
- 最终运行交互效果