乐趣区

webpack-处理-CSS-资源

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 内容。

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 选项

TODO…

退出移动版