webpack 开发loader和plugin

1、了解loader和plugin分别是做什么的
 
loader:它是一个转换器,将A文件进行编译成B文件,比如:将A.less转换为A.css,单纯的文件转换过程。
plugin:是一个扩展器,它丰富了webpack本身,针对是loader结束后,webpack打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听webpack打包过程中的某些节点,执行广泛的任务

 

2、开发loader
新建一个和webpack同级的名为loaders的文件夹

 

- loaders
...
-- html-plugin.js
-- image-plugin.js
-- less-plugin.js
-- style-plugin.js
-- typescript-plugin.js
-- vue-plugin.js

 

html-plugin实例代码如下
function htmlLoader (source) {
// const context = this;
console.log(context.request, source);
return source;
};

module.exports = htmlLoader;

 

第一种 webpack如何调用通过动态进入调用
...
{
  test:/\.html?$/i,
  use:[
     {
      loader: path.resolve(__dirname,'./loaders/html-loader.js'),
      options: {
        typescript: false
      }
    }
  ]
}

第二种 webpack设置resolveLoader

 
...
resolveLoader: {
  modules: [
    'node_modules',
    path.resolve(__dirname, '../loaders')
  ]
}

{
  test:/\.html?$/i,
  use:[
     {
      loader: 'html-loader',
      options: {
        typescript: false
      }
    }
  ]
}
第三种 通过plugin动态注入loader,下面plugin中详细说

 

3、开发plugin

 

我们开发一个动态注入loader的plugin,方便我们简化webpack配置
plugin需要手动声明一个apply的方法,webpack会把参数回调给这个方法
webpack-plugin有自己的生命周期这个自己看就行了
新建pulgin文件夹

 

- plugin
-- inject-plugin

 

代码如下
const path = require('path');

class InjectPlugin {
  constructor (options) {
    this.loaders = {
      'test.html': {
        loader: path.resolve(__dirname, '../../loaders/html-loader/index.js'),
        options: {
          html: false
        }
      },
      'test.png': {
        loader: path.resolve(__dirname, '../../loaders/image-loader/index.js'),
        options: {
          html: false
        }
      },
      'test.js': {
        loader: path.resolve(__dirname, '../../loaders/javascript-loader/index.js'),
        options: {
          html: false
        }
      },
      'test.sass': {
        loader: path.resolve(__dirname, '../../loaders/scss-loader/index.js'),
        options: {
          html: false
        }
      },
      'test.vue': {
        loader: path.resolve(__dirname, '../../loaders/vue-loader/index.js'),
        options: {
          html: false
        }
      },
      'test.ts': {
        loader: path.resolve(__dirname, '../../loaders/typescript-loader/index.js'),
        options: {
          typescript: false
        }
      },
      'test.less': {
        loader: path.resolve(__dirname, '../../loaders/less-loader/index.js'),
        options: {}
      },
      'style.less': {
        loader: path.resolve(__dirname, '../../loaders/style-loader/index.js'),
        options: {
          style: true
        }
      }
    };
  }

  apply (compiler) {
    this.compiler = compiler;
    const rules = compiler.options.module.rules;
    rules.forEach(rule => {
      Object.entries(this.loaders).forEach(([file, item]) => {
        if (rule.test.test(file) === true) {
          if (typeof rule.use === 'string') {
            rule.use = [rule.use, item];
          } else {
            rule.use = [...rule.use, item];
          }
        }
      });
    });
    // console.log(rules);
  }
}

module.exports = InjectPlugin;

 

如何在webpack中引用
const InjectPlugin = require('../plugin/webpack-plugin');

...
plugins:[
   new InjectPlugin({title:'test'}),
]

 

4、如何debug 调试

package.json 中新增脚本

"debug": "cross-env BUILD_ENV=development node --inspect node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack/webpack.config.js",


npm run debug后打开谷歌调试 chrome://inspect/#devices -> Open dedicated DevTools for Node

 

 

 

 
 
posted @ 2022-03-13 12:23  程序員劝退师  阅读(139)  评论(0编辑  收藏  举报