一.调整目录
1.
2.添加脚本:
package.json
"scripts": {
"dev": "webpack-dev-server --config ./build/webpack.dev.js",
"build": "webpack --config ./build/webpack.prod.js",
"dev-build": "webpack --config ./build/webpack.dev.js"
},
运行npm run dev-build
,在build目录下生成了dist目录,应该把dist目录移到build目录同级,对应webpack.common.js应该做调整:
项目调整ok~
二.手动分隔代码
将使用到lodash这个库,先进行安装:
npm i lodash --save
index.js
//假设引入的库大小为1mb
import _ from 'lodash'
//业务逻辑代码大小为1mb
//字符串连接
console.log(_.join(['a', 'd', 'c'], '***'))
//此处省略一万行代码
console.log(_.join(['a', 'b', 'c'], '***'))
然后运行npm run build
,页面打印控制台现实如下:
打印出字符串拼接的结果。
分析这种方式的结果:
打包生成app.bundle.js,文件里包含lodash库
*首次访问页面时,加载app.bundle.js: 2mb
*需要加载2mb的js文件
*打包文件会很大,加载时间会长
*修改业务代码, 重新访问页面, 又需要重新加载2mb的内容
三.入口起点(entry points)
我们希望把lodash库与业务逻辑代码分开打包成两个文件,来看另外一种方式:
src/index.js
//1mb
// import _ from 'lodash'
//业务逻辑:1mb
//字符串连接
console.log(_.join(['a', 'd', 'c'], '***'))
//此处省略一万行代码
console.log(_.join(['a', 'b', 'c'], '***'))
在src下新建lodash.js文件
src/lodash.js
import _ from 'lodash';
console.log(
_.join(['liu', 'ding', 'li!'], ' ')
);
运行npm run dev-build
,生成的目录结构如下:
这里看到已经分别生成了两个文件。
这种方式: app.bundle.js被拆成lodash.bundle.js(1mb), app.bundle.js(1mb),
*浏览器并行加载文件
*当页面业务逻辑发生变化时,只要加载app.bundle.js即可(1mb)
但这种方法存在一些问题:
*如果入口 chunks 之间包含重复的模块,那些重复模块都会被引入到各个 bundle 中。
*这种方法不够灵活,并且不能将核心应用程序逻辑进行动态拆分代码。
以上两点中,第一点对我们的示例来说无疑是个问题,因为之前我们在 ./src/index.js 中也引入过 lodash,这样就在两个 bundle 中造成重复引用。
四.webpack自动实现code splitting
删除掉lodash.js文件
src/index.js
import _ from 'lodash'
console.log(_.join(['a', 'd', 'c'], '***'))
console.log(_.join(['a', 'b', 'c'], '***'))
代码分割: webpack在处理公用内库的时候,会自动把库打包成单独一个文件,业务逻辑再打包成一个文件。
webpack.common.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader', //babel-loader:babel和webpack中间的桥梁
options: {
"presets": [
[
//es6=>es5
"@babel/preset-env", {
"targets": {
// "edge": "17",
// "firefox": "60",
// "chrome": "67",
"safari": "11.1", //以上版本已经支持es6,不需要再做es6=>es5
},
useBuiltIns: 'usage'
}
],
"@babel/preset-react", //转化react代码
],
}
},
{
test:/\.css$/,
use: [
'style-loader',
'css-loader'
]
},
]
},
entry: {
app: './src/index.js',
// lodash: './src/lodash.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, '../dist'),
//publicPath也会在服务器脚本用到,确保资源能够在 http://localhost:3000下正确访问
// publicPath: '/'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CleanWebpackPlugin(),
],
//代码分割
optimization: {
splitChunks: {
chunks: 'all',
},
}
}
运行npm run dev-build
,生成目录结构如下:
不需要我们手动分割代码,只需要在webpack.common.js中做optimization的配置项
当遇到公用内库时,会自动把内库打包生成一个文件,业务逻辑再拆分成一个文件。webpack自动借助插件实现了code splitting。
五.异步代码自动进行代码分割
src/index.js
function getComponent() {
return import('lodash').then(({ default: _ }) => {
var ele = document.createElement('div')
ele.innerHTML = _.join(['yang', 'yue'], '-')
return ele
})
}
getComponent().then(ele => {
document.body.appendChild(ele)
})
运行npm run dev-build
,依然生成两个打包文件:
加载lodash库是异步加载的,这个库就会被单独放到一个文件里去。
总结:
-代码分割和webpack无关
-webpack中实现代码分割,两种方式:
(1)同步代码: 只需要在webpack.common.js中做optimization的配置项
optimization: {
splitChunks: {
chunks: ‘all’
}
}
(2)异步代码(import): 异步代码无需做任何配置,会自动进行代码分割,放置到新的文件中