简体   繁体   English

在 Visual Studio 的预构建中使用 webpack

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

I have two commands:我有两个命令:

npm run build - calls webpack to compile all my .js npm run build - 调用webpack来编译我所有的 .js

npm run dev - calls webpack -w , compiles all my .js and stays in watch mode, looking for changes. npm run dev - 调用webpack -w ,编译我所有的 .js 并保持监视模式,寻找变化。

I want to integrate it with Visual Studio's build, so I went into Properties -> Build Events -> Pre-build我想将它与 Visual Studio 的构建集成,所以我进入了 Properties -> Build Events -> Pre-build

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

This logic works.这个逻辑有效。 If I'm at release mode, it will simple bundle my files and the server will run.如果我处于发布模式,它将简单地捆绑我的文件并且服务器将运行。 But the problem is at debug mode, since the webpack -w doesn't end, the build also never ends, it's expecting an exit code....但问题是在调试模式下,因为webpack -w没有结束,构建也永远不会结束,它期待一个退出代码......

So I tried to outsmart Visual Studio and start a new cmd process that would not block the build's start:所以我试图超越 Visual Studio 并启动一个不会阻止构建启动的新 cmd 进程:

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

Unfortunately, Visual Studio is too smart for me.不幸的是,Visual Studio 对我来说太聪明了。

So the question is: is there any smart way to make the visual studio simply run what I want in the pre-build command and not wait for it to finish?所以问题是:有没有什么聪明的方法可以让 Visual Studio 简单地在预构建命令中运行我想要的东西而不是等待它完成?

I know there's a proper place for this called task runner, but I couldn't configure it properly, it doesn't recognize any commands from my package.json.我知道这个叫做 task runner 的地方有一个合适的地方,但我无法正确配置它,它无法识别来自我的 package.json 的任何命令。 Also, I don't want to active it manually after/before running my server, ideally I want it to be integrated with the server startup so that's why I went for the pre-build.此外,我不想在运行我的服务器之后/之前手动激活它,理想情况下我希望它与服务器启动集成,这就是我进行预构建的原因。 But if there's a smarter way to do this, feel free to point it to me.但如果有更聪明的方法来做到这一点,请随时指出我。

Thanks in advance.提前致谢。

To answer this question:要回答这个问题:

So the question is: is there any smart way to make the visual studio simply run what I want in the pre-build command and not wait for it to finish?所以问题是:有没有什么聪明的方法可以让 Visual Studio 简单地在预构建命令中运行我想要的东西而不是等待它完成?

The answer is yes, there is a smart way that I figured out.答案是肯定的,我想出了一个聪明的方法。

In your prebuild script, you need to use NodeJS to spawn a new process not connected to its parent.在您的预构建脚本中,您需要使用 NodeJS 来生成一个未连接到其父进程的新进程。 You would call something like this:你会这样称呼:

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

Then you need the spawner.js script in your project root然后你需要项目根目录中的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

It requires make-runnable so make sure to run npm i make-runnable -D它需要make-runnable所以确保运行npm i make-runnable -D

Along with spawner.js , this script uses forked-child.js which should also be placed in your project root.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);

I have included other methods in the spanwer.js script that might come in useful.我在 spanwer.js 脚本中包含了其他可能有用的方法。 For this example it's calling the fork method.对于这个例子,它调用了fork方法。

Now just run your build, and it should execute现在只需运行您的构建,它应该会执行

  1. node spawner.js fork \\"npm --prefix ../ run dev\\" , which calls node spawner.js fork \\"npm --prefix ../ run dev\\" ,它调用
  2. forked-child.js , which receives your command as an argument and forked-child.js ,它接收你的命令作为参数和
  3. opens that in a new detached process在新的分离进程中打开它

Because it is detached from its parent via forking, Visual Studio's build process will continue running even while this runs in its own never-ending terminal instance.因为它是通过分叉与其父级分离的,所以即使在其自己的永无止境的终端实例中运行时,Visual Studio 的构建过程也将继续运行。

