This plugin extracts CSS into separate files. It creates a CSS file per JS file which contains CSS. It supports On-Demand-Loading of CSS and SourceMaps.css
用某度翻譯後:「該插件將CSS提取到單獨的文件中。它爲每一個包含CSS的JS文件建立一個CSS文件。它支持CSS和SourceMap的按需加載。」html
包含CSS的JS文件,JS文件不是指組件對應的JS文件,是指打包後生成的JS文件。 webpack
在Webpack4.0以前,是用ExtractTextWebpackPlugin插件來提取css的,與其相比有以下優勢git
搭建個簡單的Wenpack Demo,演示一下。github
先安裝MiniCssExtractPlugin插件。web
npm install --save-dev mini-css-extract-plugin
複製代碼
安裝成功後,在webpack.config.js文件中配置。npm
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: {
main: "./src/main.js",
},
plugins:[
new MiniCssExtractPlugin(),
],
module:{
rules:[
{
test: /\.css$/,
use:[MiniCssExtractPlugin.loader,'css-loader']
},
]
}
}
複製代碼
入口文件爲main.js瀏覽器
import './css/main.css'
import './index'
console.log('main')
複製代碼
index.jsbash
import './css/index.css'
import './index'
console.log('main')
複製代碼
main.css和index.css內容同樣異步
.class{
color:red
}
複製代碼
執行命令webpack
,能夠在dist文件夾中看到打包生成的三個文件
項目中有兩個包含CSS的JS文件,可是隻打包生成了一個CSS文件,證明了上面 「它爲每一個包含CSS的JS文件建立一個CSS文件」中的包含CSS的JS文件是指打包後生成的JS文件。
在瀏覽器打開index.html,在開發者工具中能夠看到以下圖所示
打包生成的CSS文件用link
標籤引入
若是沒有用MiniCssExtractPlugin插件呢,改一下webpack.config.js文件中配置。
module:{
rules:[
{
test: /\.css$/,
use:['style-loader','css-loader']
},
]
}
複製代碼
再執行webpack
命令。在瀏覽器打開index.html,會發現樣式在頭部用<style></style>
嵌入式引入。
看到這裏也應該明白了MiniCssExtractPlugin插件的做用,就是提取JS中的CSS樣式,用link
外部引入,減小JS文件的大小,簡稱CCSS樣式分離。
MiniCssExtractPlugin插件不能和style-loader共用
控制從打包後的入口JS文件中提取CSS樣式生成的CSS文件的名稱。
module.exports = {
entry: {
main: "./src/main.js",
},
plugins:[
new MiniCssExtractPlugin({
filename: '[name]-test.css',
}),
]
}
複製代碼
執行webpack
命令,能夠在dist文件夾中看到打包生成的CSS文件名稱爲main-test.css
控制從打包後的非入口JS文件中提取CSS樣式生成的CSS文件的名稱。
module.exports = {
entry: {
main: "./src/main.js",
},
plugins:[
new MiniCssExtractPlugin({
filename: '[name]-test.css',
chunkFilename: '[name]-test.css'
}),
]
}
複製代碼
main.js
import './css/main.css'
import(/*webpackChunkName: "index"*/ './index')
console.log('main')
複製代碼
執行webpack
命令,能夠在dist文件夾中看到非入口JS文件index.bundle.js提取出來的CSS文件名爲index-test.css。
該參數的值是個函數,主要應用多入口場景,控制從打包後的入口JS文件中提取CSS樣式生成的CSS文件的名稱。
若是和filename
參數共用,filename
將不起做用。
module.exports = {
entry: {
main: "./src/main.js",
main1: "./src/main1.js",
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].css',
moduleFilename: (
{ name }) => {
return `${name}.css`
},
}),
],
}
複製代碼
執行webpack
命令,打包生成的文件以下圖所示
控制css的引入順序不一致是否警告,true
表示警告,false
表示不警告。
簡單的說,就是在js裏css的引入順序致使的問題,多個css的在js裏的引入順序不一樣,就會有這個警告。例如,在1.js 裏,引入的順序是a.css, b.css; 在2.js裏,引入順序是b.css,a.css,出現了這種引入順序不一樣,就致使了警告。在兩個js裏把引入順序調成一致,就沒問題了。在1.js和2.js裏的引入順序都調整成a.css, b.css 就沒有那個警告了。
固然也能夠設置ignoreOrder
參數爲false
,關閉這些警告。
默認值是webpackOptions.output,以下面所示,默認值就是path.resolve(__dirname, 'dist')
。
module.exports = {
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, 'dist'),
},
}
複製代碼
做用是指定目標文件的定製公共路徑。有點難理解,下面用一個實例來解釋。
main.css
body{
background: url('./LOGO.png');
}
複製代碼
main.js入口文件
import './css/main.css'
console.log('main')
複製代碼
由於main.css中引入圖片,要用file-loader處理一下。在webpack.config.js中這麼配置
module.exports = {
module: {
rules: [
{
test: /\.png$/,
use: [
{
loader: 'file-loader',
options: {
name: 'img/[name].[hash:8].[ext]'
}
}
]
},
],
},
};
複製代碼
執行webpack
命令,打包生成的CSS文件以下main.css以下所示
若是改一下生成的CSS文件路徑。
module.exports = {
plugins:[
new MiniCssExtractPlugin({
filename: 'css/[name].css',
}),
]
}
複製代碼
再執行webpack
命令,打包生成的CSS文件以下main.css以下所示
由於main.css 中圖片的引用路徑是img/LOGO.af6d901d.png
,顯然路徑不對,因此圖片沒法加載出來,要把圖片的引用路徑改爲../img/LOGO.af6d901d.png
才能夠加載出來。
可是不可能去修改打包生成的文件,那要如何解決這個錯誤呢?此時publicPath參數的做用就體現出來了,能夠利用publicPath參數來修改圖片的引用路徑,修改一下webpack.config.js的配置。
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader:MiniCssExtractPlugin.loader,
options:{
publicPath:'../'
}
},
'css-loader']
},
],
}
}
複製代碼
再執行webpack
命令,打包生成的CSS文件以下main.css以下所示
在瀏覽器打開index.html,圖片能夠加載出來。
publicPath的做用指定目標文件的定製公共路徑,能夠理解爲指定../img/LOGO.af6d901d.png
中img
前面的路徑../
。
默認值爲false
,表明MiniCssExtractPlugin生成使用CommonJS模塊語法的JS模塊。
若爲true
,表明MiniCssExtractPlugin生成使用ES6模塊語法的JS模塊。
默認爲false
,爲true
時啓動樣式文件熱更新。
在不啓用樣式文件熱更新時,修改CSS源文件的時候,修改的樣式不會自動在頁面上顯示,須要手動刷新頁面,纔會加載變化。啓動樣式文件熱更新後,再也不須要刷新整個頁面,修改的樣式就能夠自動在頁面上顯示。
上面說到過MiniCssExtractPlugin插件不能和style-loader共用,通常在開發環境中配置style-loader,在生產環境中配置MiniCssExtractPlugin插件。其實style-loader也能夠實現樣式文件熱更新。
HMR is an opt-in feature that only affects modules containing HMR code. One example would be patching styling through the style-loader. In order for patching to work, the style-loader implements the HMR interface; when it receives an update through HMR, it replaces the old styles with the new ones.
可是MiniCssExtractPlugin插件的樣式文件熱更新比style-loader更強大一些。好比說在public文件夾中的index.html引入一個CSS樣式文件,若是修改了這個CSS樣式文件的源碼,使用style-loader是不會觸發樣式文件熱更新,由於style-loader只熱更新JS中引入的樣式,但MiniCssExtractPlugin插件會熱更新加載全部的樣式。
通常只在生產環境中將hmr
設置爲true
。
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader:MiniCssExtractPlugin.loader,
options:{
publicPath:'../',
hmr: process.env.NODE_ENV === 'development',
}
},
'css-loader']
},
],
}
}
複製代碼
if hmr does not work, this is a forceful method.
通常配合hrm
參數使用,爲true
時,表示樣式文件熱更新不起做用時從新加載所有樣式。
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader:MiniCssExtractPlugin.loader,
options:{
publicPath:'../',
hmr: process.env.NODE_ENV === 'development',
reloadAll: true
}
},
'css-loader']
},
],
}
}
複製代碼
用SplitChunks插件去實現。SplitChunks插件的具體用法能夠看我另外一篇文章:Webpack之SplitChunks插件用法詳解
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
test: /\.css$/,
chunks: 'all',
enforce: true,
},
},
},
},
}
複製代碼
執行webpack
命令,打包生成的文件以下以下所示