创建自己的Loader

  1. module.exports = function (content) {
  2. console.log('async------------------')
  3. return content
  4. }

引入loader

resolveLoader属性

  1. resolveLoader: {
  2. modules: ['./wsy-loader', "node_modules"],
  3. },
  1. const path = require('path');
  2. const htmlWebpackPlugin = require('html-webpack-plugin');
  3. const { CleanWebpackPlugin }= require('clean-webpack-plugin');
  4. module.exports = {
  5. entry: './src/main.js',
  6. mode: 'production',
  7. output: {
  8. path: path.resolve(__dirname, 'dist'),
  9. filename: 'main.js',
  10. },
  11. resolveLoader: {
  12. modules: ['./wsy-loader', "node_modules"],
  13. },
  14. module: {
  15. rules: [{
  16. test: /\.js$/,
  17. use: [{
  18. loader: 'wsy-loader1'
  19. }],
  20. enforce: 'pre'
  21. }, {
  22. test: /\.js$/,
  23. use: [{
  24. loader: 'wsy-loader-async',
  25. }, ]
  26. }],
  27. },
  28. plugins: [
  29. new htmlWebpackPlugin({
  30. template: path.resolve(__dirname, 'public/index.html'),
  31. title: 'test-loader'
  32. }),
  33. new CleanWebpackPlugin()
  34. ]
  35. };

loader的执行顺序

从后向前、从右向左的

  1. async------------------
  2. norm--------------------------

pitch-loader

  1. norm---------pitch-----------------
  2. async---------pitch-----------------
  3. async------------------
  4. norm--------------------------

enforce

enforce一共有四种方式:

  1. 默认所有的loader都是normal;
  2. 在行内设置的loader是inline(在前面将css加载时讲过,import ‘loader1!loader2!./test.js’);
  3. 也可以通过enforce设置 pre 和 post;
  1. module: {
  2. rules: [
  3. {
  4. test: /\.js$/,
  5. use: [{
  6. loader: 'wsy-loader1'
  7. }],
  8. enforce: 'pre'
  9. },
  10. {
  11. test: /\.js$/,
  12. use: [{
  13. loader: 'wsy-loader-async',
  14. }, ]
  15. }
  16. ],
  17. },

在Pitching和Normal它们的执行顺序分别是:

  • post, inline, normal, pre;
  • pre, normal, inline, post;
  1. async---------pitch-----------------
  2. norm---------pitch-----------------
  3. norm--------------------------
  4. async------------------

同步的Loader

默认创建的Loader就是同步的Loader,

这个Loader必须通过 return 或者 this.callback 来返回结果,交给下一个loader来处理;

p通常在有错误的情况下,我们会使用 this.callback;

this.callback的用法如下:

  1. 第一个参数必须是 Error 或者 null;
  2. 第二个参数是一个 string或者Buffer;
  1. // 第一种
  2. module.exports = function (content) {
  3. return content
  4. }
  5. // 第二种
  6. module.exports = function (content) {
  7. this.callback(null,content)
  8. }

异步的Loader

  1. module.exports = function (content) {
  2. const callback = this.async()
  3. setTimeout(()=>{
  4. callback(null,content)
  5. })
  6. }

传入和获取参数

  • this.query
  • loader-utils
  1. // 第一种
  2. const {
  3. getOptions
  4. } = require('loader-utils');
  5. module.exports = function (content) {
  6. const options = getOptions(this);
  7. console.log('norm--------------------------', options)
  8. return content
  9. }
  10. // 第二种
  11. module.exports = function (content) {
  12. const options = this.query;
  13. console.log('norm--------------------------', options)
  14. return content
  15. }

校验参数

安装依赖

  1. yarn add schema-utils -D
  1. // 新建schema.json
  2. {
  3. "type": "object",
  4. "properties": {
  5. "name": {
  6. "type": "string",
  7. "description": "请选择true or false"
  8. },
  9. "sourceMap": {
  10. "type": "boolean",
  11. "description": "sourceMap值是不对的啊"
  12. }
  13. },
  14. "additionalProperties": true
  15. }
  1. const {
  2. getOptions
  3. } = require('loader-utils');
  4. const schemaOptions = require("./schema.json")
  5. const configuration = {
  6. name: "Loader Name/Plugin Name/Name"
  7. };
  8. const {
  9. validate
  10. } = require('schema-utils');
  11. module.exports = function (content) {
  12. const options = getOptions(this);
  13. validate(schemaOptions, options, {
  14. name: "MyPlugin",
  15. postFormatter: (formattedError, error) => {
  16. return formattedError;
  17. },
  18. })
  19. this.callback(null, content)
  20. }