webpack-编写loader
当我们在源代码里面引入一个新的js、vue等文件的时候,可以借助loader去处理引用的文件
1.初始化一个项目:npm init -y
2.新建文件夹loaders,loaders下面新建文件(loader):replaceLoader.js:
// 不能写成箭头函数,否则this指向就会有问题 module.exports=function(source){ // source:引入文件的内容 return source.replace(‘jin‘,‘goly‘); }
3.使用(webpack.config.js):
const path=require(‘path‘); module.exports={ mode:‘development‘, entry:{ main:‘./src/index.js‘ }, module:{ rules:[{ test:/\.js$/, use:[path.resolve(__dirname,‘./loaders/replaceLoader.js‘)] }] }, output:{ path:path.resolve(__dirname,‘dist‘), filename:‘[name].js‘ } }
4.src/index.js:
console.log(‘jin world‘);
5.运行webpack,打开打包生成的main.js,会发现console.log(‘jin world‘);变成了console.log(‘goly world‘);这样就实现了一个简单的loader。
6.还可以修改一下loader的引入:
use:[{ loader:path.resolve(__dirname,‘./loaders/replaceLoader.js‘), options:{ name:‘hello‘ } }]
那么我们需要如何拿到name呢?是传递参数的形式吗?其实不然,而是通过this:
module.exports=function(source){ // source:引入文件的内容 return source.replace(‘jin‘,this.query.name); }
除了query,还有很多其他的东西,可到官网官网查阅https://webpack.js.org/api/loaders/
7.有时候传递过来的参数会比较诡异,比如说是一个对象或者字符串,直接使用this.query取参数不是很方便,所以官方推荐使用loader-utils模块帮助我们分析一些内容:
npm install loader -D
将replaceLoder.js中修改:
const loaderUtils=require(‘loader-utils‘); module.exports=function(source){ const options=loaderUtils.getOptions(this); return source.replace(‘jin‘,options.name); }
8.现在这样我们只能对源代码做一些处理,但是如果我们现在要使用sourceMap或者说我们对源代码处理好以后我们在返回源代码的同时,还要把sourceMap也带回去,这个时候就需要用到this.callback:
this.callback( err: Error | null, content: string | Buffer, sourceMap?: SourceMap, meta?: any );
那么我们就可以这样使用:
const loaderUtils=require(‘loader-utils‘); module.exports=function(source){ const options=loaderUtils.getOptions(this); const result=source.replace(‘jin‘,options.name); this.callback(null,result); }
9.有时候我们需要写一些异步代码,不能直接使用setTimeout这种,不然打包会报错,需要使用this.async方法:
module.exports=function(source){ // source:引入文件的内容 const options=loaderUtils.getOptions(this); const callback=this.async(); setTimeout(()=>{ const result=source.replace(‘jin‘,options.name); callback(null,result); },1000); }
10.当我们使用多个loader的时候每次写path会显得冗长,webpack提供了一个属性:
resolveLoader:{ modules:[‘node_modules‘,‘./loaders‘] }, module:{ rules:[{ test:/\.js$/, use:[{ loader:‘replaceLoader‘, options:{ name:‘test‘ } }] }] },
resolveLoader属性会帮我们先去node_modules下面找该loader,若不存在,会去loaders下面找
11.loader用途场景:
(1)当我们需要捕获错误信息的时候,可以将所有function(){}改成try{function(){}}catch(err){}
(2)当我们需要导出中英文,可以在业务代码(index.js)中使用占位符:console.log(‘{{title}}‘)
在loader中(replaceLoder.js):
if(Node全局变量){ source.replace(‘{{title}}‘,‘中文标题‘); }else{ source.replace(‘{{title}}‘,‘English Title‘); }