loader的作用,主要是给源码source做特殊处理。

初始化环境

创建一个defineLoader环境,创建一个文件夹defineLoader

  1. npm init -y
  2. npm install webpack webpack-cli -D

创建被编译的文件

在defineLoader内创建文件夹src,并创建index.js

  1. console.log("hello 北鸟南游");

webpack配置文件

webpack.config.js

  1. const path = require("path");
  2. module.exports = {
  3. mode: 'development',
  4. entry:{
  5. main:"./src/index.js"
  6. },
  7. output:{
  8. path: path.resolve(__dirname, "dist"),
  9. filename: '[name].js'
  10. }
  11. }

定义loader

创建loaders文件夹,并创建replaceLoader.js

  1. module.exports = function(source){
  2. // 函数体内this上挂有多个方法和属性,具体参考https://webpack.js.org/api/loaders/
  3. return source.replace(/北鸟南游/g, 'shenshuai89@qq.com');
  4. }

修改webpack配置文件

  1. const path = require("path");
  2. module.exports = {
  3. mode: 'development',
  4. entry:{
  5. main:"./src/index.js"
  6. },
  7. output:{
  8. path: path.resolve(__dirname, "dist"),
  9. filename: '[name].js'
  10. },
  11. // 新增对js文件的处理,添加自定义的loader
  12. module:{
  13. rules:[{
  14. test: /\.js/,
  15. use: [
  16. path.resolve(__dirname, './loaders/replaceLoader.js')
  17. ]
  18. }]
  19. }
  20. }

通过options给loader传参

将use数组中直接应用loader路径修改为对象

  1. module:{
  2. rules:[{
  3. test: /\.js/,
  4. use: [{
  5. loader: path.resolve(__dirname, './loaders/replaceLoader.js'),
  6. options: {
  7. name: 'shenshuai'
  8. }
  9. }]
  10. }]
  11. }

修改loader内部对options参数的接收。

  1. module.exports = function(source){
  2. // 函数体内this上挂有多个方法和属性,具体参考https://webpack.js.org/api/loaders/
  3. return source.replace(/北鸟南游/g, this.query.name);
  4. }

使用loader-utils插件【4版本】

loader-utils更方便的解析options中的参数

安装 loader-utils

  1. npm install loader-utils --save-dev

引入loader-utils

  1. const loaderUtils = require('loader-utils')
  2. module.exports = function(source){
  3. const options = loaderUtils.getOptions(this)
  4. // 函数体内this上挂有多个方法和属性,具体参考https://webpack.js.org/api/loaders/
  5. return source.replace(/北鸟南游/g, options.name);
  6. }

直接使用this.options【5版本】

新版本5,使用this.getOptions方法,替换原来的loaderUtils.getOptions()
https://webpack.js.org/api/loaders/#thisgetoptionsschema

  1. module.exports = function(source){
  2. console.log(this.getOptions())
  3. // 函数体内this上挂有多个方法和属性,具体参考https://webpack.js.org/api/loaders/
  4. return source.replace(/北鸟南游/g,this.getOptions().name);
  5. }

callback回调替换return

使用return返回最后一个值,只能返回一个参数,可以使用callback返回多个参数
https://webpack.js.org/api/loaders/#thiscallback

  1. this.callback(
  2. err: Error | null,
  3. content: string | Buffer,
  4. sourceMap?: SourceMap,
  5. meta?: any
  6. );
  1. 第一个参数必须是一个Error或null
  2. 第二个参数是 astring或 a Buffer
  3. 可选:第三个参数必须是可由该模块解析的源映射。
  4. 可选:第四个选项,被 webpack 忽略,可以是任何东西(例如一些元数据)。
    1. module.exports = function(source){
    2. // 函数体内this上挂有多个方法和属性,具体参考https://webpack.js.org/api/loaders/
    3. const result = source.replace(/北鸟南游/g,this.getOptions().name);
    4. this.callback(null, result)
    5. }

    async异步函数

    loader内异步操作的处理https://webpack.js.org/api/loaders/#thisasync
    1. module.exports = function(source){
    2. // 使用this.async()重新定义callback
    3. const callback = this.async()
    4. // 函数体内this上挂有多个方法和属性,具体参考https://webpack.js.org/api/loaders/
    5. setTimeout(()=>{
    6. const result = source.replace(/北鸟南游/g,this.getOptions().name);
    7. callback(null, result)
    8. }, 1000)
    9. }

    简化loader引入

    使用resolveLoader配置loader路径,可以简化loader路径的地址的写法。
    1. resolveLoader:{
    2. modules:['node_modules', './loaders']
    3. },
    4. module:{
    5. rules:[{
    6. test: /\.js/,
    7. use: [{
    8. loader: 'replaceLoader',
    9. options: {
    10. name: 'shenshuai'
    11. }
    12. }]
    13. }]
    14. }
    通过resolveLoader简化,可以定义加载loader的文件夹。