如何手动触发Webpack开发服务器的监视/重新加载?

时间:2018-12-28 18:39:28

标签: javascript webpack webpack-dev-server

我有一个相当简单的webpack,但有些曲折。我可以通过几种不同的方式来创建自己的预期行为,但是我想知道是否有更好的方法(对于Webpack,我还是很陌生)。

我有一个基本的TypeScript / Scss应用程序,所有src文件都位于src目录中。我还有一个组件库捆绑包,它是通过一个单独的构建过程(通过Node触发)动态生成的。该捆绑软件还以src目录结尾(它包含一些sass变量和一些属于src的其他资产)。这是src/custom-library-bundle。我当前的Webpack设置通过public将适当的分发包文件移动到CopyWebpackPlugin(dist)目录。我的webpack开发服务器监视更改并按预期重新加载。这一切都很漂亮。

现在开始扭转。我已经建立了一个自定义监视程序,该监视程序存在于其他地方,以监视自定义组件库捆绑更改。当在那里发生更改时,它将触发上述自定义构建过程。如预期的那样,此操作将修改src/custom-library-bundle目录,并在填充分发包时触发几次监视/重新加载。技术上可行吗?行为是可以预期的,但是理想情况下,我可以告诉它等到自定义安装工作“完成”并且只有 then 使其触发编译/重新加载。

Ph。这不是一个容易解释的人。这是一个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开发服务器以在自定义监视回调中执行其操作;让它忽略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

2 个答案:

答案 0 :(得分:1)

webpack提供的有用功能包括multi-compiler构建,从CompilerCompilation实例,DllPlugin创建子编译器,以及以编程方式管理编译器通过调用webpack.watch()webpack.compile()

  • 当您要在一次运行中构建多个编译且输出彼此独立的编译器时,多编译器设置很有用
  • 子编译器允许您在 编译器并使用钩子,它们使您可以阻止父级,直到 例如,子编译完成了将最新的捆绑包发送到 资产
  • DllPlugin允许您创建一个汇编并 它的清单可能会产生可以包含模块的块 可以用作尚未编译的依赖文件(清单 需要事先制作并传递给他们)
  • 以编程方式 管理编译器使您可以编写简单的Node.js脚本 可以手动完成大部分操作。

如果我理解正确,除了期望软件包添加到输出资产中之外,您的webpack编译器实际上并没有任何依赖,因此您可以考虑进行多编译器构建。如果这对您不起作用,您可以编写一个简单的插件,该插件创建一个子编译器,该子编译器监视所有组件捆绑包依赖性,并在更改时将构建的捆绑包释放到主编译资产中。最终,正如您提到的那样,您可以编写一个简单的脚本,然后以编程方式将所有内容编织在一起。所有这些方法都可以卸载跟踪对webpack的构建依赖关系,因此,如果将编译器置于监视模式,则webpack将在需要更新某些内容时跟踪。

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

答案 1 :(得分:0)

将以下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中提到了这一点,因此受到了认可。