webpack中css文件的代码分割
module.exports = { output: { filename: '[name].js', chunkFilename: '[name].chunk.js', path: path.resolve(__dirname, '../dist') } }
在看别人写的webpack,output配置项,肯跟会碰到chunkFilename这样的配置项,那这个是什么意思呢?filename和chunkFilename有什么区别呢?首先看个例子
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>html template</title> </head> <body> <div id='root'></div> </body> </html>
index.js
async function getComponent() { const { default: _ } = await import(/* webpackChunkName:'lodash' */'lodash'); const element = document.createElement('div'); element.innerHTML = _.join(['1', '2'], '-'); return element } document.addEventListener('click', ()=> { getComponent().then( element =>{ document.body.appendChild(element); }) })
webpack.common.js
module.exports = { entry: { main: './src/index.js' }, output: { filename: '[name].js', chunkFilename: '[name].chunk.js', path: path.resolve(__dirname, '../dist') } }
运行npm run dev-build打包。打开dist目录,发现第三方模块打包好的名字叫vendors~lodash.chunk.js,不再是之前的vendors~lodash.js。我们的入口文件对应的都是filename的输出。如果不是入口文件,是异步引入或者间接产生的js文件,他就会走chunkFilename这个输出的配置参数。
接下来进入主题,css代码的分割
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>html template</title> </head> <body> <div id='root'></div> </body> </html>
index.js
import './style.css';
console.log(' hello world ');
style.css
body{ background: #abcdef; }
运行npm run dev-build。发现打包生成的文件只有main.js 和 vendors~main.chunk.js。但是浏览器打开index.html。背景已经有了。这是怎么回事呢?webpack在做css的打包的时候,会直接打包到js里面
如果我希望在打包生成代码的时候,如果我引入了css文件,那么把css文件打包到dist目录下。而不是直接引入到js文件里面。那么就需要引入一个插件
https://webpack.js.org/plugins/mini-css-extract-plugin
npm install --save-dev mini-css-extract-plugin
这个插件可以对css进行代码分割。这个插件不适合开发环境,因为官网说了,这个插件现在还暂时不支持热更新。
安装好之后看怎么使用,首先要在webpack中引入这个插件。首先打开线上配置文件
webpack.prod.js
const merge = require('webpack-merge'); const commonConfig = require('./webpack.common.js'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const prodConfig = { mode: 'production', devtool: 'cheap-module-source-map', module: { rules:[{ test: /\.scss$/, use: [ MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { importLoaders: 2 } }, 'sass-loader', 'postcss-loader' ] },{ test: /\.css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader' ] }] }, plugins:[ new MiniCssExtractPlugin({}) ] } module.exports = merge(commonConfig, prodConfig);
然后对应到webpack.common.js里面删除css,scss相关到配置。运行npm run build。发现多出了两个文件main.css 和 main.css.map
css打包好后,是未压缩的,要将打包好的css进行压缩,安装,optimize-css-assets-webpack-plugin
npm install optimize-css-assets-webpack-plugin -D
在webpack.props.js引入并配置
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); module.exports = { optimization: { minimizer: [new OptimizeCSSAssetsPlugin({})], }, }
运行 npm run build。会发现css文件被自动的合并压缩。
还有更高级的用法, 假设有很多个css,要打包到一个css文件里面
https://webpack.js.org/plugins/mini-css-extract-plugin
也可以实现
optimization: { splitChunks: { cacheGroups: { styles: { name: 'styles', test: /\.css$/, chunks: 'all', enforce: true, // 忽略到前面到配置,不管是minSize,maxSize等等,只要是css,都打包到同一个文件中 }, }, }, },