如何动态创建应该包含在webpack包中的新文件?

时间:2016-10-16 11:11:53

标签: webpack

我想用自定义中间件或加载程序修改我的webpack配置,它可以帮助我:

  • 查找所有src/**/*.srv.js
  • 创建或更新以下文件:
    • 进口他们
    • 将它们导出到对象中 (导出默认值{x,y,z等})
    • 在捆绑包中添加新文件,以便我可以在main.js
    • 中轻松使用它们

这是我实际需要的简化用例,但如果我知道如何做到这一点,我可以自己解决其余问题。

有什么想法吗?

3 个答案:

答案 0 :(得分:0)

我认为没有 webpack 方式来执行您所描述的内容。但是,您似乎可以通过shell脚本轻松地执行此操作,可能使用npm脚本。

我在工作中有类似的用例:我们使用font-custom将Sass mixins生成为(.gitignore' d文件)_generated-font.scss文件(来自SVG目录)文件),然后从版本化的Sass文件导入_generated-font.scss,然后由webpack的sass-loader选择。

这显然必须在webpack运行之前发生,所以我们通过prestart npm脚本运行它。

我希望我足够清楚 - 让我知道其他情况:)。

答案 1 :(得分:0)

所以我提出了一个我认为足够好的解决方案。

首先,我通过在脚本启动时运行的插件清理/创建文件。然后我发现加载器可以使用this.resourcePath查看当前处理文件的文件路径,所以我只是让preload中的加载器将import / export语句插入到我刚刚创建的新文件中。

此文件包含在我的主文件中。奇迹般有效。 ...但它不严格在内存中,它不处理删除/重命名的文件。但足够接近!

此处的示例代码: https://github.com/presidenten/vuex-automator-loader

答案 2 :(得分:0)

这是超级晚了,但是如果其他人落在这里,我认为解决此问题的最佳方法是为每个srv.js文件生成一个单独的资产,这可以通过一个简单的加载器{{3 }}。然后,您可以像使用其他CSS或JS文件一样在html中使用这些资产。

但是,如果您真的只想生成单个资产,则可以这样做:

  1. 创建一个将函数注入加载程序上下文的插件,以便加载程序可以将信息传递回该插件(like so
  2. srv.js文件创建一个加载器,以提取数据并将其从步骤1传递到插件。
  3. 使用第1步中使用的相同插件,汇总来自加载程序的所有数据并生成一个资产文件(more info

一些粗略的代码来显示我的意思:

插件

class MyPlugin {
    apply(compiler) {
        var allData = "";

        // inject a function to loaderContext so loaders can pass back info
        compiler.hooks.compilation.tap('MyPlugin', compilation =>
            compilation.hooks.normalModuleLoader.tap(
                'MyPlugin',
                (loaderContext, module) => {
                    loaderContext.myExportFn = (data) => {
                        allData += data;
                    }
                }
            )
        );

        // at the end, generate an asset using the data
        compiler.hooks.emit.tapAsync(
            'MyPlugin',
            (compilation, callback) => {
                compilation.assets['myfile.js'] = {
                    source: () => allData,
                    size: () => allData.length
                };
                callback();
            }
        );
    }
}

加载程序

module.exports = function(content) {
    // use the injected function, pass back some data
    this.myExportFn(`loader called for filepath: ${this.resourcePath}`);
    return content; // return the source file unchanged
};