美文网首页
编写 Loader 和插件

编写 Loader 和插件

作者: 饼干www | 来源:发表于2019-12-18 11:43 被阅读0次

    Loader Interface
    loader-utils
    loader-runner

    一个最简单的 loader 代码结构

    定义: loader 只是一个导出为函数的 JavaScript 模块

    module.exports = function (source) {
        return source;
    };
    

    使用loader-runner进行loader的调试

    定义:允许你在不安装webpack的情况下运行loaders
    作用:作为webpack的依赖,在webpack中执行loader
    进行loader的开发和调试

    import {runLoaders} from 'loader-runner';
    runLoaders({
        resource: "/abs/path/to/file.txt?query",
        loaders: [],
        context: {},
        readResource: fs.readFile.bind(fs)
    }, function(err, result) {
        // err
        // result
    });
    
    属性名 说明
    resource 资源的绝对路径(可以增加查询字符串)
    loaders loader 的绝对路径(可以增加查询字符串)
    context 基础上下文之外的额外 loader 上下文
    readResource 读取资源的函数

    loader的参数获取

    通过loader-utils的getOptions方法获取

    const loaderUtils = require("loader-utils");
    module.exports = function(content) {
         const { name } = loaderUtils.getOptions(this);
    };
    

    loader的异常处理

    1、loader 内直接通过 throw 抛出
    2、通过\color{red}{this.callback}传递错误

    this.callback(
        err: Error | null,
        content: string | Buffer, 
        sourceMap?: SourceMap,
        meta?:any
    );
    

    loader的异步处理

    通过\color{red}{this.async} 来返回一个异步函数

    module.exports = function(input) { 
        const callback = this.async();
        // No callback -> return synchronous results // if (callback) { ... }
        callback(null, input + input); //第一个参数是 Error,第二个参数是处理的结果
    };
    

    在 loader 中使用缓存

    webpack 中默认开启 loader 缓存
    (可以使用 this.cacheable(false) 关掉缓存)
    缓存条件: loader 的结果在相同的输入下有确定的输出
    (有依赖的 loader 无法使用缓存)

    loader 如何进行文件输出

    通过\color{red}{this.emitFile}进行文件写入

    const loaderUtils = require("loader-utils");
    module.exports = function (content) {
        const url = loaderUtils.interpolateName(this, "[hash].[ext]", {
            content,
        });
        this.emitFile(url, content);
        const path = `__webpack_public_path__ + ${JSON.stringify(url)};`;
        return `export default ${path}`;
    };
    

    插件的运行环境

    只能在 webpack 里面运行

    插件的基本结构

    基本结构

    /* 插件名称 */
    class MyPlugin {
        /* apply方法 */
        apply(compiler) {
            /* 插件的hooks */
            compiler.hooks.done.tap(' My Plugin', (
                stats/* stats is passed as argument when done hook is tapped. */
            ) => {
                /* 逻辑 */
                console.log('Hello World!');
            });
        }
    }
    module.exports = MyPlugin;
    

    插件使用:

    plugins: [ new MyPlugin() ]
    

    搭建插件的运行环境

    const path = require("path");
    const DemoPlugin = require("./plugins/demo-plugin.js");
    const PATHS = {
        lib: path.join(__dirname, "app", "shake.js"),
        build: path.join(__dirname, "build")
    };
    module.exports = {
        entry: {
            lib: PATHS.lib,
        },
        output: {
            path: PATHS.build,
            filename: "[name].js",
        },
        plugins: [new DemoPlugin()]
    };
    

    插件中如何获取传递的参数

    通过插件的构造函数进行获取

    constructor(options) {
        this.options = options;
    }
    
    new ZipPlugin({
        filename: 'offline'
    })
    

    插件的错误处理

    参数校验阶段可以直接 throw 的方式抛出

    throw new Error(“ Error Message”);
    

    通过 compilation 对象的 warnings 和 errors 接收

    compilation.warnings.push("warning"); 
    compilation.errors.push("error");
    

    通过 Compilation 进行文件写入

    Compilation 上的 assets 可以用于文件写入
    文件写入需要使用 webpack-sources (https://www.npmjs.com/package/webpack-sources)

    const {
        RawSource
    } = require("webpack-sources");
    module.exports = class DemoPlugin {
        constructor(options) {
            this.options = options;
        }
        apply(compiler) {
            const {
                name
            } = this.options;
            compiler.plugin("emit", (compilation, cb) => {
                compilation.assets[name] = new RawSource("demo");
                cb();
            })
        }
    };
    

    相关文章

      网友评论

          本文标题:编写 Loader 和插件

          本文链接:https://www.haomeiwen.com/subject/xlyenctx.html