分离样式文件
首先来看怎么处理工程中的纯 CSS
首先要考虑如何输出单独的CSS文件,一般来说,在生产环境下,我们希望样式存在于CSS文件中而不是style标签中,因为文件更有利于客户端进行缓存。那么可以使用专门的插件extract-text-webpack-plugin、mini-cssextract-plugin,来解决这些问题,它们就是专门用来提取样式到CSS文件的
extract-text-webpack-plugin
首先用npm安装
npm install extract-text-webpack-plugin
在webpack.config.js中引入:
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: './app.js',
output: {
filename: 'bundle.js',
},
mode: 'development',
module: {
rule: {
{
test: /\.css$/,
use: ExtractTextPlugin.extract{{
fallback: 'style-loader',
use: 'css-loader',
}}
}
}
},
plugin: {
new ExtractTextPlugin("bundle.css")
}
}
在module.rules 中我们设置了处理 CSS 文件的规则,其中的use字段并没有直接传入loader,而是使用了插件的extract 方法包了一层。内部的 fallback 属性用于指定当插件无法提取样式时所采用的 loader(目前还接触不到这种场景,后面会介绍),use(extract方法里面的)用于指定在提取样式之前采用哪些 loader 来预先进行处理。除此之外还要在 Webpack的 plugins 配置中添加该插件,并传入提取后的资源文件名。
plugins用于接收一个插件数组,我们可以使用 Webpack 内部提供的一些插件,也可加载外部插件。Webpack 为插件提供了各种API,使其可以在打包的各个环节中添加些额外任务
打包后最终的结果是增加了 bundle.css,正是我们在插件中指定的文件名
多样式文件的处理
样式的提取是以资源入口开始的整个chunk为单位的。假设我们的应用从index.js 开始一层层引人了几百个模块,也许其中很多模块都引入了各自的样式,但是最终只会生成一个CSS文件,因为它们都来自同一个入口模块。
当工程有多个入口时就会发生重名问题。就像在前面的章节中我们配置动态的output.filename一样,这里我们也要对插件提取的 CSS 文件使用类似模板的命名方式
假设我们有 foo.js和bar.js,并且它们分别引用了 foo-style.css和bar-style.css,现在我们要通过配置使它们输出各自的 CSS文件。
// webpack.config.js
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: {
foo: './src/scripts/foo.js',
bar: './src/scripts/bar.js',
},
output:{
filename: '[name].js',
},
mode: 'development',
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract{{
fallback: 'style-loader',
use: 'css-loader',
}}
}
]
},
plugin: {
new ExtractTextPlugin("[name].css")
}
}
上面使用了[name].css来动态生成CSS为文件名。这里的[name]和在 output.filename中的意义一样,都是指代chunk的名字,即entry 中我们为每一个人口分配的名字(foo bar)。
mini-css-extract-plugin
mini-css-extract-plugin 可以理解成extract-text-webpack-plugin 的升级版,它的特性是支持按需加载CSS
mini-css-extract-plugin会单独打包出一个0.css(假设使用默认配置)这个CSS文件将a.js通过动态插 link标签的方式加载
webpack.config.js配置如下:
// webpack.config.js
const MiniCssExtractplugin = require('mini-css-extract-plugin');
module.exports = {
entry: './app.js',
output:{
filename: '[name].js',
},
mode: 'development',
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
},
},
'css-loader'
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css',
})
]
}
在配置上 mini-css-extract-plugin 与extract-text-webpack-plugin 有以下几点不同
- loader 规则设置的形式不同,并且 mini-css-extract-plugin 支持配置 publicPath;用来指定异步 CSS的加载路径
- 不需要设置 fallback
- 在plugins设置中,除了指定同步加的 CSS 资源名 (flename),还要指定异步加载的CSS资源名(chunkFilename)。