文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
四、配置 loader
4.1 loader 匹配规则
当我们需要配置 loader
时,都是在 module.rules
中添加新的配置项,在该字段中,每一项被视为一条匹配使用 loader
的规则
module.exports = { // ... module: { rules: [ { test: /\.jsx?/, // 条件 include: [ path.resolve(__dirname, 'src'), ], // 条件 use: 'babel-loader', // 规则应用结果 }, // 一个 object 即一条规则 // ... ], }, }...
loader
的匹配规则中有两个最关键的因素:一个是匹配条件,一个是匹配规则后的应用
4.2 规则条件配置
大多数情况下,配置 loader
的匹配条件时,只要使用 test
字段就好了,很多时候都只需要匹配文件后缀名来决定使用什么 loader
,但也不排除在某些特殊场景下,我们需要配置比较复杂的匹配条件。webpack 的规则提供了多种配置形式…
{ test: ... }
匹配特定条件{ include: ... }
匹配特定路径{ exclude: ... }
排除特定路径{ and: [...] }
必须匹配数组中所有条件{ or: [...] }
匹配数组中任意一个条件{ not: [...] }
排除匹配数组中所有条件…
上述的所谓条件的值可以是:
- 字符串:必须以提供的字符串开始,所以是字符串的话,这里我们需要提供绝对路径
- 正则表达式:调用正则的
test
方法来判断匹配 - 函数:
(path) => boolean
,返回true
表示匹配 - 数组:至少包含一个条件的数组
- 对象:匹配所有属性值的条件…
rules: [ { test: /\.jsx?/, // 正则 include: [ path.resolve(__dirname, 'src'), // 字符串,注意是绝对路径 ], // 数组 // ... }, { test: { js: /\.js/, jsx: /\.jsx/, }, // 对象,不建议使用 not: [ (value) => { /* ... */ return true; }, // 函数,通常需要高度自定义时才会使用 ], }, ],...
4.3 使用 loader 配置
module.rules
的匹配规则最重要的还是用于配置 loader
,我们可以使用 use
字段
rules: [ { test: /\.less/, use: [ 'style-loader', // 直接使用字符串表示 loader { loader: 'css-loader', options: { importLoaders: 1 }, }, // 用对象表示 loader,可以传递 loader 配置等 { loader: 'less-loader', options: { noIeCompat: true }, // 传递 loader 配置 }, ], }, ],...
use
字段可以是一个数组,也可以是一个字符串或者表示 loader
的对象。如果只需要一个 loader
,也可以这样: use: { loader: 'babel-loader'
, options: { ... } }
4.4 loader 应用顺序
- 对于上面的
less
规则配置,一个style.less
文件会途径less-loader
、css-loader
、style-loader
处理,成为一个可以打包的模块。 loader
的应用顺序在配置多个loader
一起工作时很重要,通常会使用在 CSS 配置上,除了style-loader
和css-loader
,你可能还要配置less-loader
然后再加个postcss
的autoprefixer
等。- 上述从后到前的顺序是在同一个
rule
中进行的,那如果多个rule
匹配了同一个模块文件,loader
的应用顺序又是怎样的呢?看一份这样的配置…
rules: [ { test: /\.js$/, exclude: /node_modules/, loader: "eslint-loader", }, { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", }, ],...
这样无法法保证 eslint-loader
在 babel-loader
应用前执行。 webpack
在 r ules
中提供了一个 enforce
的字段来配置当前 rule
的 loader
类型,没配置的话是普通类型,我们可以配置 pre
或 post
,分别对应前置类型或后置类型的 loader
…
- 所有的
loader
按照前置 -> 行 内 -> 普通 -> 后置 的顺序执行。所以当我们要确保eslint-loader
在babel-loader
之前执行时,可以如下添加enforce
配置
rules: [ { enforce: 'pre', // 指定为前置类型 test: /\.js$/, exclude: /node_modules/, loader: "eslint-loader", }, ]...
当项目文件类型和应用的 loader
不是特别复杂的时候,通常建议把要应用的同一类型 loader
都写在同一个匹配规则中,这样更好维护和控制
4.5 完整代码
const path = require('path') const webpack = require('webpack') const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextPlugin = require('extract-text-webpack-plugin') const CopyWebpackPlugin = require('copy-webpack-plugin') module.exports = { entry: './src/index', output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js', }, module: { rules: [ { enforce: 'pre', // 指定为前置类型 test: /\.jsx?$/, exclude: /node_modules/, loader: "eslint-loader", }, { test: /\.jsx?$/, include: [ path.resolve(__dirname, 'src'), ], use: 'babel-loader', }, { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: [ 'css-loader', ], }), }, { test: /\.less$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: [ 'css-loader', 'less-loader', ], }), }, { test: /\.(png|jpg|gif)$/, use: [ { loader: 'file-loader' }, ], }, ], }, resolve: { alias: { utils: path.resolve(__dirname, 'src/utils'), // 这里使用 path.resolve 和 __dirname 来获取绝对路径 log$: path.resolve(__dirname, 'src/utils/log.js') // 只匹配 log }, extensions: ['.js', '.json', '.jsx', '.css', '.less'], modules: [ path.resolve(__dirname, 'node_modules'), // 指定当前目录下的 node_modules 优先查找 ], }, plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', // 配置输出文件名和路径 template: 'src/index.html', // 配置文件模板 }), new ExtractTextPlugin('[name].css'), new webpack.DefinePlugin({ TWO: '1+1', CONSTANTS: { APP_VERSION: JSON.stringify('1.1.2'), // const CONSTANTS = { APP_VERSION: '1.1.2' } }, }), new CopyWebpackPlugin([ { from: 'src/assets/favicon.ico', to: 'favicon.ico', }, // 顾名思义,from 配置来源,to 配置目标路径 ]), new webpack.ProvidePlugin({ _: 'lodash', }), ], devServer: { port: '1234', before(app){ app.get('/api/test.json', function(req, res) { // 当访问 /some/path 路径时,返回自定义的 json 数据 res.json({ code: 200, message: 'hello world' }) }) } }, }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论