如何手动触发webpack dev服务器的watch / reload?

问题描述 投票:1回答:2

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

我有一个基本的TypeScript / Scss应用程序,所有src文件都存在于src目录中。我还有一个组件库包,它通过一个单独的构建过程(通过Node触发)动态生成。这个包也最终出现在src目录中(它包含一些sass变量和一些属于src的其他资产)。这是src/custom-library-bundle。我当前的webpack设置通过public将相应的包文件移动到CopyWebpackPlugin(dist)目录。我的webpack dev服务器按预期监视更改和重新加载。这一切都很美妙。

现在为扭曲。我已经在其他地方设置了一个自定义观察程序来监视自定义组件库包的更改。当在那里发生更改时,它会触发上面提到的自定义构建过程。这(如预期的那样)修改了src/custom-library-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服务器在我的自定义手表回调中做它的事情;让它忽略src/custom-library-bundle,直到我告诉它要注意。但是,我似乎找不到办法做到这一点。这可能吗?

替代方法#1:我可以忽略src/custom-library-bundle目录,将更新的文件移动到public(不使用webpack方法),然后在我知道完成时触发重新加载。我不喜欢这个因为我想利用相同的过程,无论是我正在观看还是仅仅进行一次性构建(我希望所有内容最终都在public目录中,因为webpack完成了这项工作,不是因为我写了一个脚本把它放在特定情况下)。但是,让我说我克服了这个问题,如何为开发服务器触发浏览器重新加载?这可能吗?

替代方法#2这是我倾向于的,但感觉就像额外的,不必要的工作。我可以将自定义构建过程输出到另一个目录(我的webpack设置的目录根本不关心)。一旦构建过程完成,我可以将所有文件移动到src/custom-library-bundle,其中手表将获取1个更改并执行单个复杂/重新加载。这让我如此接近,但感觉我正在添加一个我不想要的步骤。

替代方法#3?你能想出一个更好的解决方法吗?

更新(包括版本):

  • webpack 4.26.1
  • webpack-dev-server 3.1.14
javascript webpack webpack-dev-server
2个回答
1
投票

想到webpack提供的有用的东西是multi-compiler构建,从CompilerCompilation实例创建子编译器,DllPlugin并通过调用webpack.watch()webpack.compile()以编程方式管理编译器。

  • 当您希望在单个运行中构建多个编译时,多编译器设置非常有用,这些编译的输出彼此独立
  • 子编译器允许您在编译器之间设置依赖关系并使用钩子,它们允许您阻止父级,直到子编译完成将最新的bundle发送到资产中
  • DllPlugin允许您创建一个编译,它的清单可以生成可以包含模块的块,这些模块可以用作尚未构建的编译的依赖项(清单需要预先生成并传递给它们)
  • 以编程方式管理编译器允许您编写一个简单的Node.js脚本,该脚本可以手动完成大部分操作。

如果我理解正确,你的webpack编译器除了期望它有一些东西添加到输出资产之外,对你的bundle没有任何依赖,所以你可以考虑做一个多编译器构建。如果这对您不起作用,您可以编写一个简单的插件来创建一个子编译器,该子编译器监视所有组件包依赖关系,并在更改时将构建的bundle发送到主编译资产中。最后,正如您自己提到的,您可以编写一个简单的脚本并以编程方式将所有内容编织在一起。所有这些方法卸载跟踪构建了对webpack的依赖关系,因此如果您将编译器置于监视模式,webpack将跟踪何时需要更新的内容。

如果您有兴趣仔细研究如何创建和使用子编译器,我衷心建议您阅读html-webpack-plugin插件的来源。看起来这个插件似乎并没有像你一样处理相同类型的构建设置,但值得注意的是,HTML插件可以处理不属于构建依赖项的文件(源代码中没有任何内容或依赖于用于创建添加到输出的HTML文件的文件/模板。


1
投票

将以下server.sockWrite调用添加到after方法:

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的核心开发者之一在a comment on GitHub中提到过它,所以它有点受到制裁。

© www.soinside.com 2019 - 2024. All rights reserved.