webpack只能打包javascript,如何让webpack处理各式各样的静态资源呢?这时就需要借助loader了。loader赋予了webpack处理不同类型资源的能力,极大的丰富了其可扩展性。
loader概述
loader本质上是一个函数,形如output=loader(input),将output结果输送到webpack进行后续处理,或者作为下一个loader的输入向后传递。如下所示:
//使用babel-loader将ES6+转换为ES5
ES5=babel-loader(ES6+)
//使用sass-loader css-loader style-loader编译SCSS
Style标签=style-loader(css-loader(sass-loader(scss)))
loader引入
loader都是一些第三方npm模块,因此使用loader的第一步就是先从npm安装它。以css-loader为例。在工程目录下执行命令:
npm install css-loader
接下来将loader引入工程中,具体配置如下
module.exports={
module:{
rules:[{
test: /\.css$/,
use: ['css-loader']
}]
}
}
链式loader
很多时候,在处理某一类资源时,我们都需要使用多个loader。如,对于SCSS类型的资源来说,我们需要sass-loader来处理其语法,并将其编译为css,接着再用css-loader处理css的各类加载语法;最后使用style-loader来将样式字符串包装成style标签插入页面。
module.exports={
module:{
rules:[{
test: /\.css$/,
use: ['style-loader','css-loader','sass-loader']
}]
}
}
Webpack打包时是按照数组从后向前的顺序将资源交给loader处理的,因此要把最后生效的放在最前面。
loader options
loader作为预处理器,通常会给开发者提供一些配置项,在引入loader的时候,可以通过options将他们传入。
module.exports={
module:{
rules:[{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
//css-loader配置项
}
},
'sass-loader'
]
}]
}
}
更多配置
1. exclude和include
exclude和include是用来排除或者包含指定目录的模块,可以接受正则表达式或者字符串,以及由他们组成的数组。下面例子中表示,node_modules中的模块不会被这些loader处理。
module.exports={
module:{
rules:[{
test: /\.css$/,
use: ['style-loader','css-loader','sass-loader'],
exclude: /node_module/
}]
}
}
下面例子中,表示仅处理src目录下的css文件。
module.exports={
module:{
rules:[{
test: /\.css$/,
use: ['style-loader','css-loader','sass-loader'],
include: /src/
}]
}
}
当exclude和include同时存在时,exclude的优先级更高。下面例子虽然配置了include,但无法覆盖exclude的配置。
module.exports={
module:{
rules:[{
test: /\.css$/,
use: ['style-loader','css-loader','sass-loader'],
exclude: /node_module/,
include: /node_module\/awesome-ui/
}]
}
}
假如,我们想让该规则对node_modules中的某一模块生效,可更改exclude的正则。
module.exports={
module:{
rules:[{
test: /\.css$/,
use: ['style-loader','css-loader','sass-loader'],
exclude: /node_module\/(?!(awesome-ui)\/).*/,
}]
}
}
由于exclude的优先级更高,可以对include的子目录进行排除。
module.exports={
module:{
rules:[{
test: /\.css$/,
use: ['style-loader','css-loader','sass-loader'],
include: /src/,
exclude: /src\/lib/,
}]
}
}
2. resource与issuer
resource和issuer可以用于更加精确地确定模块规则的作用范围。 resource就是被加载的模块,issuer是加载者。前面介绍的test/exclude/include都是针对resource的。如果想对加载者添加条件限制,也可以通过配置实现。
如下代码所示,添加了issuer配置对象,表示只有/src/pages/目录下的JS文件应用CSS文件时,这条规则才会生效。
module.exports={
module:{
rules:[{
use: ['style-loader','css-loader','sass-loader'],
test: /\.css$/,
include: /src/,
exclude: /src\/lib/,
issuer:{
test:/\.js$/,
include: /src\/pages/
}
}]
}
}
事实上,我们也可以将上面的代码该一下,增加其可读性。
module.exports={
module:{
rules:[{
use: ['style-loader','css-loader','sass-loader'],
resource:{
test: /\.css$/,
include: /src/,
exclude: /src\/lib/,
}
issuer:{
test:/\.js$/,
include: /src\/pages/
}
}]
}
}
3. enfore
enforce用来指定一个loader的种类,只能接受“pre”"post"两种字符串类型的值。 pre表示他将在所有正常loader之前执行。
module.exports={
module:{
rules:[{
test: /\.css$/,
use: ['style-loader','css-loader','sass-loader'],
include: /src/,
exclude: /src\/lib/,
enforce: 'pre'
}]
}
}
常用Loader
babel-loader、 ts-loader、 html-loader、 file-loader、 url-loader、 vue-loader、
vue-loader用于处理vue组件,vue-loader可将组件的模板、js、及样式进行拆分,因此在安装时,除了必要的vue与vue-loader外,还需要vue-template-compiler来编译Vue模板,以及css-loader来处理样式。