webpack-编写loader

Posted 金钩梨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
        }

以上是关于webpack-编写loader的主要内容,如果未能解决你的问题,请参考以下文章

webpack loader自定义编写

webpack loader自定义编写

webpack3.0之loader配置及编写

编写一个webpack loader

webpack-底层原理(Loader编写Plugin编写 Bundler编写)

Webpack 系列第六篇:如何编写loader