manlili blog

webpack之loaders例子(css,sass-loader)

下面来介绍css或者less的打包转义后插入html,一般打包用css-loader,插入html用的style-loader,
源码地址https://github.com/manlili/webpack_learn里面的lesson09
下面来看下步骤

第一步

在空白的文件夹正确的安装webpack,这一步webpack入门指南已经讲过了。
然后创建源文件夹src,在src下面创建app.js和css文件夹,css文件夹下面创建个common.css,然后创建个目标文件夹dist,用来盛放打包生成的文件.

第二步

在根目录下面创建index.html,内容是:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
</body>
</html>

来看下common.css文件内容:

1
2
3
4
5
html , body {
padding: 0;
margin: 0;
background-color: red;
}

为了测试,我们将app.js用ES6的语言引入待打包的common.css,内容是:

1
2
3
4
import style from './css/common.css'
const App = () => {
console.log("测试");
}

第三步

配置webpack的打包配置文件webpack.config.js,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//使用css-loader
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/app.js',
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name].bundle.js' //区分文件有[name], [hash], [chunkhash]
},
module: {
rules: [
{
test: /\.js$/, //用正则匹配找到所有的js文件
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: {
loader: 'babel-loader'
}
},
{
test: /\.css$/,
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: [
{loader: 'style-loader'},//注意先后顺序,一般都要先用css-loader处理完然后用style-loader生成style标签,但webpack读取的顺序是从右到左
{loader: 'css-loader'}
]
}
]
},
plugins: [
new htmlWebpackPlugin({
filename: 'index.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
inject: 'body', //打包生成的js,css和其他东西插入的位置
title: 'i am girl'
})
]
}

注意上面使用了css-loaderstyle-loader,需要先安装才可以使用,可以在他们的官网找到安装的方法,这里我就讲安装的方法贴出来:

1
2
npm install --save-dev css-loader
npm install style-loader --save-dev

接下来来看下我们的文件夹组成
图

第四步

在根目录下打开命名行输入

1
webpack

打包后发现dist/js下面生成的app.bundle.js(打包后代码很乱,无需关注),这时检查是否在html里面插入了css,这个时候我们来看下生成的index.html内容:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>i am girl</title>
</head>
<body>
<script type="text/javascript" src="js/app.bundle.js"></script></body>
</html>

咦?为什么生成的index.html里面没有内嵌css,因为我们是在app.js里面引入的css,所以打包直接将css转义到了生成的app.bundle.js里面,感兴趣的同学可以自己去查下生成的app.bundle.js的代码。
既然不能直接打开生成的index.html查看,那么就需要在浏览器里面面打开,得到的效果如下:
图

第五步

其实我们可以使用连着的loader,下面来看修改过的webpack.config.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//loaders连着书写的方式进行css打包
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/app.js',
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name].bundle.js' //区分文件有[name], [hash], [chunkhash]
},
module: {
rules: [
{
test: /\.js$/, //用正则匹配找到所有的js文件
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: {
loader: 'babel-loader'
}
},
{
test: /\.css$/,
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: ["style-loader", "css-loader"]
}
]
},
plugins: [
new htmlWebpackPlugin({
filename: 'index.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
inject: 'body', //打包生成的js,css和其他东西插入的位置
title: 'i am girl'
})
]
}

在根目录下打开命名行输入

1
webpack

可以看出打包后的效果是一致的。

如果我们需要给css加浏览器前缀,比如将common.css修改为:

1
2
3
4
5
6
7
8
html , body {
padding: 0;
margin: 0;
background-color: red;
}
.box-flex {
display: flex;
}

我们都知道flex的兼容性不是太好,需要加浏览器前缀,下面来看下postcss,这个loader很牛逼,有200多个插件,主要是用来处理css,安装方法如下:

1
2
npm install postcss --save-dev
npm install postcss-loader --save-dev

下面来看修改过的webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/app.js',
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name].bundle.js' //区分文件有[name], [hash], [chunkhash]
},
module: {
rules: [
{
test: /\.js$/, //用正则匹配找到所有的js文件
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: {
loader: 'babel-loader'
}
},
{
test: /\.css$/,
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: ["style-loader", "css-loader", "postcss-loader"]
}
]
},
plugins: [
new htmlWebpackPlugin({
filename: 'index.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
inject: 'body', //打包生成的js,css和其他东西插入的位置
title: 'i am girl'
})
]
}

根据postcss-loader官网要求,如果需要给postcss-loader参加参数或者插件,需要在根目录下新建一个postcss.config.js,内容是:

1
2
3
4
5
module.exports = {
plugins: [
require('autoprefixer') //自动给css新属性加浏览器前缀
]
}

在根目录下打开命名行输入

1
webpack

发现生成的index.html在浏览器打开以后出现:
图
果然像我们预期的那样出现了浏览器的前缀

第六步

有时候我们项目会使用less或者scss,这个时候打包我们就需要用到less-loader或者sass-loader,假设我们项目用到了scss,在src/css文件下创建一个test.scss,内容是:

1
2
3
4
$blue : red; 
.test {
color : $blue;
}

安装sass-loader方法(这步很重要):

1
npm install sass-loader node-sass webpack --save-dev

接下来来看webpack.config.js配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//使用sass-loader
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/app.js',
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name].bundle.js' //区分文件有[name], [hash], [chunkhash]
},
module: {
rules: [
{
test: /\.js$/, //用正则匹配找到所有的js文件
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
use: {
loader: 'babel-loader'
}
},
{
test: /\.css$/,
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
},{
loader: "postcss-loader"
}, {
loader: "sass-loader"
}]
},
{
test: /\.scss$/,
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
},{
loader: "postcss-loader"
}, {
loader: "sass-loader"
}]
}
]
},
plugins: [
new htmlWebpackPlugin({
filename: 'index.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
inject: 'body', //打包生成的js,css和其他东西插入的位置
title: 'i am girl'
})
]
}

在根目录下打开命名行输入

1
webpack

发现生成的index.html在浏览器打开以后出现:
图
从上图我们发现了按我们预期的将scss转义成了css,并且插入了到了html里面

请我喝杯果汁吧!