从0基础到大牛-webpack深入浅出超强完整版(三)

你可能只需要这一个教程

webpack - 万物皆可打包

  • 打包CSS

  通过import或require引入样式文件,webpack无法直接打包,需引入css-loader将其转化
  下载依赖css-loader与style-loadernpm install --save-dev css-loader style-loader,并新增配置如下

1
2
3
4
5
6
7
8
9
10
11
12

module.exports = {
module:{
rules: [
{
test: /\.css$/,
loader: ['style-loader','css-loader'],
exclude: /node_modules/
}
]
}
};

  loader的执行顺序是从后向前,即先执行css-loader,转化后交给style-loader,将其挂载到html文件内
  css-loader负责转化css,而style-loader将转化后的css,包裹在style标签内,并将其插入到html文件的header中
  此处应注意包引入的顺序与被置入的内联样式顺序有关,重复并不会转化多次
  style-loader是以文件为单位,将其包裹为一个内部样式
  css实际打包进了js文件,并未分离出来,后面将讲解css的分离配置

  • 打包CSS预编译语言(scss/less/stylus)

  css预编译语言同样无法直接编译,需要使用相应的loader,我们以sass为例
  下载sass-loader,这里我们跟着官方文档第一个来配置
  有时官方文档也会出现更新不及时的问题,另sass-loader依赖node-sass,它在底层是用C语言编写,可能会在服务器端出现依赖包问题
  下载依赖npm install sass-loader node-sass webpack --save-dev,并配置如下

1
2
3
4
5
6
7
8
9
10
11
12

module.exports = {
module:{
rules: [
{
test: /\.s[ac]ss$/i,
loader: ['style-loader','css-loader','scss-loader'],
exclude: /node_modules/
}
]
}
};

  与css相比,我们需要先使用scss-loader将sass语言转为css语言

  • 添加CSS3前缀

  浏览器一日不统一,我们就需要一日跟兼容性抗争到底。每次写样式我们都要加一堆的兼容前缀么?自动添加兼容代码,摆脱兼容烦恼
  下载依赖npm install --save--dev postcss-loader autoprefixer
  需要在css的loader中修改,我们以sass加配置

1
2
3
4
5
6
7
8
9
10
11
module.exports = {
module:{
rules: [
{
test: /\.s[ac]ss$/i,
loader: ['style-loader','css-loader','sass-loader','postcss-loader'],
exclude: /node_modules/
}
]
}
};

  同时我们需要在根目录下新建postcss的配置文件postcss.config.js,配置如下

1
2
3
modules.exports = {
plugins: [ require("autoprefixer") ]
};

  此处也可以直接配置在webpack中,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = {
module:{
rules: [
{
test: /\.s[ac]ss$/i,
loader: ['style-loader','css-loader','sass-loader',{
loader: 'postcss-loader',
options:{
plugins: [require('autoprefixer')]
}
}],
exclude: /node_modules/
}
]
}
};

  post-loader会自动加载postcss.config.js下的配置,将文件内配置的插件加载进去
  这时再打包出来的css,将会自动为我们加入兼容前缀

  • css模块化打包

  当前引入与打包生成的css样式,是全局样式,如何做到样式隔离呢
  像vue样式的scoped,如何样式隔离只针对当前工作区呢
  css模块化配置如下(scss/less/stylus等相同)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = {
module:{
rules: [
{
test: /\.css$/,
loader: ['style-loader',{
loader: 'css-loader',
options: {
modules: true // true/local 开启模块化机制 默认global
}
}],
exclude: /node_modules/
}
]
}
};

  之前我们引入样式的方式如下

1
import "./app.css";

  重新打包后我们发现,app.css中标签样式可以显示,而类选择器、id选择器等样式没有生效
  我们查看一下打包后生成的样式会发现样式并没有丢失,但除标签名外,其他选择器名都帮我们改为了无意义的字符串
  也就是说,如果我们想用这些样式,就要知道我们写的类名对应生成的字符串是什么,那么如何获取这些名称呢
  modules为我们抛出了一个对象,key为我们定义的选择器名,value对应生成的字符串
  我们需要这样引入:

1
2
3
4
// 个人猜测 模块化是根据原有选择器名进行编码处理 再通过export default { 选择器名1: 编码选择器名1,选择器名2: 编码选择器名2,...  }
import CSS from"./app.css";

// 假如我们在app.css有一个样式 .avatar{ ... } 此时我们只需要获取CSS.avatar 并将其绑定到对应DOM上,即可生效

  默认hash编码,我们还可以指定编码方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module.exports = {
module:{
rules: [
{
test: /\.css$/,
loader: ['style-loader',{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[path][name]__[local]--[hash:base64:5]',
},
}
}],
exclude: /node_modules/
}
]
}
};
  • 字体打包

  当我们使用外部字体库时,很显然直接引用,我们需要对字体进行打包处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module.exports = {
module:{
rules: [
{
test: /\.(woff|woff2|svg|eot|ttf)/, // 常用字体库
loader: [{
loader: 'file-loader', // 还记得我们的图片打包么
options: { // 若不配置,默认打包只output文件下,并修改文件名为编码后的字符串
outputPath: "font/", // 输出的文件路径
name: '[name].[ext]' // 输出的文件名 ext是文件后缀名称
}
}],
exclude: /node_modules/
}
]
}
};