如何手动触发Webpack Dev Server的监视/重新加载?

4

我有一个相当简单的webpack设置,但是有一点不同。我可以想到几种不同的方法来创建我的预期行为,但我想知道是否有更好的方法(我对webpack还比较陌生)。

我有一个基本的TypeScript/Scss应用程序,所有的src文件都存在于src目录中。我还有一个组件库捆绑包,通过单独的构建过程(通过Node触发)动态生成。这个捆绑包也以src的形式结束(它包含一些Sass变量和一些其他属于 src 的资源)。这是src/custom-library-bundle。我当前的webpack设置使用CopyWebpackPlugin将适当的bundle文件移动到public(dist)目录中。我的webpack开发服务器会监视变化并按预期重新加载。这一切都运作得非常好。

现在来看这个变化。我已经设置了一个自定义的watcher以便在别处监视自定义组件库的捆绑包变化。当那里发生变化时,它会触发上面提到的定制build过程。这个过程(正如预期的那样)修改了src/custom-library-bundle目录,并启动了多个监视器/重新加载器,因为bundle正在填充。在技术上它是工作的?行为也是预期的,但理想情况下,我希望能够告诉它等到自定义安装工作“完成”,然后才触发编译/重新加载。

哇,这不是一个容易解释的问题。以下是一个webpack配置,希望能够更清晰地说明:

devServer: {
  contentBase: path.join(__dirname, 'public'),
  port: 9000,
  host: '127.0.0.1',
  after: (app, server) => {
    new MyCustomWatcherForOtherThings().watch(() => {
      // invoked after the src/custom-library-bundle is done doing its thing (each time)
      // now that I know it's done, I want to trigger the normal compilation/reload
    })
  },
  watchOptions: {
    ignored: [
      /node_modules/
      // I've been experimenting with the ignored feature a bit
      // path.resolve(__dirname, 'src/custom-library-bundle/')
    ]
  }
}

最理想的方法:在我最理想的情况下,我希望只需手动触发webpack dev server在我的自定义监视回调中执行其操作;直到我告诉它注意为止,它可以忽略src/custom-library-bundle。然而,我似乎找不到这样的方法。这可能吗?

备选方案#1:我可以忽略src/custom-library-bundle目录,将更新的文件移动到public(不使用webpack方法),然后当我知道完成时仅触发重新加载。我不喜欢这个方案,因为我希望无论是监视还是进行一次性构建都能使用相同的流程(我希望所有内容最终都出现在public目录中,因为webpack完成了这项工作,而不是因为我编写脚本在特定情况下将其放置在那里)。但是,假设我克服了这个问题,如何为dev server触发浏览器重新加载?这可能吗?

备选方案#2:这是我倾向于的方法,但感觉额外且不必要。我可以使我的自定义构建过程输出到另一个目录中(一个我的webpack设置完全不关心的目录)。一旦构建过程完成,我可以将所有文件移动到src/custom-library-bundle,其中监视会检测到1个更改并进行单个编译/重新加载。这让我非常接近,但感觉添加了一个我不想要的步骤。

备选方案#3?你能想到更好的方法解决这个问题吗?

更新(包括版本):

  • webpack 4.26.1
  • webpack-dev-server 3.1.14
2个回答

11
在你的after方法中添加以下server.sockWrite调用:
devServer: {
  after: (app, server) => {
    new MyCustomWatcherForOtherThings().watch(() => {
      // invoked after the src/custom-library-bundle is done doing its thing (each time)
      // now that I know it's done, I want to trigger the normal compilation/reload

      // calling this on `server` triggers a full page refresh
      server.sockWrite(server.sockets, "content-changed");
    });
  };
}

我从未在文档中找到过这个,但webpack的核心开发人员之一在GitHub上的评论中提到了它,所以它有一定的认可。


1

我能想到的webpack提供的有用功能包括多编译器构建、从CompilerCompilation实例创建子编译器、DllPlugin和通过调用webpack.watch()webpack.compile()来以编程方式管理编译器。

多编译器设置在您想要在单次运行中构建多个编译,其输出彼此独立时非常有用。 子编译器允许您在编译器之间设置依赖关系,并使用钩子阻止父级,直到子编译完成将最新的包发送到资产为止。 DllPlugin允许您创建一个编译及其清单,该清单可以生成包含模块的块,这些模块可以用作尚未构建的编译的依赖项(需要先生成清单并将其传递给它们)。 以编程方式管理编译器使您能够编写一个简单的Node.js脚本,手动完成大部分工作。
如果我理解正确的话,您的webpack编译器实际上并没有任何依赖于您的捆绑包,除了期望将某些内容添加到输出资产之外,因此您可以考虑进行多编译器构建。 如果这对您不起作用,您可以编写一个简单的插件,创建一个子编译器来监视所有组件包依赖项,并在更改时将构建的包发出到主编译资产中。 最终,正如您自己提到的那样,您可以编写一个简单的脚本并以编程方式将所有内容编织在一起。 所有这些方法都将构建依赖关系跟踪卸载到webpack,因此如果将编译器放入观察模式,webpack将跟踪需要更新的内容。
如果您有兴趣更仔细地查看如何创建和使用子编译器,我强烈建议阅读html-webpack-plugin插件的源代码。 看起来该插件处理的不是与您的构建设置相同类型的内容,但值得注意的是HTML插件可以处理不属于构建依赖项的文件(源中没有任何内容引用或依赖于用于创建添加到输出的HTML文件的文件/模板)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接