繁体   English   中英

在 Visual Studio 的预构建中使用 webpack

[英]Using webpack in Visual Studio's pre-build

我有两个命令:

npm run build - 调用webpack来编译我所有的 .js

npm run dev - 调用webpack -w ,编译我所有的 .js 并保持监视模式,寻找变化。

我想将它与 Visual Studio 的构建集成,所以我进入了 Properties -> Build Events -> Pre-build

if $(ConfigurationName) == Debug (
  npm --prefix ../ run dev
) ELSE (
  npm --prefix ../ run build
)

这个逻辑有效。 如果我处于发布模式,它将简单地捆绑我的文件并且服务器将运行。 但问题是在调试模式下,因为webpack -w没有结束,构建也永远不会结束,它期待一个退出代码......

所以我试图超越 Visual Studio 并启动一个不会阻止构建启动的新 cmd 进程:

start cmd /K npm --prefix ../ run dev

不幸的是,Visual Studio 对我来说太聪明了。

所以问题是:有没有什么聪明的方法可以让 Visual Studio 简单地在预构建命令中运行我想要的东西而不是等待它完成?

我知道这个叫做 task runner 的地方有一个合适的地方,但我无法正确配置它,它无法识别来自我的 package.json 的任何命令。 此外,我不想在运行我的服务器之后/之前手动激活它,理想情况下我希望它与服务器启动集成,这就是我进行预构建的原因。 但如果有更聪明的方法来做到这一点,请随时指出我。

提前致谢。

要回答这个问题:

所以问题是:有没有什么聪明的方法可以让 Visual Studio 简单地在预构建命令中运行我想要的东西而不是等待它完成?

答案是肯定的,我想出了一个聪明的方法。

在您的预构建脚本中,您需要使用 NodeJS 来生成一个未连接到其父进程的新进程。 你会这样称呼:

node spawner.js fork \"npm --prefix ../ run dev\"

然后你需要项目根目录中的spawner.js脚本

 /**
 * Spawns a new forked child process
 *
 * The process.argv property returns an array containing the command line arguments
 * passed when the Node.js process was launched. The first element will be process.execPath.
 * See process.argv0 if access to the original value of argv[0] is needed. The second element
 * will be the path to the JavaScript file being executed. The remaining elements will be any
 * additional command line arguments.
 * See: https://nodejs.org/docs/latest/api/process.html#process_process_argv
 *
 */


/**
 * Function: run()
 * This method runs the command using child_proces.exec only
 * Does the same as function fork(), but in a different implementation.
 */
module.exports = {


   /**
    * Function: fork()
    * This method runs the command using child_proces.fork and child_process.exec
    * Does the same as function run(), but in a different implementation.
    * Forks a new NodeJS process of the same codebase in a new V8 instance.
    */
   fork: function (command) {

      console.log('Begin Forking New Process');
      console.log(command);

      var cp = require('child_process');
      var child = cp.fork('./forked-child.js', [command]);

      /**
       * child.unref()
       * Causes the parent's (this) event loop to not include the child (spawned-child.js)
       * in its reference count, allowing the parent to exit independently of the child,
       * unless there is an established IPC channel between the child and parent.
       */
      child.unref();

   },

   runTsNode: function (command) {

      console.log('Begin Running ts-node Script');

      require('child_process').exec(
         // terminating command prompt is /c - persistent command prompt is /k
         'ts-node ' + command + '"',
         function () {
            console.log('Received Command: ' + command);
         });

      /**
       * Debug the arguments received on command line.
       */
      var args = process.argv.slice(2);
      args.forEach((val, index) => {
         console.log(`${index}: ${val}`);
      });

      /**
       * Kill the child process after 2 seconds, once the detached cmd.exe process has spawned
       */
      setTimeout(function () {
         console.log('Done Spawning');
         process.exit(0);
      }, 2000);

   },

   runNode: function (command) {

      console.log('Begin Running Node Script');

      require('child_process').exec(
         // terminating command prompt is /c - persistent command prompt is /k
         'node ' + command + '"',
         function () {
            console.log('Received Command: ' + command);
         });

      /**
       * Debug the arguments received on command line.
       */
      var args = process.argv.slice(2);
      args.forEach((val, index) => {
         console.log(`${index}: ${val}`);
      });

      /**
       * Kill the child process after 2 seconds, once the detached cmd.exe process has spawned
       */
      setTimeout(function () {
         console.log('Done Spawning');
         process.exit(0);
      }, 2000);

   },

   runCommand: function (command) {

      console.log('Begin Running Command Line Script');

      require('child_process').exec(
         // terminating command prompt is /c - persistent command prompt is /k
         'cmd.exe @cmd /k "' + command + '"',
         function () {
            console.log('Received Command: ' + command);
         });

      /**
       * Debug the arguments received on command line.
       */
      var args = process.argv.slice(2);
      args.forEach((val, index) => {
         console.log(`${index}: ${val}`);
      });

      /**
       * Kill the child process after 2 seconds, once the detached cmd.exe process has spawned
       */
      setTimeout(function () {
         console.log('Done Spawning');
         process.exit(0);
      }, 2000);

   },


};

