有三种常用的代码分离方法:
- 入口起点:使用
entry
配置手动地分离代码。 - 防止重复:使用
CommonsChunkPlugin
去重和分离 chunk。(CommonsChunkPlugin已经从 webpack v4(代号 legato)中移除,使用SplitChunksPlugin
插件可以将公共的依赖模块提取到已有的 entry chunk 中,或者提取到一个新生成的 chunk。) - 动态导入:通过模块的内联函数调用来分离代码。
module.exports = { entry: { index: './src/index.js', another: './src/another-module.js' }, plugins: [ new HTMLWebpackPlugin({ title: 'Code Splitting' }) ], output: { filename: '[name].bundle.js',//生成分离代码 path: path.resolve(__dirname, 'dist') },
optimization: {
splitChunks: {//删除重复依赖项,分离到一个单独的 chunk 中
chunks: 'all'
}
}
};
ExtractTextPlugin
: 用于将 CSS 从主应用程序中分离。(webpack 3)(webpack 4 使用 mini-css-extract-plugin)bundle-loader
: 用于分离代码和延迟加载生成的 bundle。promise-loader
: 类似于bundle-loader
,但是使用的是 promises。
const ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { module: { rules: [ { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: "css-loader" }) } ] }, plugins: [ new ExtractTextPlugin("styles.css"), ] }
它会将所有的入口 chunk(entry chunks)中引用的 *.css
,移动到独立分离的 CSS 文件。因此,你的样式将不再内嵌到 JS bundle 中,而是会放到一个单独的 CSS 文件(即 styles.css
)当中。
多个实例
const ExtractTextPlugin = require('extract-text-webpack-plugin'); // 创建多个实例 const extractCSS = new ExtractTextPlugin('stylesheets/[name]-one.css'); const extractLESS = new ExtractTextPlugin('stylesheets/[name]-two.css'); module.exports = { module: { rules: [ { test: /\.css$/, use: extractCSS.extract([ 'css-loader', 'postcss-loader' ]) }, { test: /\.less$/i, use: extractLESS.extract([ 'css-loader', 'less-loader' ]) }, ] }, plugins: [ extractCSS, extractLESS ] };
修改文件名
entry: {
'js/a': "./a"
},
plugins: [
new ExtractTextPlugin({
filename: (getPath) => {
return getPath('css/[name].css').replace('css/js', 'css');
},
allChunks: true
})
]
demo地址:webpack-auto-refresh
动态导入
import()
语法 来实现动态导入
module.exports = { mode: 'development', entry: { index: './src/index.js' }, output: { filename: '[name].bundle.js', chunkFilename: '[name].bundle.js',//非入口 chunk 名称 path: path.resolve(__dirname, 'dist') } };
webpack v4.6.0+ 添加了预取和预加载的支持。
- prefetch(预取):将来某些导航下可能需要的资源
- preload(预加载):当前导航下可能需要资源
import(/* webpackPrefetch: true */ 'LoginModal');
这会生成 <link rel="prefetch" href="login-modal-chunk.js">
并追加到页面头部,指示着浏览器在闲置时间预取 login-modal-chunk.js
文件。
import(/* webpackPreload: true */ 'ChartingLibrary');
在页面中使用 ChartComponent
时,在请求 ChartComponent.js 的同时,还会通过 <link rel="preload">
请求 charting-library-chunk。
动态地加载模块。调用 import()
之处,被作为分离的模块起点,意思是,被请求的模块和它引用的所有子模块,会分离到一个单独的 chunk 中。
import()
会返回一个 promise。
import("./math").then(math => {
console.log(math.add(16, 26));
});