webpack手写同步loader
- Loader其实就是一个函数,只需要自定义一个模块,在模块中暴露一个函数,在函数中实现Loader相关的功能即可
注意点
- 这个函数必须是一个普通函数(es5),不能是箭头函数(es6),因为webpack在调用Loader的时候会修改这个函数中的this,而如果是箭头函数webpack就不能修改了
- webpack在调用Loader的时候会将打包文件的内容传递给实现Loader的函数中的形参,拿到内容后就可以对内容进行操作,然后再将操作后的内容返回回去即可
- 在loader中返回的数据必须是字符串类型或者是二进制类型
需求:将index.js中的nhw替换为nb
- index.js:
console.log("123nhw123");
创建一个ReplaceLoader模块:主要用来替换文本内容
// module.exports将函数暴露出去,source可拿到打包文件内容,return将操作后的内容返回 module.exports = function (source) { source = source.replace(/nhw/g, "nb"); return source; };
在webpack.config.js中添加配置:
module.exports = { module: { rules: [{ test: /\.js$/, use: [{ loader: path.resolve(__dirname, 'loader/ReplaceLoader.js') }] }] } }
处理loader参数
在webpack.config.js中配置Loader的时候, 可以通过options配置一些额外的参数
module.exports = { module: { rules: [{ test: /\.js$/, use: [{ loader: path.resolve(__dirname, 'loader/ReplaceLoader.js'), options: { name: "lyt" } }] }] } }
获取参数方法一(不推荐)
通过loader函数中的this获取
this.query
获取方法二(推荐)
通过loader-utils模块获取
- 安装模块:
npm install --save-d loader-utils
- 导入模块:
const loaderUtils = require('loader-utils');
ReplaceLoader.js:
const loaderUtils = require('loader-utils'); module.exports = function (source) { // console.log(this.query.name); let options = loaderUtils.getOptions(this); console.log(options.name); source = source.replace(/nhw/g, options.name); return source; };
- 安装模块:
校验loader参数
通过schema-utils模块来校验
- 安装模块:
npm install --save-d schema-utils
- 导入模块:
const validateOptions = require('schema-utils');
ReplaceLoader.js:
- 当options中传递的参数类型不符就会报错
const loaderUtils = require('loader-utils'); const validateOptions = require('schema-utils'); module.exports = function (source) { // 1.获取webpack传递过来的参数 // console.log(this.query.name); let options = loaderUtils.getOptions(this); console.log(options.name); // 2.定制校验的规则 let schema = { type: "object", // 可以在properties中告诉webpack, 当前loader可以传递哪些参数 properties: { // 可以传递name参数 name: { // name参数的数据类型必须是字符串类型 type: "string" } }, additionalProperties: false }; // 3.利用校验方法校验传递过来的参数是否符合指定的规则 validateOptions(schema, options, 'RepalceLoader'); source = source.replace(/nhw/g, options.name); return source; };
- 安装模块:
简化loader使用
- 只编写loader的名称,不需要通过path指定loader的路径
在webpack.config.js中使用resolveLoader配置来简化
module.exports = { resolveLoader: { // 起别名 alias: { ReplaceLoader: path.resolve(__dirname, "loader/ReplaceLoader.js") } // 或者先在node_modules目录下查找再在./loader目录下查找 // modules: [ 'node_modules', './loader'], }, }
于是在loader中只用写:
loader: path.resolve('ReplaceLoader'),
module: { rules: [{ test: /\.js$/, use: [{ loader: 'ReplaceLoader', options: { name: "lyt" } }] }] }