node.js Webpack --watch 并启动 nodemon?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35545093/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 19:57:29  来源:igfitidea点击:

Webpack --watch and launching nodemon?

node.jswebpackbrowser-syncnodemon

提问by XeroxDucati

Thanks to an excellent answerby @McMath I now have webpack compiling both my client and my server. I'm now on to trying to make webpack --watchbe useful. Ideally I'd like to have it spawn something like nodemon for my server process when that bundle changes, and some flavor of browsersync for when my client changes.

感谢@McMath的出色回答,我现在可以通过 webpack 编译我的客户端和服务器。我现在正在努力使webpack --watch有用。理想情况下,我希望它在包更改时为我的服务器进程生成类似 nodemon 的东西,并在我的客户端更改时生成一些浏览器同步。

I realize it's a bundler/loader and not really a task runner, but is there some way to accomplish this? A lack of google results seems to indicate I'm trying something new, but this must have been done already..

我意识到它是一个打包器/加载器,而不是真正的任务运行器,但是有什么方法可以做到这一点吗?缺乏谷歌搜索结果似乎表明我正在尝试新的东西,但这一定已经完成了..

I can always have webpack package to another directory and use gulp to watch it/copy it/browsersync-ify it, but that seems like a hack.. Is there a better way?

我总是可以将 webpack 包放到另一个目录并使用 gulp 来观看它/复制它/浏览器同步它,但这似乎是一个黑客......有没有更好的方法?

采纳答案by Jonik

Faced the same problem and found the next solution - "webpack-shell-plugin". It

遇到同样的问题,找到了下一个解决方案——“webpack-shell-plugin”。它

allows you to run any shell commands before or after webpack builds

允许你在 webpack 构建之前或之后运行任何 shell 命令

So, thats my scripts in package.json:

所以,这就是我在 package.json 中的脚本:

"scripts": {
      "clean": "rimraf build",
      "prestart": "npm run clean",
      "start": "webpack --config webpack.client.config.js",
      "poststart": "webpack --watch --config webpack.server.config.js",
}

If I run 'start' script it launches next script sequence: clean -> start -> poststart. And there is part of 'webpack.server.config.js':

如果我运行“开始”脚本,它会启动下一个脚本序列:clean -> start -> poststart。并且有一部分“webpack.server.config.js”:

var WebpackShellPlugin = require('webpack-shell-plugin');

...
if (process.env.NODE_ENV !== 'production') {
    config.plugins.push(new WebpackShellPlugin({onBuildEnd: ['nodemon build/server.js --watch build']}));
}
...

"onBuildEnd" event fires only once after first build, rebuilds are not trigger "onBuildEnd", so nodemonworks as intended

“onBuildEnd”事件在第一次构建后只触发一次,重建不会触发“onBuildEnd”,所以nodemon按预期工作

回答by Ling

  1. Install the following dependencies:
  1. 安装以下依赖项:

npm install npm-run-all webpack nodemon

npm install npm-run-all webpack nodemon

  1. Configure your package.jsonfile to something as seen below:
  1. 将您的package.json文件配置为如下所示的内容:

package.json

package.json

{
  ...

  "scripts": {
    "start"        : "npm-run-all --parallel watch:server watch:build",
    "watch:build"  : "webpack --watch",
    "watch:server" : "nodemon \"./dist/index.js\" --watch \"./dist\""
  },

  ...

}

After doing so, you can easily run your project by using npm start.

这样做之后,您可以使用npm start.

Don't forget config WatchIgnorePlugin for webpack to ignore ./distfolder.

不要忘记为 webpack 配置 WatchIgnorePlugin 以忽略./dist文件夹。

Dependencies

依赖关系

  1. npm-run-all- A CLI tool to run multiple npm-scripts in parallel or sequential.
  2. webpack- webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.
  3. nodemon- Simple monitor script for use during development of a node.js app.
  1. npm-run-all- 并行或顺序运行多个 npm 脚本的 CLI 工具。
  2. webpack- webpack 是一个模块打包器。它的主要目的是捆绑 JavaScript 文件以在浏览器中使用,但它也能够转换、捆绑或打包几乎任何资源或资产。
  3. nodemon- 在开发 node.js 应用程序期间使用的简单监视器脚本。

回答by galki

I like the simplicity of nodemon-webpack-plugin

我喜欢nodemon-webpack-plugin的简单性

webpack.config.js

webpack.config.js

const NodemonPlugin = require('nodemon-webpack-plugin')

module.exports = {
  plugins: [new NodemonPlugin()]
}

then just run webpack with the watchflag

然后只需运行带有watch标志的webpack

webpack --watch

