本文作者:IMWeb zixinfeng 原文出处:IMWeb社区 未经同意,禁止转载
// app.js
import sum from './sum'
conosle.log(sum(1,2))
// sum.js
export default function sum(a, b) {
return a + b;
}
// 打包命令: webpack app.js --output-path=dist --output-filename=bundle.js --mode development
// 指定配置文件 webpack --config webpack.config.dev.js
// 0. 单入口pageA, 不做任何的优化 直接引入 subPageA, subPageB, lodash 会发现pageA非常大
// 1. 异步引入, 将lodash打包到vendor中
require.ensure('lodash', require => {
const _ = require('lodash')
_.join([1, 2, 3], 4)
console.log(_)
}, 'vendor')
// 2. pageA.js中修改
if (page === 'subPageA') {
// require([]) 参数是空数组的话, 里面的require的包还是会被异步打包
require.ensure(['./subPageA'], require => {
// 如果不require的话, 那么就不会执行subPageA中的代码块
const subPageA = require('./subPageA')
console.log(subPageA)
}, 'subPageA')
} else if (page === 'subPageB') {
require.ensure(['./subPageB'], require => {
const subPageB = require('./subPageB')
console.log(subPageB)
}, 'subPageB')
}
// 结果: moduleA分别在打包好的文件 subPageA.chunk.js 和 subPageB.chunk.js中, 公共部分moduleA没有被提取出来
// 3. 单entry有上述公共代码的情况的话, 使用inlcude的情况处理, 将module在父模块pageA.js提前引入, 但是并不运行
require.include('./moduleA')
// 结果: moduleA被打包进入了pageA.bundle.js中, 这样就完成了代码分割
// --- import 方案 -------------
/* 坑: import 只有在stage-0 或者 syntax-dynamic-import
yarn add babel-preset-stage-0 babel-plugin-syntax-dynamic-import --dev
.babelrc { "presets": ["stage-0"], "plugins": ["syntax-dynamic-import"] }
上述两种情况只使用一种即可
*/
// 在import的时候 代码实际上已经执行了
if (page) {
import(
/* webpackChunkName: "subPageA" */
/* webpackMode: "lazy" */
'./subPageC'
).then(subPageC => {
console.log(subPageC)
})
} else {
import(
/* webpackChunkName: 'subPageD' */
/* webpackMode: "lazy" */
'./subPageD'
)
}
// webpack3
var ExtractTextWebpackPlugin = require('ExtractTextWebpackPlugin)
module: {
rules: [
{
test: /\.less$/,
use: ExtractTextWebpackPlugin.extract({
fallback: {
// 告诉webpack, 当不提取的时候, 使用何种方式将其加载到页面中
loader: 'style-loader,
options: {
singleton: true,
// transform: ''
}
},
use: [
{loader: 'css-loader'}
{loader: 'less-loader'}
], // 定义我们继续处理的loader
})
}
]
},
plugins: [
new ExtractTextWebpackPlugin({
filename: '[name].min.css', // 提取出来的css的名称
// 将css-loader的option中的minimize打开
// allChunks 给插件指定一个范围, 指定提取css的范围
// 1. 设置为true 表示所有的引用的css文件都提取
// 2. 设置为false, 默认, 只会提取初始化的css(异步加载不认为是初始化)
allChunks:false,
})
]
// webpack3 结果: index.bundle.js app.min.css 但是打开index.html 并没有插入进去
// webpack4
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
// loader: 'file-loader'
options: {
minimize: process.env.NODE_ENV === 'production',
modules: true,
localIdentName: '[path]_[name]_[local]--[hash:base64:5]'
}
},
{
loader: 'less-loader'
}
]
}
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].css',
chunkFilename: '[id].css'
})
]
- 异步引入a.js文件, 在a.js文件中引入a.less
1. 针对allChunks为false的情况
- webpack3: 生成a.bundle.js文件, css文件被当成js的一个模块被打包处理, 将css放在js文件里面, 一起被提取; css代码切分的一种方式, 将初始化加载和动态加载区分开; 借助动态加载的代码区分, 也是css-in-js的一个概念
- weboack4: 生成moduleA.chunk.js 和moduleA.chunk.css文件, 在index.bundle.js 包括了对于modulA.js和module.css文件的引用
2. webpack4使用splitChunks配置
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
test: /\.scss|css$/,
chunks: 'all', // merge all the css chunk to one file
enforce: true
}
}
}
}
- 结果: 生成index.bundle.js style.chunk.js style.chunk.css 将所有的样式文件都打包进了style.chunk.css文件中, 但是需要手动添加到项目htm中
- question: 为什么这里不会运行? npm run extract
{
loader: 'postcss-loader',
options: {
// require进来的插件给postcss使用的
ident: 'postcss', // 表明接下来的插件是给postcss使用的
plugins: [
// require('autoprefixer')(),
// 两个一起用cssnext 会给出警告, 提示已经包含autoprefixer
require('postcss-cssnext')()
]
}
},