回顾第二章提出的一个问题:
上面只是演示了对 js 文件的打包,所谓的一切皆模块儿的概念没有体现呢,如何做?
webpack 的世界里,一切都是模块儿,不同的模块通过相应的模块儿加载器去处理。
其实在我们前端的范畴里,模块儿的类型并不会太多,一般也就那么几种:
文件类型 | 后缀名 |
---|---|
js | .js |
JSON | .json |
css | .css, .scss, .sass |
图片文件 | .jpg, .png, .webp, .gif... |
字体文件 | .eot, .svg, .ttf, .woff ... |
flash | .swf |
jsx | .jsx |
vue | .vue |
html | .html |
twig | .twig |
jade | .jade |
... | ... |
下面我们就通过 webpack 加载 css 模块儿来理解 loader 在 webpack 中所起的作用。
我们依然使用之前的测试项目 webpack-test
在 src 目录下新建 css 文件夹,完成 main.css 的编写
// main.css
html, body {
background: red;
}
修改 main.js 将 css 模块添加到项目中,作为依赖。
// main.js
import './css/main.css' // 这里可以使用相对路径来引入
import './js/b';
这个时候去执行编译命令 npm run build
会得到如下报错:
> webpack
Hash: 695f49dbe3071133e5f6
Version: webpack 3.5.4
Time: 105ms
Asset Size Chunks Chunk Names
main.bundle.js 3.7 kB 0 [emitted] main
[0] ./src/main.js 51 bytes {0} [built]
[1] ./src/css/main.css 215 bytes {0} [built] [failed] [1 error]
[2] ./src/js/b.js 49 bytes {0} [built]
[3] ./src/js/a.js 68 bytes {0} [built]
ERROR in ./src/css/main.css
Module parse failed: /Users/Ben/Work/webpack-test/src/css/main.css Unexpected token (1:11)
You may need an appropriate loader to handle this file type.
html, body {
background: red;
}
@ ./src/main.js 1:0-25
大概意思是说:错误发生在 ./src/css/main.css
, 模块解析失败,你可能需要适当的loader 来解析这种文件类型。
是的,我们只是告诉 webpack 我们依赖 css 文件,但是 webpack 需要合适的 loader 才能处理 css 模块儿。处理 css 模块儿的 loader 是 css-loader
通过 npm 安装 css-loader到开发依赖
npm i -D css-loader
修改 webpack 的配置文件 webpack.config.js 如下
const patch = require('path');
module.exports = {
entry: './src/main.js',
output: {
path: patch.resolve(__dirname, './dist'),
filename: 'main.bundle.js'
},
// 编写针对模块儿的处理配置
module: {
loaders: [
{
test: /\.css$/, // 利用正则匹配,匹配到各种类型的模块儿。
loader: ['css-loader'] // 为具体类型的模块儿使用适当的loader
}
]
},
devServer: {
contentBase: './dist'
}
}
然后重启 devServer
: npm run devServer
可以发现打包成功,没有报错了。
然后查看页面发现,,,我们的样式没有生效。。。这是为什么呢 ??
因为 css-loader 只负责解析 css 文件,并不负责将样式代码添加到页面中。为了做这一步,我们还需要另外一个loader,可以帮助我们把css 代码以 html 中 style 标签的形式插入 html 中。
通过npm 安装 style-loader 到开发依赖
npm i -D style-loader
修改 webpack 配置文件 webpack.config.js
// webpack.config.js
// ...
loaders: [
{
test: /\.css$/,
loader: ['style-loader', 'css-loader'] // loader 的应用顺序是倒序的。
// 所以,webpack 的处理顺序是先试用css-loader 处理,然后再使用style-loader 处理。
}
]
// ...
npm run devServer
重启devServer.
这次可以看到我们的样式已经生效了。并且审查页面的 style 元素可以看到我们写的 css 代码。
至此我们支配 webpack 完成了对 css 模块儿的处理和使用。
但是我们经常使用的是 LESS ,又需要怎么处理呢?非常简单,只需要先把 less 文件利用 less-loader 处理成 css ,然后再按照 css module 处理不就可以了。
直接把前面的 main.css
修改成 main.less
把入口文件main.js 里对 main.css 的依赖改为 main.less
然后把前面写的对 css 文件的正则匹配改成对less 文件的正则匹配。并且在loader 最后面添加 less-loader
// webpack.config.js
// ...
loaders: [
{
test: /\.less$/,
loader: ['style-loader', 'css-loader', 'less-loader'] // loader 的应用顺序是倒序的。
}
]
// ...
记得通过npm 来安装 less-loader 到开发依赖哦
npm i -D less-loader
最后,重启devServer。看看是不是已经生效了 ?
类似 LESS Module 的处理,,不再做说明。
我们以 css 和 less 为例学习了配置 webpack 加载其他类型的模块儿的方法。在使用的时候,我们只需要通过匹配,匹配到具体某种类型的模块儿,然后为这种类型的模块儿使用合适的 loader 就可以了。
- 我们刚才把css代码添加到了 html 的 style 标签中,如果存在大量的 css 代码,难道还要放在style 标签吗?如何把 css 文件提取出来放在单独的文件。
- loader 的运行原理是什么? loader 到底内部做了什么处理就可以让 webpack 来打包不同类型的模块儿 ?