[英]What is the purpose of css-loader in webpack
我开始使用Webpack 2,我看到很多项目正在使用css-loader,但我没有找到它的目的。
EDIT: In original answer I was describing style-loader
not css-loader
. 编辑:在原始答案中,我描述的是
style-loader
而不是css-loader
。 It's easy to forget different purpose of those loader since css-loader
can only be used with style-loader
. 由于
css-loader
只能与style-loader
一起使用,因此很容易忘记这些加载器的不同用途。
css-loader
gives you more control over importing .css
files. css-loader
使您可以更好地控制导入.css
文件。
1. Transforms url(image.png) => require('./image.png')
1.转换
url(image.png) => require('./image.png')
Since now require
is used, it's enables you to use for example file-loader
or url-loader
. 由于现在使用了
require
,因此可以使用例如file-loader
或url-loader
。 Now url(image.png)
can be converted to: 现在
url(image.png)
可以转换为:
url(/public-path/0dcbbaa701328a3c262cfd45869e351f.png)
or with limit property of url-loader
creates inline picture: 或者使用
url-loader
limit属性创建内联图片:
url(data:image/jpeg;base64,LzlqLzRBQ ... zdF3)
2. Enables CSS Modules 2.启用CSS模块
Let's consider styles of componentA
and componentB
: 让我们考虑
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
looks: componentA
看起来:
import './style.css';
export default function () {
document.body.innerHTML = `
<div class="wrapper">
<div class="specificToComponentA">componentA</div>
</div>
`;
}
and componentB
looks: 和
componentB
看起来:
import './style.css';
export default function () {
document.body.innerHTML = `
<div class="wrapper">
<div class="specificToComponentB">componentB</div>
</div>
`;
}
What color of background color those components would have? 这些组件的背景颜色是什么颜色的? This problem is related with leaking of styles, it's hard to tell if they are will be red or blue (it's hard to predict order of styles created by
style-loader
). 这个问题与样式泄漏有关,很难判断它们是红色还是蓝色(很难预测样式
style-loader
创建的style-loader
顺序)。 If you use CSS Modules approach you can deal with this problem. 如果您使用CSS模块方法,您可以处理此问题。 Now import styles to variable and this variable will contain object with mapping class names:
现在将样式导入变量,此变量将包含具有映射类名称的对象:
componentA
with CSS Modules looks: 带有CSS模块的
componentA
看起来:
import s from './style.css';
export default function () {
document.body.innerHTML = `
<div class="${s.wrapper}">
<div class="${s.specificToComponentA}">componentA</div>
</div>
`;
}
s
object will contain : s
对象将包含:
{
wrapper: "WO0HHIhH77",
specificToComponentA: "jPYPsVTDZu"
}
componentA/style.css
will be converted to componentA/style.css
将被转换为
.WO0HHIhH77 {
background-color: blue;
}
.jPYPsVTDZu {
// rest of styles
}
and componentB
with CSS Modules looks: 和使用CSS模块的
componentB
看起来:
import s from './style.css';
export default function () {
document.body.innerHTML = `
<div class="${s.wrapper}">
<div class="${s.specificToComponentB}">componentB</div>
</div>
`;
}
s
object will contain : s
对象将包含:
{
wrapper: "C8EKTwiZfd", // Look, different than in componentA!!!
specificToComponentB: "KI5jRsC2R5"
}
componentB/style.css
will be converted to componentB/style.css
将被转换为
.C8EKTwiZfd { // Look, different than in componentA!!!
background-color: red;
}
.KI5jRsC2R5 {
// rest of styles
}
And now even if you don't use super specific name like wrapper
in both components you are sure that they don't overlap and componentA
stays blue and componentB
red. 现在,即使你不在两个组件中使用超级特定名称(如
wrapper
,也可以确保它们不重叠, componentA
保持蓝色, componentB
保持红色。 It's great power of encapsulation of styles described as CSS Modules - it is possible with help of css-loader
. 它是封装描述为CSS模块的样式的强大功能 - 在
css-loader
帮助下可以实现。
Let's consider this structure of project 让我们考虑一下这个项目结构
├── components
│ │
│ ├── componentA
│ │ ├── style.css
│ │ └── index.js
│ │
│ ├── componentB
│ │ ├── style.css
│ │ └── index.js
│ │
│ └── componentC
│ ├── style.css
│ └── index.js
│
├── index.js
└── index.html
index.js
looks like this index.js
看起来像这样
import componentA from './components/componentA';
import componentB from './components/componentB';
import componentC from './components/componentC';
componentA();
componentB();
componentC();
1. Without css-loader style-loader 1.没有
css-loader样式加载器
each of *.js
components in general looks like this 每个
*.js
组件通常都是这样的
export default function () {
// logic of this component
}
index.html
contains 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>
Now if you want to refactor your code and for example disable componentB
you must remove it from index.js
现在,如果要重构代码,例如禁用
componentB
,则必须将其从index.js
删除
import componentA from './components/componentA';
// import componentB from './components/componentB';
import componentC from './components/componentC';
componentA();
// componentB();
componentC();
and since css and js are decoupled you must do the same for styles in index.html
并且因为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>
This duplication in large project can lead to leaving dead css code - it's harder to maintain since you must do two things in separate places. 大型项目中的这种重复可能会导致死css代码 - 因为你必须在不同的地方做两件事,所以它很难维护。
NOTE: SASS or LESS have the same problem. 注意: SASS或LESS有同样的问题。 It's only moved from
index.html
to index.sass
: 它只从
index.html
移到index.sass
:
@import './components/componentA';
@import './components/componentB'; // you must disable this manually
@import './components/componentC';
2. With css-loader style-loader 2.使用
css-loader样式加载器
Now you point to styles related to some component directly from it (not in separate place like in 1. point) For example your *.js
component will look like 现在你直接从它指向与某个组件相关的样式(不是在1. point中的单独位置)例如你的
*.js
组件看起来像
import './style.css';
export default function () {
// logic of this component
}
and index.html
和
index.html
<script type="text/javascript" src="dist/bundle.js"></script>
The most important is that if you have this architecture and want to disable componentB
, only what you do is 最重要的是,如果你有这个架构并想要禁用
componentB
,那么你所做的只是
import componentA from './components/componentA';
// import componentB from './components/componentB';
import componentC from './components/componentC';
componentA();
// componentB();
componentC();
It's all! 这就是全部! No more looking for reference of styles
componentB/style.css
in any .html
or .sass
or .less
. 不再需要在任何
.html
或.sass
或.less
查找样式componentB/style.css
引用。 The same goes if you want to add new components: by simply importing .js
file you add js logic and css styles. 如果要添加新组件,也是如此:只需导入
.js
文件即可添加js逻辑和css样式。 This is much easier to maintain! 这更容易维护!
In .js
file ES6 import
or CommonJS 's require()
allows you to import only JavaScript files(modules) into it. 在
.js
文件中, ES6 import
或CommonJS的require()
允许您只将JavaScript文件(模块)导入其中。 So when you include your styles.css
, for instance, in .js
file via import from './styles.css'
, you'll need to convert in into .js
in the first place. 因此,当您通过
import from './styles.css'
包含styles.css
,例如,在.js
文件中时,您需要首先转换为.js
。 And here is where css-loader comes to the rescue. 这里是css-loader来救援的地方。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.