loader我的理解是把非js的模块转换成js模块,毕竟浏览器只认识js语言
官方的说法:loader 是导出为一个函数的 node 模块。该函数在 loader 转换资源的时候调用。给定的函数将调用 loader API,并通过 this
上下文访问。
当处理一种类型模块的时候,多个loader配置时从右向左或者从下向上执行。
loader使用主要有以下三种方式:
module.exports = { module:{ rules:[ { test: /.less$/, loader:'css-loader!less-loader', // 1.多个loader中用感叹号分隔(无参数传递时) }, { test:/.css/, use:['css-loader'],//2.数组形式(无参数传递时) }, { test:/.(png|gif|jpg)$/, use:[ // loader传递参数时建议该方法 { loader: 'file-loader', options:{ // file-loader自己的参数,跟webpack无关 name: 'images/[name].[hash:8].js' } } ] } ] } };
1.自己编写需要的loader需知
// Webpack中loader是一个CommonJs风格的函数,接收输入的源码,通过同步或异步的方式替换源码后进行输出。 // module.exports = function (source, sourceMap, meta) { // } // •source是输入的内容 // •sourceMap是可选的 // •meta是模块的元数据,也是可选的 // 需要注意的是,该导出函数必须使用function,不能使用箭头函数,因为loader编写过程中会经常使用到this访问选项和其他方法。
2.自定义loader--replace-loader.js
// 通过loader - utils来读取配置选项 const loaderUtils = require('loader-utils'); // module.exports = function (source) { // const options = loaderUtils.getOptions(this); // return source.replace(/World/g, options.text); // }; // loader异步,通过this.async(),此例子,打包的时候等待1秒 module.exports = function (source) { const callback = this.async(); const options = loaderUtils.getOptions(this); setTimeout(() => { const output = source.replace(/World/g, options.text); callback(null, output); }, 1000); }
要是想获取从webpack.config.js配置文件里获取对应的loader参数,需要先npm loader-utils这个东西先
具体在loader中获取参数看上面代码。
在Loader中,如果存在异步调用,那么就无法直接通过return返回构建后的结果了,此时需要使用到Webpack提供的回调函数将数据进行回调。
Webpack4给Loader提供了this.async()
函数,调用之后返回一个callback,上面例子打包的时候需要等待人为设置的1秒
loader要是想取其他文件的内容要通过require('path')
3.webpack.config.js中使用
const path = require('path'); module.exports = { entry: './src/index', mode: 'production', target: 'node', // 我们编译为Node.js环境下的JS,等下直接使用Node.js执行编译完成的文件 output: { path: path.resolve(__dirname, 'build'), filename: '[name].js' }, module: { rules: [ { test: /.js$/, use: [ { loader: 'replace-loader', options: {// 给loader传的参数 text: 'Webpack4--loader异步' } }, { loader: 'i18n-loader', options: { // 传递选项 locale: 'zh' } } ] } ] }, resolveLoader: { modules: ['./node_modules', './loader'] // 配置loader的查找目录 } };
可以看到replace-loader的参数传递为text;
而引入loader文件通过resolveLoader里的内容,从node_modules依赖包和我自定义的loader文件里找到对应的loader
文件目录:
可参考:
https://www.webpackjs.com/contribute/writing-a-loader/
https://mp.weixin.qq.com/s/i5eZ02uh7MC-TbKb9VJF-w