æ¬æä»¶ä¼å° CSS æåå°åç¬çæä»¶ä¸ï¼ä¸ºæ¯ä¸ªå å« CSS ç JS æä»¶å建ä¸ä¸ª CSS æä»¶ï¼å¹¶ä¸æ¯æ CSS å SourceMaps çæéå è½½ã
æ¬æä»¶åºäº webpack v5 çæ°ç¹æ§æå»ºï¼å¹¶ä¸éè¦ webpack 5 æè½æ£å¸¸å·¥ä½ã
ä¸ extract-text-webpack-plugin ç¸æ¯ï¼
é¦å
ï¼ä½ éè¦å®è£
mini-css-extract-pluginï¼
npm install --save-dev mini-css-extract-plugin建议 mini-css-extract-plugin ä¸ css-loader ä¸èµ·ä½¿ç¨ã
ä¹åå° loader ä¸ plugin æ·»å å°ä½ ç webpack é
ç½®æä»¶ä¸ã ä¾å¦ï¼
style.css
body {
background: green;
}component.js
import "./style.css";webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};â ï¸ æ³¨æï¼å¦æä½ ä» webpack å ¥å£å¤å¯¼å ¥ CSS æè å¨ åå§ chunk ä¸å¼å ¥ styleï¼
mini-css-extract-pluginåä¸ä¼å°è¿äº CSS å è½½å°é¡µé¢ä¸ã请使ç¨html-webpack-pluginèªå¨çælinkæ ç¾æè å¨å建index.htmlæä»¶æ¶ä½¿ç¨linkæ ç¾ã
â ï¸ source map åªå¨
source-map/nosources-source-map/hidden-nosources-source-map/hidden-source-map弿 åµä¸èµ·ä½ç¨ï¼å 为 CSS ä» æ¯æå¸¦æsourceMappingURL注éç source map (ä¾å¦//# sourceMappingURL=style.css.map)ãå¦æä½ éè¦å°devtoolè®¾ç½®ä¸ºå ¶ä»å¼ï¼ä½ å¯ä»¥ä½¿ç¨css-loaderä¸çsourceMap: trueæ¥å¯ç¨æåå¹¶çæ CSS ç source mapã
| é项å | ç±»å | é»è®¤å¼ | æè¿° |
|---|---|---|---|
filename | {String|Function} | [name].css | æ¤é项å³å®äºè¾åºçæ¯ä¸ª CSS æä»¶çåç§° |
chunkFilename | {String|Function} | based on filename | æ¤é项å³å®äºéå ¥å£ç chunk æä»¶åç§° |
ignoreOrder | {Boolean} | false | ç§»é¤ Order è¦å |
insert | {String|Function} | var head = document.getElementsByTagName("head")[0];head.appendChild(linkTag); | 卿å®ä½ç½®å° éåå§ï¼ç± async ä¿®é¥°ï¼ ç CSS chunk æå
¥ link æ ç¾ |
attributes | {Object} | {} | 为 éåå§ï¼ç± async ä¿®é¥°ï¼ ç CSS chunk æå¤ç link æ ç¾æ·»å èªå®ä¹å±æ§ |
linkType | {String|Boolean} | text/css | å 许使ç¨èªå®ä¹ link ç±»åå è½½å¼æ¥ chunk |
runtime | {Boolean} | true | å 许å¯å¨/ç¦ç¨ runtime çæ |
experimentalUseImportModule | {Boolean} | undefined | 使ç¨å®éªæ§ç webpack API æ¥æ§è¡æ¨¡åï¼èéå代ç¼è¯å¨ |
filenameç±»åï¼String|Function
é»è®¤å¼ï¼[name].css
æ¤é项å³å®äºè¾åºçæ¯ä¸ª CSS æä»¶çåç§°ã
æºå¶ç±»ä¼¼äº output.filenameã
chunkFilenameç±»åï¼String|Function
é»è®¤å¼ï¼based on filename
å°
chunkFilename设置为functionï¼ä» å¨ webpack@5 ä¸å¯ç¨ã
æ¤é项å³å®äºéå ¥å£ç chunk æä»¶åç§°
æºå¶ç±»ä¼¼äº output.chunkFilename
ignoreOrderç±»åï¼Boolean
é»è®¤å¼ï¼false
ç§»é¤ Order è¦å å ·ä½ç»è请åé 示ä¾ã
insertç±»åï¼String|Function
é»è®¤å¼ï¼document.head.appendChild(linkTag);
â ï¸ ä» å¯¹ éåå§ï¼ç± async ä¿®é¥°ï¼ chunk ææã
é»è®¤æ
åµä¸ï¼mini-css-extract-plugin ä¼å° stylesï¼<link> å
ç´ ï¼éå å°å½å window ç document.head ä¸ã
ä½å¨æäºæ
åµä¸ï¼å¯è½éè¦å¯¹éå çç®æ è¿è¡ç²¾ç»å管çï¼çè³å»¶è¿ link å
ç´ çæå
¥ã
ä¾å¦ï¼å½ä½ å¨ iframe ä¸è¿è¡åºç¨ç¨åºå¼æ¥å è½½æ ·å¼æ¶ï¼å°±å±äºæ¤æ
åµã
å¯¹äºæ¤ç±»æ
åµï¼insert å¯è¢«é
ç½®ä¸ºå½æ°æèªå®ä¹çéæ©å¨ã
妿éå ç®æ 为 iframeï¼è¯·ç¡®ä¿ç¶ææ¡£æè¶³å¤çè®¿é®æéè¿å ¥ frame documentï¼å¹¶å°å ç´ éå å°å®ä¸é¢ã
Stringå
许设置èªå®ä¹ç query selectorã
æ°ç <link> å
ç´ å°è¢«æå
¥å°æ¾å°ç item ä¹åã
webpack.config.js
new MiniCssExtractPlugin({
insert: "#some-element",
});æ¾å° id 为 some-element çå
ç´ ï¼å¨å®ä¹åæå
¥æ°ç <link> å
ç´ ã
Functionå 许è¦çé»è®¤è¡ä¸ºï¼å¹¶å¨ä»»æä½ç½®æå ¥æ ·å¼ã
â æ³¨æï¼è¿æ®µä»£ç å°ä¸ä½ çåºç¨ç¨åºä¸èµ·å¨æµè§å¨ä¸è¿è¡ãç±äºå¹¶éæææµè§å¨é½æ¯æ ESMA ç¹æ§ï¼å¦
letï¼constï¼arrow function expressionçï¼æä»¬å»ºè®®åªä½¿ç¨ ECMA 5 çç¹æ§åè¯æ³ã
â
insert彿°è¢«åºåå为åç¬¦ä¸²å¹¶ä¼ éç»æä»¶ãè¿æå³çå®å°æ æ³è®¿é® webpack é 置模åçä½ç¨åã
webpack.config.js
new MiniCssExtractPlugin({
insert: function (linkTag) {
var reference = document.querySelector("#some-element");
if (reference) {
reference.parentNode.insertBefore(linkTag, reference);
}
},
});æ¾å° id 为 some-element çå
ç´ ï¼å¨å®ä¹åæå
¥æ°ç <link> å
ç´ ã
attributesç±»åï¼Object
é»è®¤å¼ï¼{}
â ï¸ ä» å¯¹ éåå§ï¼ç± async ä¿®é¥°ï¼ chunk ææã
妿å®ä¹äºæ¤é项ï¼mini-css-extract-plugin å°ææå®ç屿§åå¼éå å° <link> å
ç´ ä¸ã
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
attributes: {
id: "target",
"data-target": "example",
},
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};注æï¼å®åªéç¨äºå¨æå è½½ç css chunkï¼å¦æä½ æ³ä¿®æ¹ html æä»¶å ç龿¥å±æ§ï¼è¯·ä½¿ç¨ html-webpack-pluginã
linkTypeç±»åï¼String|Boolean
é»è®¤å¼ï¼text/css
æ¤é项è¿è¡ä½¿ç¨èªå®ä¹é¾æ¥ç±»åå è½½å¼æ¥ chunkï¼ä¾å¦ <link type="text/css" ...>ã
Stringå¯éå¼ï¼text/css
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
linkType: "text/css",
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};Booleanfalse ç¦ç¨ link ç type 屿§
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
linkType: false,
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};runtimeType: Boolean
Default: true
å 许å¼å¯/ç¦ç¨ runtime çæã CSS ä»å°è¢«æåï¼å¹¶å¯ç¨äºèªå®ä¹å è½½æ¹æ³ã ä¾å¦ï¼ä½ å¯ä»¥ä½¿ç¨ assets-webpack-plugin æ¥æ£ç´¢å®ä»¬ï¼ç¶åå½éè¦æ¶ä½¿ç¨ä½ èªå·±ç runtime 代ç ä¸è½½éæèµæºã
设置为 true 以跳è¿ã
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
runtime: false,
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};experimentalUseImportModuleç±»åï¼Boolean
é»è®¤å¼ï¼undefined
å¦ææ²¡ææ¾å¼å¯ç¨ï¼åé»è®¤å¯ç¨ï¼å³å¯ä»¥éè¿ true ä¸ false æ¾å¼æ§å¶è¯¥é
ç½®ï¼ï¼å¹¶ä¸æ° API å¤äºå¯ç¨ç¶æï¼webpack çæ¬è³å°ä¸º 5.52.0ï¼ã
å¸å°å¼å¨ 5.33.2 çæ¬åå¯ç¨ï¼ä½æ¯ä½ éè¦å¯ç¨ experiments.executeModuleï¼webpack 5.52.0 çæ¬ä¸éè¦ï¼ã
ä½¿ç¨æ°ç webpack API æ¥æ§è¡æ¨¡åè䏿¯åç¼è¯å¨ã è¿å¤§å¤§æé«äºæ§è½åå å使ç¨ã
å½ä¸ experiments.layers ç¸ç»åæ¶ï¼æ·»å äºä¸ä¸ª layer éé¡¹å° loader é
置项ä¸ï¼ä»¥æå® CSS æ§è¡ç layerã
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// `>= 5.52.0` çæ¬ç webpack ä¸éè¦è¯¥é
ç½®ï¼å 为该é
置项é»è®¤å¯ç¨
// ä»
`>= 5.33.2 & <= 5.52.0` çæ¬ç webpack éè¦è¯¥é
ç½®
// å¯¹äº `<= 5.33.2` çæ¬ç webpack ä¸å¯ç¨/ä¸å®å
¨
experimentalUseImportModule: true,
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};| åç§° | ç±»å | é»è®¤å¼ | æè¿° |
|---|---|---|---|
publicPath | {String|Function} | webpackOptions.output.publicPath | 为å¾çãæä»¶çå¤é¨èµæºæå®ä¸ä¸ªèªå®ä¹çå ¬å ±è·¯å¾ã |
emit | {Boolean} | true | å¦æè®¾ä¸º falseï¼æä»¶å°ä¼æå CSS ä½ä¸ä¼ çææä»¶ |
esModule | {Boolean} | true | ä½¿ç¨ ES modules è¯æ³ |
publicPathç±»åï¼String|Function
é»è®¤å¼ï¼webpackOptions.output é项ä¸ç publicPath
为 CSS å
çå¾çãæä»¶çå¤é¨èµæºæå®ä¸ä¸ªèªå®ä¹çå
Œ
±è·¯å¾ã
æºå¶ç±»ä¼¼äº output.publicPathã
Stringwebpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// ç±»ä¼¼äº webpackOptions.output ä¸çé项
// ææé项齿¯å¯éç
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: "/public/path/to/",
},
},
"css-loader",
],
},
],
},
};Functionwebpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// ç±»ä¼¼äº webpackOptions.output ä¸çé项
// ææé项齿¯å¯éç
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: (resourcePath, context) => {
return path.relative(path.dirname(resourcePath), context) + "/";
},
},
},
"css-loader",
],
},
],
},
};emitç±»åï¼Boolean
é»è®¤å¼ï¼true
å¦æè®¾ç½®ä¸º trueï¼ä¼åéä¸ä¸ªæä»¶ï¼åæä»¶ç³»ç»ä¸åå ¥ä¸ä¸ªæä»¶ï¼ãå¦æè®¾ç½®ä¸º falseï¼è¯¥æä»¶å°ä¼æå CSS 使¯ ä¸ä¼ åéæä»¶ã ç¦ç¨è¯¥é 置对æå¡ä¾§çå æ¯è¾æç¨ã
esModuleç±»åï¼Boolean
é»è®¤å¼ï¼true
é»è®¤æ
åµä¸ mini-css-extract-plugin å°ä¼çæä½¿ç¨ ES 模åè¯æ³ç JS 模åã
å¨æäºæ
åµä¸ï¼ä½¿ç¨ ES æ¨¡åæ¯æççï¼æ¯å¦ï¼module concatenation å tree shakingã
ä½ å¯ä»¥ä½¿ç¨ä»¥ä¸æ¹å¼å¯ç¨ CommonJS è¯æ³ï¼
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/i,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
esModule: false,
},
},
"css-loader",
],
},
],
},
};æ¨è production ç¯å¢çæå»ºå° CSS ä»ä½ ç bundle ä¸åç¦»åºæ¥ï¼è¿æ ·å¯ä»¥ä½¿ç¨ CSS/JS æä»¶çå¹¶è¡å è½½ã
è¿å¯ä»¥éè¿ä½¿ç¨ mini-css-extract-plugin æ¥å®ç°ï¼å 为å®å¯ä»¥å建åç¬ç CSS æä»¶ã
å¯¹äº development 模å¼ï¼å
æ¬ webpack-dev-serverï¼ï¼ä½ å¯ä»¥ä½¿ç¨ style-loaderï¼å 为å®å¯ä»¥ä½¿ç¨å¤ä¸ª æ ç¾å° CSS æå
¥å° DOM ä¸ï¼å¹¶ä¸ååºä¼æ´å¿«ã
i ä¸è¦åæ¶ä½¿ç¨
style-loaderä¸mini-css-extract-pluginã
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== "production";
module.exports = {
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
devMode ? "style-loader" : MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"sass-loader",
],
},
],
},
plugins: [].concat(devMode ? [] : [new MiniCssExtractPlugin()]),
};webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// all options are optional
filename: "[name].css",
chunkFilename: "[id].css",
ignoreOrder: false, // Enable to remove warnings about conflicting order
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it uses publicPath in webpackOptions.output
publicPath: "../",
},
},
"css-loader",
],
},
],
},
};â å½åä¼è¢«ä¿®æ¹ä¸º
camelCaseçå½¢å¼ã
â ä¸å è®¸å¨ css ç class name ä¸ä½¿ç¨ JavaScript å ³é®åã
â åºå¯ç¨
css-loaderä¸çesModule以åmodules.namedExporté项ã
styles.css
.foo-baz {
color: red;
}
.bar {
color: blue;
}index.js
import { fooBaz, bar } from "./styles.css";
console.log(fooBaz, bar);ä½ å¯ä»¥æç §å¦ä¸é ç½®å¯ç¨ ES 模åå½å导åºï¼
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: "css-loader",
options: {
esModule: true,
modules: {
namedExport: true,
localIdentName: "foo__[name]__[local]",
},
},
},
],
},
],
},
};publicPath éé¡¹ä¸ºå½æ°webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// ç±»ä¼¼äº webpackOptions.output ä¸çé项
// ææé项齿¯å¯éç
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: (resourcePath, context) => {
// publicPath æ¯èµæºç¸å¯¹äºä¸ä¸æçç¸å¯¹è·¯å¾
// ä¾å¦ï¼å¯¹äº ./css/admin/main.css publicPath å°ä¼æ¯ ../../
// èå¯¹äº ./css/main.css publicPath å°ä¼æ¯ ../
return path.relative(path.dirname(resourcePath), context) + '/';
},
},
},
"css-loader",
],
},
],
},
};æ¤æä»¶ä¸è½ä¸ loader é¾ä¸ç style-loader ä¸å使ç¨ã
è¿æ¯ä¸ä¸ªå¨ development æå»ºä¸ä½¿ç¨ HMR å¹¶ä¸å¨ production æå»ºä¸å°æ ·å¼æä»¶æåå°ç¬ç«æä»¶ä¸ç示ä¾ã
ï¼ä¸ºäºæ´å æ¸ æ¥ç表达ï¼çç¥äº Loader çé项ï¼ä»¥éåºéè¦ãï¼
å¦æä½ ä½¿ç¨çæ¯ webpack-dev-serverï¼é£ä¹å°±æ éä½¿ç¨ HotModuleReplacementPlugin pluginã
webpack-dev-server ä½¿ç¨ hot é项å³å®æ¯å¦å¯ç¨/ç¦ç¨ HMRã
webpack.config.js
const webpack = require("webpack");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== "production";
const plugins = [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: devMode ? "[name].css" : "[name].[contenthash].css",
chunkFilename: devMode ? "[id].css" : "[id].[contenthash].css",
}),
];
if (devMode) {
// only enable hot in development
plugins.push(new webpack.HotModuleReplacementPlugin());
}
module.exports = {
plugins,
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"sass-loader",
],
},
],
},
};注æï¼å¨ webpack 5 ä¸ HMR å·²èªå¨æ¯æãæ éé ç½®ãä½ å¯ä»¥è·³è¿ä»¥ä¸å 容ï¼
mini-css-extract-plugin æ¯æå¨å¼åä¸çéè½½å®é
ç CSS æä»¶ã
æä»¬æä¾äºä¸äºé项æ¥å¯å¨æ å stylesheets 忬å°èå´å
CSS å CSS modules ç HMR æ¯æã
以䏿¯ mini-css ç¨äºå¯å¨ HMR CSS modules ç示ä¾é
ç½®ã
å¦æä½ ä½¿ç¨çæ¯ webpack-dev-serverï¼é£ä¹ä½ æ éä½¿ç¨ HotModuleReplacementPlugin æä»¶ã
webpack-dev-server ä½¿ç¨ hot éé¡¹æ¥æ§å¶å¯ç¨/ç¦ç¨ HMRã
webpack.config.js
const webpack = require("webpack");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const plugins = [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: devMode ? "[name].css" : "[name].[contenthash].css",
chunkFilename: devMode ? "[id].css" : "[id].[contenthash].css",
}),
];
if (devMode) {
// only enable hot in development
plugins.push(new webpack.HotModuleReplacementPlugin());
}
module.exports = {
plugins,
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {},
},
"css-loader",
],
},
],
},
};为äºå缩è¾åºæä»¶ï¼è¯·ä½¿ç¨ç±»ä¼¼äº css-minimizer-webpack-plugin è¿æ ·çæä»¶ã
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
optimization: {
minimizer: [
// For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
// `...`,
new CssMinimizerPlugin(),
],
},
};è¿å°åªå¨ç产模å¼ä¸å¯ç¨ CSS å缩ä¼åãå¦æä½ éè¦å¨å¼å模å¼ä¸ä½¿ç¨ï¼è¯·è®¾ç½® optimization.minimize é项为 trueã
è¿è¡æ¶ä»£ç éè¿ <link> æè
<style> æ ç¾æ£æµå·²ç»æ·»å ç CSSã
å½å¨æå¡ç«¯æ³¨å
¥ CSS 代ç 以åå SSR æ¶å°ä¼å¾æç¨ã
<link> æ ç¾ç href 屿§å¿
é¡»ä¸å°è¦è¢«å è½½ç CSS chunk ç URL ç¸å¹é
ã
data-href 屿§ä¹å¯ä»¥è¢«ç¨å¨ <link> å <style> æ ç¾ä¸
使ç¨å
è CSS æ¶ï¼å¿
é¡»ä½¿ç¨ data-href 屿§ã
ç¨è¿ä½¿ç¨ optimization.splitChunks.cacheGroups éé¡¹ï¼ææç CSS å¯ä»¥è¢«æåå°ä¸ä¸ª CSS æä»¶ä¸ã
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: "styles",
type: "css/mini-extract",
chunks: "all",
enforce: true,
},
},
},
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};请注æå¨ webpack 5 ä¸åºè¯¥ä½¿ç¨ type è䏿¯ testï¼å¦åå°ä¼çæ .js æä»¶è䏿¯ .cssãè¿æ¯å 为 test ä¸ç¥éåºè¯¥å»æåªä¸ªæ¨¡åï¼å¨è¿ç§æ
åµä¸ï¼å®ä¸ä¼æ£æµå° .js åºè¯¥è¢«å é¤ï¼ã
ä½ å¯ä»¥åºäº webpack çå ¥å£åç§°æå CSSã å½ä½ 使ç¨è·¯ç±å¨æå è½½ä½æ¯æ³è¦éè¿å ¥å£å 载对åºç CSS æä»¶æ¶è¿å°ä¼é常æç¨ã è¿æ ·ä¹é¿å äº ExtractTextPlugin é æç CSS éå¤å¤å¶é®é¢ã
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: {
foo: path.resolve(__dirname, "src/foo"),
bar: path.resolve(__dirname, "src/bar"),
},
optimization: {
splitChunks: {
cacheGroups: {
fooStyles: {
type: "css/mini-extract",
name: "styles_foo",
chunks: (chunk) => {
return chunk.name === "foo";
},
enforce: true,
},
barStyles: {
type: "css/mini-extract",
name: "styles_bar",
chunks: (chunk) => {
return chunk.name === "bar";
},
enforce: true,
},
},
},
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};ä½¿ç¨ filename é项ï¼ä½ å¯ä»¥ä½¿ç¨ chunk æ°æ®æ¥å®å¶æä»¶åã
è¿ç¹å¨å¤çå¤ä¸ªå
¥å£ï¼å¹¶ä¸å¸æå¯¹ç»å®ç å
¥å£/chunk æä»¶è¿è¡æ´å¤å¤çæ¶ï¼é常æç¨ã
ä¸é¢ç¤ºä¾ä¸ï¼æä»¬ä½¿ç¨ filename å°çæç css è¾åºå°ä¸åçç®å½ä¸ã
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: ({ chunk }) => `${chunk.name.replace("/js/", "/css/")}.css`,
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};ä½¿ç¨ filename: "[contenthash].css" å¯å¨é¿æç¼åãæ ¹æ®éè¦æ·»å [name]ã
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css",
chunkFilename: "[id].[contenthash].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};对äºéè¿ä½¿ç¨ scoping æå½åçº¦å®æ¥è§£å³ css order ç项ç®ï¼å¯ä»¥éè¿å°æä»¶ç ignoreOrder é项设置为 true æ¥ç¦ç¨ css order è¦åã
webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
ignoreOrder: true,
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
};webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: "./src/index.js",
module: {
rules: [
{
test: /\.s[ac]ss$/i,
oneOf: [
{
resourceQuery: "?dark",
use: [
Self.loader,
"css-loader",
{
loader: "sass-loader",
options: {
additionalData: `@use 'dark-theme/vars' as vars;`,
},
},
],
},
{
use: [
Self.loader,
"css-loader",
{
loader: "sass-loader",
options: {
additionalData: `@use 'light-theme/vars' as vars;`,
},
},
],
},
],
},
],
},
plugins: [
new Self({
filename: "[name].css",
attributes: {
id: "theme",
},
}),
],
};src/index.js
import "./style.scss";
let theme = "light";
const themes = {};
themes[theme] = document.querySelector("#theme");
async function loadTheme(newTheme) {
// eslint-disable-next-line no-console
console.log(`CHANGE THEME - ${newTheme}`);
const themeElement = document.querySelector("#theme");
if (themeElement) {
themeElement.remove();
}
if (themes[newTheme]) {
// eslint-disable-next-line no-console
console.log(`THEME ALREADY LOADED - ${newTheme}`);
document.head.appendChild(themes[newTheme]);
return;
}
if (newTheme === "dark") {
// eslint-disable-next-line no-console
console.log(`LOADING THEME - ${newTheme}`);
import(/* webpackChunkName: "dark" */ "./style.scss?dark").then(() => {
themes[newTheme] = document.querySelector("#theme");
// eslint-disable-next-line no-console
console.log(`LOADED - ${newTheme}`);
});
}
}
document.onclick = () => {
if (theme === "light") {
theme = "dark";
} else {
theme = "light";
}
loadTheme(theme);
};src/dark-theme/_vars.scss
$background: black;src/light-theme/_vars.scss
$background: white;src/styles.scss
body {
background-color: vars.$background;
}public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Document</title>
<link id="theme" rel="stylesheet" type="text/css" href="./main.css" />
</head>
<body>
<script src="./main.js"></script>
</body>
</html>å¦ææ¨æ³ä» CSS æä»¶ä¸æååªä½æ¥è¯¢ï¼å 为移å¨ç¨æ·ä¸éè¦å è½½çµèæå¹³æ¿ä¸ç¨ç CSS ï¼ï¼åºä½¿ç¨ä»¥ä¸æä»¶ä¹ä¸ï¼
å¦æä½ è¿æ²¡æé è¯»è¿æä»¬çè´¡ç®æåï¼è¯·è±ä¸ç¹æ¶é´é 读å®ã