回答by Monarch Wadia

There's no need to use plugins here. You could try running multiple nodemoninstances like below. Try modifying the following script for your use case, and see if it works for you:

这里不需要使用插件。您可以尝试运行多个nodemon实例,如下所示。尝试为您的用例修改以下脚本,看看它是否适合您:

"scripts": {
    "start": "nodemon --ignore './public/' ./bin/www & nodemon --ignore './public/' --exec 'yarn webpack'",
    "webpack": "webpack --config frontend/webpack.config.js"
}

回答by Ash Blue

@Ling has an answer very close to being correct. But it errors the first time somebody runs watch. You'll need to modify the solution as so to prevent errors.

@Ling 的答案非常接近正确。但是当有人第一次运行 watch 时它会出错。您需要修改解决方案以防止错误。

  1. Run npm install npm-run-all webpack nodemon

  2. Create a file called watch-shim.jsin your root. Add the following contents, which will create a dummy file and directory if they're missing.

    var fs = require('fs');
    
    if (!fs.existsSync('./dist')) {
        fs.mkdir('./dist');
        fs.writeFileSync('./dist/bundle.js', '');
    }
    
  3. Setup your scripts as so in package.json. This will only run watch if the watch-shim.jsfile runs successfully. Thereby preventing Nodemon from crashing due to missing files on the first run.

    {
        ...
        "scripts": {
            "start": "npm run watch",
            "watch": "node watch-shim.js && npm-run-all --parallel watch:server watch:build",
            "watch:build": "webpack --progress --colors --watch",
            "watch:server": "nodemon \"./dist/bundle.js\" --watch \"./dist/*\""
        }
        ...
    },
    
  1. npm install npm-run-all webpack nodemon

  2. 创建一个watch-shim.js在您的根目录中调用的文件。添加以下内容,如果它们丢失,将创建一个虚拟文件和目录。

    var fs = require('fs');
    
    if (!fs.existsSync('./dist')) {
        fs.mkdir('./dist');
        fs.writeFileSync('./dist/bundle.js', '');
    }
    
  3. package.json. 如果watch-shim.js文件成功运行,这只会运行 watch 。从而防止 Nodemon 在第一次运行时由于丢失文件而崩溃。

    {
        ...
        "scripts": {
            "start": "npm run watch",
            "watch": "node watch-shim.js && npm-run-all --parallel watch:server watch:build",
            "watch:build": "webpack --progress --colors --watch",
            "watch:server": "nodemon \"./dist/bundle.js\" --watch \"./dist/*\""
        }
        ...
    },
    

回答by Antoni Xu

You don't need any plugins to use webpack and nodemon, just use this scripts on your package.json

你不需要任何插件来使用 webpack 和 nodemon,只需在你的 package.json 上使用这个脚本

"scripts": {
  "start": "nodemon --ignore './client/dist' -e js,ejs,html,css --exec 'npm run watch'",
  "watch": "npm run build && node ./server/index.js",
  "build": "rimraf ./client/dist && webpack --bail --progress --profile"
},

回答by ford04

In addition to @Ling's good answer:

除了@Ling 的好回答:

If you want to build your project once, before you watch it with nodemon, you can use a webpack compiler hook. The plugin's code triggers nodemonin the donehook once after webpack has finished its compilation (see also this helpful post).

如果你想一次构建你的项目,在你用 观看它之前nodemon,你可以使用 webpack编译器 hook。在 webpack 完成编译后,插件的代码会nodemondone钩子中触发一次(另见这篇有用的帖子)。

const { spawn } = require("child_process")

function OnFirstBuildDonePlugin() {
  let isInitialBuild = true
  return {
    apply: compiler => {
      compiler.hooks.done.tap("OnFirstBuildDonePlugin", compilation => {
        if (isInitialBuild) {
          isInitialBuild = false
          spawn("nodemon dist/index.js --watch dist", {
            stdio: "inherit",
            shell: true
          })
        }
      })
    }
  }
}

webpack.config.js:

webpack.config.js:

  module.exports = {
    ... 
    plugins: [
      ... 
      OnFirstBuildDonePlugin()
    ]
  })

package.json:

包.json:

"scripts": {
  "dev"  : "webpack --watch"
},

Hope, it helps.

希望能帮助到你。

回答by abernier

Assuming nodemon server.jstouch the server.jsfile afterEmit:

假设nodemon server.js触摸server.js文件afterEmit

// webpack.config.js

module.exports = {
  // ...
  plugins: [
    // ...,

    // 
    apply: (compiler) => {
      compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {

        require('child_process').execSync('touch server.js') // $ touch server.js
      });
    }
  ]
}