require('make-runnable'); // must be at the END of the file

它需要make-runnable所以确保运行npm i make-runnable -D

spawner.js ,这个脚本使用forked-child.js ,它也应该放在你的项目根目录中。

 /**
 * Spawns a new forked child process
 *
 * The process.argv property returns an array containing the command line arguments
 * passed when the Node.js process was launched. The first element will be process.execPath.
 * See process.argv0 if access to the original value of argv[0] is needed. The second element
 * will be the path to the JavaScript file being executed. The remaining elements will be any
 * additional command line arguments.
 * See: https://nodejs.org/docs/latest/api/process.html#process_process_argv
 *
 */

// Window only until its updated for cross platform
require('child_process')
// terminating command prompt is /c - persistent command prompt is /k
   .exec('start cmd.exe @cmd /k "' + process.argv[2] + '"',
      function () {
         console.log('Received Command: ' + process.argv[2]);
      });


/**
 * Debug the arguments received on command line.
 */
process.argv.forEach((val, index) => {
   console.log(`${index}: ${val}`);
});

/**
 * Kill the child process after 2 seconds, once the detached cmd.exe process has spawned
 */
setTimeout(function () {
   console.log('Done Spawning');
   process.exit(0);
}, 2000);

我在 spanwer.js 脚本中包含了其他可能有用的方法。 对于这个例子,它调用了fork方法。

现在只需运行您的构建,它应该会执行

  1. node spawner.js fork \\"npm --prefix ../ run dev\\" ,它调用
  2. forked-child.js ,它接收你的命令作为参数和
  3. 在新的分离进程中打开它

因为它是通过分叉与其父级分离的,所以即使在其自己的永无止境的终端实例中运行时,Visual Studio 的构建过程也将继续运行。

这就是我使用 webpack-dev-server 和 Visual Studio 解决这个确切问题的方法。 我希望这有帮助。

我最近遇到了类似的情况,在调试模式下构建我的项目后,我想在监视模式下运行 Webpack。 我遇到了同样的问题,当我运行我的项目时,预构建步骤会无限期地挂起。

我想出了以下解决方案,它通过打开一个单独的 cmd 窗口来运行 .bat 文件,该窗口不会阻止构建完成并且像魅力一样工作。

第 1 步- 在项目的根目录中创建一个 .bat 文件,我使用以下代码调用了这个 WebpackWatch.bat,这将运行 webpack 并在打开的 cmd 窗口中将其置于监视模式

webpack --progress --profile --watch --mode development

第 2 步- 在构建后事件中,我添加了以下内容,这将运行 powershell 命令打开 .bat 文件,然后继续构建,对于发布模式,它在我的包中调用脚本 build:prod配置

if $(ConfigurationName) == Debug powershell start-process $(ProjectDir)WebpackWatch.bat
if $(ConfigurationName) == Release npm run build:prod

出于信息目的,我的 package.json 文件具有以下用于发布构建事件的脚本,注意这在构建过程中没有 --watch ,因此这会使用构建步骤完成文件。

 "scripts": {
    "build:prod": "webpack --progress --profile --mode production"
  },

cd [基于bin文件夹的WebPack Package.json路径] npx webpack

我实际上想出了一种使用预构建命令来做到这一点的方法。 您可以在 Visual Studio 中启动应用程序的同时启动 webpack,而无需等待命令完成。

你可以使用

powershell start-process "cmd ""/K npm run start"""

例如,这是我在 ASP.Net MVC 5 项目属性下的 Build Events 中的预构建事件命令行:

cd "$(ProjectDir)React"
if $(ConfigurationName) == Debug (
  call npm run build-dev
  powershell start-process "cmd ""/K npm run start"""
)
if $(ConfigurationName) == Release (
  call npm run build-prod
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM