1. 一个引入 CSS 资源的案例
// index.js
import './style.css'
/* style.css */
#root {
height: 100px;
width: 100px;
border: 1px solid #ccc;
}
就这样打包的话,是会报错的,那么想要成功打包 CSS 资源,需要使用下面介绍的几个 loader。
2. style-loader
将 CSS 样式注入到 DOM 中。
2.1 结合 css-loader 使用
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
}
打包后,dist 目录下生成一个 main.js,文件内容中包含了我们所写的 CSS 代码,打开浏览器查看,在 <head>
标签内插入了一个 <style>
标签,并且页面样式也是生效的:
2.2 结合 file-loader 使用
配置 injectType 选项(用来确定以何种形式将标签插入到 DOM 中)为 linkTag。
rules: [
{
test: /\.css$/,
use: [
{ loader: 'style-loader', options: { injectType: 'linkTag' } },
{ loader: 'file-loader' }
]
}
]
打包后,dist 目录下生成一个 main.js 和一个 css 文件,css 文件正是我们所写的 CSS 代码,打开浏览器查看,在 <head>
标签内插入了一个 <link>
标签,并且页面样式也是生效的:
除了可以设置 injectType 选项,该 loader 还可以设置包括 attributes(在插入的标签中设置自定义属性)、insert(将标签插入到指定的 DOM 位置)和 base 选项。
更多详情查阅 style-loader。
3. css-loader
// index.js
import style from './index.css'
console.log(style)
console.log(style.toString())
/* index.css */
@import url('./m1.css');
@import url('./m2.css');
#root {
width: 100px;
height: 100px;
border: 1px solid #ccc;
}
/* m1.css */
.foo {
color: red;
}
/* m2.css */
.bar {
color: blue;
}
打包后,打开浏览器控制台,可以看到输出的内容是这样的:
CSS 文件之间通过了 @import 语法建立了引入的关系,而 css-loader 则可以解析这种关系,然后把多个的 css 文件关联在一起,并将 css 转换为 CommonJS 模块。
3.1 modules 选项
配置该选项可以启用 CSS 模块化。
下面介绍在 vue 项目中使用 CSS 模块化。先使用 vue-cli3 新建一个项目,然后改造如下:
<!-- App.vue -->
<template>
<div id="app">
<div class="foo">foo</div>
<div class="bar">bar</div>
<HelloWorld />
<HelloCSSModules />
</div>
</template>
<!-- 中间部分代码忽略 -->
<style>
#app {
height: 200px;
width: 200px;
border: 1px solid #ccc;
}
</style>
HelloScoped 组件使用 scoped 作用域书写样式:
<!-- HelloScoped.vue -->
<template>
<div>
<div class="foo">hello foo</div>
<div class="bar">hello bar</div>
</div>
</template>
<!-- 中间部分代码忽略 -->
<style scoped>
.foo {
color: red;
}
.bar {
color: blue;
}
</style>
HelloCssModules 组件通过 :class="$style.foo"
语法绑定类名,并且在 <style>
标签设置 module 属性:
<!-- HelloCssModules.vue -->
<template>
<div>
<div :class="$style.foo">css modules foo</div>
<div :class="$style.bar">css modules bar</div>
</div>
</template>
<!-- 中间部分代码忽略 -->
<style module>
.foo {
color: green;
}
.bar {
color: orange;
}
</style>
运行项目,打开浏览器进行对比,使用 scoped 语法会在 DOM 元素上设置唯一的自定义属性,然后通过 .foo[data-v-469af010]
语法来绑定样式;而使用 module 语法则直接将 class 类名替换成动态生成的唯一类名。
3.2 importLoaders 选项
// webpack.config.js
rules: [
{
test: '/\.css$/',
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoader: 0
}
},
'postcss-loader'
]
}
]
// index.js
import style from 'index.css';
/* index.css */
@import 'm1.css';
#root {
width: 100px;
height: 100px;
border: 1px solid #ccc;
transform: translate(100px, 100px);
}
/* m1.css */
.foo {
transform: translate(10px, 10px);
}
在上述的文件中,我们在 index.js 引入了 index.css,index.css 中又通过 @import
语法引入了 m1.css,并且在 webpack.config.js 的配置中使用了 style-loader、css-loader 和 postcss-loader 来处理 css 文件,注意 css-loader 的 importLoader 设置为默认值 0。
运行项目,打开浏览器可以看到,#root
元素的 transform
样式属性加上了不同浏览器厂商的前缀,但是 .foo
元素的样式并没有加上前缀:
此时,就可以通过将 css-loader 的 importLoader 设置为 1 来解决这个问题:
// webpack.config.js
{
loader: 'css-loader',
options: {
importLoader: 1
}
}
重新打包,打开浏览器查看,发现 .foo
元素的 transform
样式属性也加上了各个浏览器厂商的前缀:
总的来说,importLoader 作用于通过 @import
语法引入的 css 文件(比如 m1.css),假设 webpack.config.js 的内容是这样的:
rules: [
{
test: '/\.css$/',
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoader: 2
}
},
'postcss-loader',
'xxx-loader'
]
}
]
importLoader 的值为 2 时,那么 m1.css 在被 css-loader 处理之前会经过 xxx-loader 和 postcss-loader,当值为 1 时,则被 css-loader 处理之前只会经过 postcss-loader,当值为 0 时,则被 css-loader 处理之前不会经过其他 loader。
更多详情查阅 css-loader。
4 sass-loader
sass-loader 可以加载 sass/scss 文件并将其编译成 css 文件。
要使用 sass-loader,需要连同 node-sass 一起安装:
npm install sass-loader node-sass --save-dev
基本的使用方式:
// src/index.js
import './index.scss'
/* index.css */
$borderColor: red;
#root {
width: 100px;
height: 100px;
border: 1px solid $borderColor;
}
// webpack.config.js
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
}
]
执行打包指令,打开页面,可以看到,sass 语法 $borderColor: red;
生效了:
4.1 导入
使用 ~
,可以导入 node_modules 目录里面的 sass 模块。
安装 bootstrap npm install bootstrap --save
。
将文件更新至下面这样:
<!-- index.html -->
<div id="root" class="btn btn-default">root</div>
/* index.css */
@import '~bootstrap/scss/bootstrap';
打包后打开浏览器,可以看到在 btn 类名下多了 bootstrap 的样式:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。