Webpack 子编译器更改配置

2024-05-14

我希望在编译我的服务工作人员时将我的 webpack 构建的输出定义为变量。

我想使用子编译功能来编译放入不同路径的服务工作人员。我需要 webpack 编译发出的输出来正确编译服务工作线程。

我最初的做法是使用与离线插件相同的策略,在其中创建子编译器,但我需要能够更改服务工作线程的输出路径。服务工作者路径很重要,因为它定义了范围。

我想知道如何使用子编译器 API 来完成下面的任务,以防止我的构建出现这种副作用(希望它能给我 webpack-dev-server 支持。

var webpack = require('webpack');

function ServiceWorkerPlugin(options) {
    this.options = options;
}

ServiceWorkerPlugin.prototype.apply = function(compiler) {
    compiler.plugin('emit', (compilation, callback) => {
    const stats = compilation.getStats().toJson();
    const child = webpack(this.options);

    child.apply(
    new webpack.DefinePlugin({
    assets: stats.assets
  })
);

child.run((err, swStats) => {
     if (err) {
         callback(err);
     }
     const swStatsJson = swStats.toJson();

     if(swStatsJson.errors.length > 0) {
         console.log(swStatsJson.errors);
     }

     if(swStatsJson.warnings.length > 0) {
         console.log(swStatsJson.warnings);
     }

     callback();
});

module.exports = ServiceWorkerPlugin;

首先,您所描述的一切都在offline-plugin实施,所以现在我将向您展示我是如何做到的。

当你需要使用 webpack 时,一切都变得有点棘手儿童汇编 and compilation.assets在里面。问题是儿童汇编必须创建于complier.plugin('make')事件,但是compilation.assets仅适用于compiler.plugin('emit')几乎在编译结束时触发的事件。

这是一种样板儿童汇编执行:

(注:代码为ES2015版本)

import SingleEntryPlugin from 'webpack/lib/SingleEntryPlugin';

export default class AwesomePlugin {
  constructor() {
    // Define compilation name and output name
    this.childCompilerName = 'awesome-plugin-compilation';
    this.outputFileName = 'custom-file.js';
    // To make child compiler work, you have to have a entry in the file system
    this.compilationEntry = 'entry-file.js';
  }

  apply(compiler) {
    // Listen to `make` event
    compiler.plugin('make', (compilation, callback) => {
      // Creating child compiler with params
      const childCompiler = compilation.createChildCompiler(this.childCompilerName, {
        filename: this.outputFileName
      });

      // Everyone plugin does this, I don't know why
      childCompiler.context = compiler.context;

      // Add SingleEntryPlugin to make all this work
      childCompiler.apply(new SingleEntryPlugin(compiler.context, this.compilationEntry, this.outputFileName));

      // Needed for HMR. Even if your plugin don't support HMR,
      // this code seems to be always needed just in case to prevent possible errors
      childCompiler.plugin('compilation', (compilation) => {
        if (compilation.cache) {
          if (!compilation.cache[name]) {
            compilation.cache[name] = {};
          }

          compilation.cache = compilation.cache[name];
        }
      });

      // Run child compilation
      childCompiler.runAsChild((err, entries, childCompilation) => {
        callback(err);
      });
    });
  }
}

这将使您的条目编译成单独的文件,您可以根据需要命名该文件。接下来,您需要进行一些 hacky 操作compilation.assets on 'emit' event:

compiler.plugin('emit', function(compilation, callback) {
  // Get our output asset
  const asset = compilation.assets[this.outputFileName];

  // Delete delete our asset from output
  delete compilation.assets[this.outputFileName];

  // Collect all output assets
  const assets = Object.keys(compilation.assets);

  // Combine collected assets and child compilation output into new source.
  // Note: `globalAssets` is global variable
  let source = `
    var globalAssets = ${ JSON.stringify(assets) }

    ${ asset.source() }
  `;

  // Add out asset back to the output
  compilation.assets[this.outputFileName] = {
    source() {
      return source;
    },
    size() {
      return Buffer.byteLength(source, 'utf8');
    }
  };
});

EDIT:您可能可以在要插入资产列表的条目中找到一些特殊的位置。但要小心,如果您使用常规模板语法,那么 JS 加载器将无法解析您的文件。所以你可以放置这样的东西__INSERT_WEBPACK_ASSETS_DATA__然后使用String#replace将其替换为实际数据。

基本上就是这样了。现在你应该能够注入变量compilation.assets进入你的儿童汇编输出。请注意,在offline-plugin, I use fake我创建它时的编译名称,然后将其重命名为'emit'事件到真实的文件名。我不记得具体原因,但我记得我有它们。因此,您可能需要亲自尝试一下。

这是该样板的完整代码(同时包含'make' and 'emit'事件):https://gist.github.com/NekR/f85d297fe4f1ea3c168827b305c13844 https://gist.github.com/NekR/f85d297fe4f1ea3c168827b305c13844

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Webpack 子编译器更改配置 的相关文章

随机推荐

  • 在 NFC 标签扫描期间,onNewIntent() 内的intent.getAction() 为 null

    这是我第一次使用 NFC 标签 我在清单中声明了 NFC 扫描活动
  • 更新 conda 后 conda 环境损坏

    在广泛使用 conda 一段时间后 我昨天被要求更新它 现在事情看起来很糟糕 我必须承认我不是幕后发生的专家 所以请耐心等待 安装 conda 后我使用了pip安装各种软件包 昨天 我开始处理 git 教程中的一些代码 该教程建议创建一个临
  • 在 ASP.NET 中使用 AjaxControlToolkit 的异步 AJAXFileUpload 控件返回数据

    我正在使用上面的控件 注意它是 ASP NET 控件 我似乎看到很多人使用用 javascript 编写的类似名称的控件 来允许使用进度条 拖放操作来上传多个文件 该部分一切正常 但我需要随文件返回两条数据 具体来说 用户从两个文本框中输入
  • Guzzle 中的“并发”到底是什么?

    我没有找到太多关于concurrency选项中Pool 如果这是可以在服务器上打开的 TCP 套接字数量 那么问题是 我可以使用多少并发来更快地处理请求 我有这个使用的例子Pool I am using Laravel this is ba
  • 检查子字符串是否在字符串列表中?

    我之前已经找到了这个问题的一些答案 但它们对于当前的Python版本来说似乎已经过时了 或者至少它们对我不起作用 我想检查字符串列表中是否包含子字符串 我只需要布尔结果 我找到了这个解决方案 word to check or wordlis
  • Python函数组成

    我尝试使用良好的语法来实现函数组合 这就是我所得到的 from functools import partial class compfunc partial def lshift self y f lambda args kwargs s
  • 如何在 swift 中以编程方式使用坐标打开地图应用程序?

    我想在地图应用程序中打开纬度和经度 我尝试了这段代码HERE https stackoverflow com questions 12504294 programmatically open maps app in ios 6 func g
  • 在 PhotoImage 下调整图像大小

    我需要调整图像大小 但我想避免使用 PIL 因为我无法使其在 OS X 下工作 不要问我为什么 无论如何 因为我对 gif pgm ppm 感到满意 所以 PhotoImage 类对我来说没问题 photoImg PhotoImage fi
  • 将 C# 字符串传递给非托管 C++ DLL

    我有一个简单的应用程序 它加载一个非托管 dll 并从 C 向它传递一些字符串值 但在 C dll 应用程序中 我收到异常 试图访问读 写保护的内存 我的 DLL 导入如下所示 DllImport X dll CallingConventi
  • 如何将数据库查询的行转换为 XML 文件?

    我正在开发一个 Delphi 应用程序 该应用程序需要从一段工作中获取行并将其转换为单个 XML 文件 以便上传到第三方 Web 服务 有没有可用的组件或库可以做到这一点 如果不是 那么构建 DB2XML 转换器的最佳代码方法是什么 我注意
  • 将相同匹配模式的连续 2 行放入单行中

    我想解析这组行 以便如果得到相同的模式 例如 lt email protected cdn cgi l email protection gt 在连续的行中 它应该以单行形式打印 并在两行之间使用 q2VDWKkY010407 222187
  • MatAutocomplete 值 X 显示

    我的自动完成显示具有以下定义的对象的值 export class Person id number name string cityName string 这是自动完成模板
  • 具有子集合成员条件的 NHibernate 查询仅返回部分子集合

    我与以下人员之间存在亲子关系Teacher and StudentReport Each StudentReport有一个时间戳字段记录老师完成报告的时间 我有一个查询 要查找截至某一分钟前已完成一份或多份报告的所有教师 public IL
  • 线程池,C++

    我正在使用 C 开发一个网络程序 我想实现一个 pthread 池 每当我从接收套接字接收到一个事件时 我都会将数据放入线程池中的队列中 我正在考虑创建 5 个独立的线程 并将持续检查队列以查看是否有任何传入数据需要完成 这是一个非常简单的
  • 在 C# 中创建一副纸牌

    因此 我正在尝试为我的一个编程课程创建一副纸牌 我从来没有真正做过这样的事情 如果我犯了一些愚蠢的错误 我很抱歉 我正在 Visual Studio 中对此进行编码 按照类规则 我正在尝试为我的 Deck 创建一系列 Card 对象 我遇到
  • 多 AVL 树旋转

    假设我有一个无序集合 s 3 6 5 1 2 4 并且我需要构造一个 AVL 树 就这么多了 我了解基本的旋转 我在这里达到这一点 5 2 6 1 3 但当我尝试插入 4 时 一切都崩溃了 我得到的最终答案是 左边的 4 But the a
  • iPhone OS 3.0.1 会毁掉你的开发手机吗?

    我将手机更新到3 0 1 虽然手机作为手机工作正常 xcode http en wikipedia org wiki Xcode组织者不再知道手机的名称 它还说这个版本的 xcode 不支持 3 0 1 我下载了最新版本的xcode和操作系
  • 使用把手显示来自 parse.com 的 json 响应

    我想将 json 响应传递给车把 我已经查看了解析文档和 stackoverflow 问题 但我似乎无法弄清楚这一点 这是回应 results address 755 W Yale createdAt 2013 02 09T01 12 15
  • 开源 EDA 项目

    您知道 EDA 电子设计自动化 领域有哪些开源项目正在寻找 C 程序员吗 如果您经常关注 gEDA 的邮件列表 您也许能够加入 gEDA 细节 http www gpleda org developer html http www gple
  • Webpack 子编译器更改配置

    我希望在编译我的服务工作人员时将我的 webpack 构建的输出定义为变量 我想使用子编译功能来编译放入不同路径的服务工作人员 我需要 webpack 编译发出的输出来正确编译服务工作线程 我最初的做法是使用与离线插件相同的策略 在其中创建