javascript-是否可以让webpacks System.import使用ajax(用于进度事件)?

因此,我刚刚更新到webpack 2,并进行了第一个工作设置,其中webpack通过查看System.import调用自动创建块.真可爱!

但是,我使用ajax调用加载了初始块,因此我可以show the progress while loading

所以我的问题是,我是否可以以某种方式覆盖或更改System.import的功能,以便它将使用我可以监听事件的ajax请求,而不是使用< script>标签?

最佳答案
不,不幸的是没有. webpack 2将System.import()转换为普通的require.ensure()调用,该调用仅使用< script>标签.甚至官方的WHATWG Loader Spec也没有为此类事件提供API.我有这个问题的created an issue.

关于webpack:有一种方法可以实现自己的require.ensure().但是,由于块加载是Webpack不可或缺的一部分,因此这需要更深入地研究.我不确定这对您有多重要,但是您可能会对Webpack中的工作方式感兴趣,所以让我们看一下:

在webpack中,所有内部功能都作为插件实现.这样,webpack能够支持许多不同的功能和环境.因此,如果您对在Webpack中如何实现事物感兴趣,那么a)查看WebpackOptionsApply或b)搜索特定的字符串/代码段始终是一个好主意.

块加载在很大程度上取决于给定的target,因为每种环境需要不同的实现. Webpack允许您定义自定义目标.当您传入函数而不是字符串时,webpack会使用编译器实例调用该函数.在那里,您可以应用所有必需的插件.由于我们的自定义目标几乎就像Web目标一样,因此我们只复制Web目标中的所有内容:

// webpack.config.js

const NodeSourcePlugin = require("webpack/lib/node/NodeSourcePlugin");
const FunctionModulePlugin = require("webpack/lib/FunctionModulePlugin");
const LoaderTargetPlugin = require("webpack/lib/LoaderTargetPlugin");
const JsonpChunkTemplatePlugin = require("webpack/lib/JsonpChunkTemplatePlugin");
const JsonpHotUpdateChunkTemplatePlugin = require("webpack/lib/JsonpHotUpdateChunkTemplatePlugin");

function customTarget(compiler) {
    compiler.apply(
        new JsonpTemplatePlugin(compiler.options.output),
        new FunctionModulePlugin(compiler.options.output),
        new NodeSourcePlugin(compiler.options.node),
        new LoaderTargetPlugin("web")
    );
}

module.exports = {
    entry:  require.resolve("./app/main.js"),
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "bundle.js"
    },
    target: customTarget
};

如果看一下每个插件,您将认识到JsonpTemplatePlugin负责加载块.因此,让我们用自己的实现代替它.我们称它为XHRTemplatePlugin:

function customTarget(compiler) {
    compiler.apply(
        new XHRTemplatePlugin(compiler.options.output),
        new FunctionModulePlugin(compiler.options.output),
        new NodeSourcePlugin(compiler.options.node),
        new LoaderTargetPlugin("my-custom-target")
    );
}

我们的XHRTemplatePlugin负责在主块,每个子块中以及热更新中提供代码:

function XHRTemplatePlugin() {}

XHRTemplatePlugin.prototype.apply = function (compiler) {
    compiler.plugin("this-compilation", function(compilation) {
        compilation.mainTemplate.apply(new XHRMainTemplatePlugin());
        compilation.chunkTemplate.apply(new XHRChunkTemplatePlugin());
        compilation.hotUpdateChunkTemplate.apply(new XHRHotUpdateChunkTemplatePlugin());
    });
};

也许,您也可以重复使用JsonpChunkTemplatePlugin和JsonpHotUpdateChunkTemplatePlugin插件,但这取决于您的用例/实现.

您的XHRMainTemplatePlugin现在看起来可能像这样:

function XHRMainTemplatePlugin() {}

XHRMainTemplatePlugin.prototype.apply = function (mainTemplate) {
    mainTemplate.plugin("require-ensure", function(_, chunk, hash) {
        return this.asString([
            // Add your custom implementation here
            "fetch()"
        ]);
    });
};

我在这里不再赘述,因为我认为这个答案已经足够长了.但是我建议创建一个真正的小示例项目,并检查webpack创建的输出.乍一看,内部的webpack插件可能看起来有些吓人,但是大多数插件确实很短,只做一件事.您也可以从中获得一些启发.

转载注明原文:javascript-是否可以让webpacks System.import使用ajax(用于进度事件)? - 代码日志