编辑:在原始答案中,我描述的是style-loader 而不是css-loader。很容易忘记这些加载程序的不同用途,因为css-loader 只能与style-loader 一起使用。
新答案
css-loader 让您可以更好地控制导入.css 文件。
1.转换url(image.png) => require('./image.png')
由于现在使用require,因此您可以使用例如file-loader 或url-loader。
现在url(image.png)可以转换为:
url(/public-path/0dcbbaa701328a3c262cfd45869e351f.png)
或者用url-loader的limit属性创建内联图片:
url(data:image/jpeg;base64,LzlqLzRBQ ... zdF3)
2。启用CSS Modules
让我们考虑componentA 和componentB 的样式:
componentA/style.css
.wrapper {
background-color: blue;
}
.specificToComponentA {
// rest of styles
}
componentB/style.css
.wrapper {
background-color: red;
}
.specificToComponentB {
// rest of styles
}
componentA 看起来:
import './style.css';
export default function () {
document.body.innerHTML = `
<div class="wrapper">
<div class="specificToComponentA">componentA</div>
</div>
`;
}
和componentB 看起来:
import './style.css';
export default function () {
document.body.innerHTML = `
<div class="wrapper">
<div class="specificToComponentB">componentB</div>
</div>
`;
}
这些组件的背景颜色是什么颜色?这个问题与样式泄漏有关,很难判断它们是红色还是蓝色(很难预测style-loader 创建的样式顺序)。如果你使用 CSS Modules 方法,你可以处理这个问题。
现在将样式导入变量,该变量将包含具有映射类名称的对象:
componentA 带有 CSS 模块的外观:
import s from './style.css';
export default function () {
document.body.innerHTML = `
<div class="${s.wrapper}">
<div class="${s.specificToComponentA}">componentA</div>
</div>
`;
}
s 对象将包含:
{
wrapper: "WO0HHIhH77",
specificToComponentA: "jPYPsVTDZu"
}
componentA/style.css 将被转换为
.WO0HHIhH77 {
background-color: blue;
}
.jPYPsVTDZu {
// rest of styles
}
和 componentB 与 CSS 模块看起来:
import s from './style.css';
export default function () {
document.body.innerHTML = `
<div class="${s.wrapper}">
<div class="${s.specificToComponentB}">componentB</div>
</div>
`;
}
s 对象将包含:
{
wrapper: "C8EKTwiZfd", // Look, different than in componentA!!!
specificToComponentB: "KI5jRsC2R5"
}
componentB/style.css 将被转换为
.C8EKTwiZfd { // Look, different than in componentA!!!
background-color: red;
}
.KI5jRsC2R5 {
// rest of styles
}
现在,即使您不在两个组件中使用像 wrapper 这样的超级特定名称,您也可以确定它们不会重叠,componentA 保持蓝色,componentB 保持红色。它是封装样式的强大功能,描述为 CSS 模块 - 在 css-loader 的帮助下可以实现。
旧答案
css-loader style-loader 改变 js 和 css
让我们考虑一下这个项目结构
├── components
│ │
│ ├── componentA
│ │ ├── style.css
│ │ └── index.js
│ │
│ ├── componentB
│ │ ├── style.css
│ │ └── index.js
│ │
│ └── componentC
│ ├── style.css
│ └── index.js
│
├── index.js
└── index.html
index.js 看起来像这样
import componentA from './components/componentA';
import componentB from './components/componentB';
import componentC from './components/componentC';
componentA();
componentB();
componentC();
1.没有 css-loader 样式加载器
每个*.js 组件通常看起来像这样
export default function () {
// logic of this component
}
index.html 包含
<link href="components/componentA/style.css" rel="stylesheet" type="text/css">
<link href="components/componentB/style.css" rel="stylesheet" type="text/css">
<link href="components/componentC/style.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="dist/bundle.js"></script>
现在,如果您想重构您的代码,例如禁用 componentB,您必须将其从 index.js 中删除
import componentA from './components/componentA';
// import componentB from './components/componentB';
import componentC from './components/componentC';
componentA();
// componentB();
componentC();
而且由于 css 和 js 是解耦的,你必须对 index.html 中的样式做同样的事情
<link href="components/componentA/style.css" rel="stylesheet" type="text/css">
<!-- <link href="components/componentB/style.css" rel="stylesheet" type="text/css"> -->
<link href="components/componentC/style.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="dist/bundle.js"></script>
大型项目中的这种重复可能会导致留下无效的 css 代码 - 因为您必须在不同的地方做两件事,所以更难维护。
注意: SASS 或 LESS 有同样的问题。它只是从index.html 移动到index.sass:
@import './components/componentA';
@import './components/componentB'; // you must disable this manually
@import './components/componentC';
2。使用 css-loader 样式加载器
现在您直接从它指向与某些组件相关的样式(而不是像 1. 点那样在单独的位置)
例如,您的 *.js 组件看起来像
import './style.css';
export default function () {
// logic of this component
}
和index.html
<script type="text/javascript" src="dist/bundle.js"></script>
最重要的是,如果你有这个架构,想禁用componentB,只有你做的就是
import componentA from './components/componentA';
// import componentB from './components/componentB';
import componentC from './components/componentC';
componentA();
// componentB();
componentC();
就是这样!无需再在任何.html 或.sass 或.less 中寻找样式componentB/style.css 的参考。如果你想添加新组件也是如此:只需导入 .js 文件,你就可以添加 js 逻辑和 css 样式。这更容易维护!