Webpack --watch 并启动 nodemon?

Webpack --watch and launching nodemon?

感谢@McMath 的 ,我现在可以使用 webpack 编译我的客户端和服务器。我现在正试图让 webpack --watch 变得有用。理想情况下,我希望它在捆绑包更改时为我的服务器进程生成类似 nodemon 的东西,并在我的客户端更改时生成一些浏览器同步的东西。

我知道它是一个 bundler/loader 而不是真正的任务运行器,但是有什么方法可以做到这一点吗?缺少 google 结果似乎表明我正在尝试一些新的东西,但这一定已经完成了..

我总是可以将 webpack 打包到另一个目录并使用 gulp 观看 it/copy it/browsersync-ify 它,但这似乎是 hack.. 有更好的方法吗?

  1. 安装以下依赖项:

npm install npm-run-all webpack nodemon

  1. 将您的 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\""
  },

  ...

}

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

轻松 运行 您的项目

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

依赖关系

  1. npm-run-all - 运行 多个 npm 脚本并行或顺序的 CLI 工具。
  2. webpack - webpack 是一个模块打包器。它的主要目的是捆绑 JavaScript 文件以便在浏览器中使用,但它也能够转换、捆绑或打包任何资源或资产。
  3. nodemon - 在 node.js 应用程序开发期间使用的简单监控脚本。

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

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

所以,这就是我在 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",
}

如果我 运行 'start' 脚本它会启动下一个脚本序列:清理 -> 开始 -> 启动后。 还有一部分 '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”事件仅在首次构建后触发一次,重建不会触发“onBuildEnd”,因此 nodemon 按预期工作

你不需要任何插件来使用 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"
},

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

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

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

  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 文件 运行 成功,这只会 运行 观看。从而防止 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/*\""
        }
        ...
    },
    

我喜欢nodemon-webpack-plugin

的简洁

webpack.config.js

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

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

然后 运行 带有 watch 标志的 webpack

webpack --watch

另外@Ling的回答不错:

如果你想在使用 nodemon 观看之前构建你的项目一次,你可以使用 webpack compiler hook. The plugin's code triggers nodemon in the done hook once after webpack has finished its compilation (see also this helpful )。

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:

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

package.json:

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

希望对您有所帮助。

假设 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
      });
    }
  ]
}

我尝试了上面提供的大部分解决方案。我相信最好的方法是使用 nodemon-webpack-plugin .

使用起来非常简单,只需添加 const NodemonPlugin = require('nodemon-webpack-plugin') 到 webpack 文件 new NodemonPlugin() 作为你的插件。

下面是使用它的脚本:

"scripts": {
    "watch:webpack-build-dev": "webpack --watch --mode development",
    "clean-db": "rm -rf ./db && mkdir -p ./db",
    "local-dev": "npm run clean-db && npm run watch:webpack-build-dev"
    ...
}

之后你可以简单地 运行 npm run local-dev.

将模块添加到开发中通常没有添加到生产中那么糟糕。大多数情况下,您无论如何都会将其用于开发。

这也不需要任何额外的包,如 nodemonnpm-run-all

另外nodemon-webpack-plugin 只在手表模式下有效。