So that is how I solved this exact problem with webpack-dev-server and visual studio.这就是我使用 webpack-dev-server 和 Visual Studio 解决这个确切问题的方法。 I hope that helps.我希望这有帮助。

I have recently had a similar situation where I want to run Webpack in watch mode after building my project in debug mode.我最近遇到了类似的情况,在调试模式下构建我的项目后,我想在监视模式下运行 Webpack。 I was running into the same issue where the prebuild step would hang indefinitely when I ran my project.我遇到了同样的问题,当我运行我的项目时,预构建步骤会无限期地挂起。

I came up with the following solution which runs the .bat file by opening a separate cmd window which doesn't stop the build from completing and works like a charm.我想出了以下解决方案,它通过打开一个单独的 cmd 窗口来运行 .bat 文件,该窗口不会阻止构建完成并且像魅力一样工作。

Step 1 - Create a .bat file in the root of the project, I have called this WebpackWatch.bat with the following code, this will run webpack and put it into watch mode in the opened cmd window第 1 步- 在项目的根目录中创建一个 .bat 文件,我使用以下代码调用了这个 WebpackWatch.bat,这将运行 webpack 并在打开的 cmd 窗口中将其置于监视模式

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

Step 2 - In the post build event, I have added the following, this will run the powershell command to open the .bat file, and then continue on with the build, for release mode, it calls the script build:prod in my packages config第 2 步- 在构建后事件中,我添加了以下内容,这将运行 powershell 命令打开 .bat 文件,然后继续构建,对于发布模式,它在我的包中调用脚本 build:prod配置

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

For information purposes my package.json file has the following script for the release build event, notice this does not have --watch in the build process so this completes file with the build step.出于信息目的,我的 package.json 文件具有以下用于发布构建事件的脚本,注意这在构建过程中没有 --watch ,因此这会使用构建步骤完成文件。

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

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

I actually figured out a way to do this with a pre-build command.我实际上想出了一种使用预构建命令来做到这一点的方法。 You can start webpack to the side at the same time you start your application in Visual Studio without waiting for the command to finish.您可以在 Visual Studio 中启动应用程序的同时启动 webpack,而无需等待命令完成。

You can use你可以使用

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

For example, this is my pre-build event command line in Build Events under the ASP.Net MVC 5 Project's properties:例如,这是我在 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.

相关问题 在Visual Studio 2010中预构建 - Pre-build in Visual Studio 2010 嵌入外部 xml 文件的 Visual Studio 预构建操作 - Visual Studio Pre-build action to embed external xml file Visual Studio C#不会生成因预生成事件而更改的文件 - visual studio c# does not build files that were change by pre-build event 在每次构建时在 Visual Studio C# 中运行预构建事件,而不总是触发目标重建 - Run pre-build event in Visual Studio C# on every build without always triggering target rebuild 如何使用Visual Studio 2013预构建事件从构建中排除脚本? - How do i use Visual Studio 2013 Pre-Build event to exclude a script from build? 如何以编程方式将AssemblyInfo.cs更新为预生成事件(Visual Studio / msbuild) - How to programatically update AssemblyInfo.cs as a Pre-Build event (Visual Studio / msbuild) Visual Studio 2017 web 部署:等待自定义预构建操作完成 - Visual Studio 2017 web deploy: wait for custom pre-build action finish 将 C# 文件作为预构建事件运行 Visual Studio (.NET Core) - Run a C# file as a pre-build event Visual Studio (.NET Core) Visual Studio 2010可以查找并替换预生成的版本号吗? - Can Visual Studio 2010 find and replace version number pre-build? 如何在C#项目中以编程方式(例如在预生成事件中)以编程方式设置Visual Studio 2015的OutDir属性? - How can I set Visual Studio 2015's OutDir property programatically, e.g. in a pre-build event, in a C# project?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM