Webpack - 监视并启动nodemon?

时间:2016-02-22 02:57:41

标签: node.js webpack browser-sync nodemon

感谢@McMath的excellent answer我现在有webpack编译我的客户端和我的服务器。我现在正试图让webpack --watch变得有用。理想情况下,当我的客户端发生变化时,我希望让它为我的服务器进程生成类似nodemon的东西,以及当我的客户端更改时的某些类型的browserync。

我意识到它是一个捆绑器/加载器而不是真正的任务运行器,但有没有办法实现这一目标?缺乏谷歌搜索结果似乎表明我正在尝试新的东西,但这一定已经完成了..

我总是可以将webpack包放到另一个目录中并使用gulp来观察/复制它/ browsersync-ify它,但这看起来像是一个黑客..有更好的方法吗?

9 个答案:

答案 0 :(得分:47)

  1. 安装以下依赖项:
  2. npm install npm-run-all webpack nodemon

    1. 将您的package.json文件配置为如下所示:
    2. 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轻松运行项目。

      请勿忘记配置WatchIgnorePlugin以使webpack忽略./dist文件夹。

      依赖关系

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

答案 1 :(得分:21)

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

  

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

那么,那就是我在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'脚本,它会启动下一个脚本序列:clean - >开始 - >启动后。 并且有一部分'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 按预期工作

答案 2 :(得分:12)

我喜欢nodemon-webpack-plugin

的简单性

<强> webpack.config.js

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

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

然后只使用watch标志

运行webpack
webpack --watch

答案 3 :(得分:1)

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

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

@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/*\""
        }
        ...
    },
    

答案 6 :(得分:0)

除了@Ling的好答案:

如果要完全构建项目,请在使用nodemon观看项目之前进行构建,或者如果您具有从属构建(例如,server之后是client),则可以执行以下操作:< / p>

只需将您自己的自定义插件添加到webpack.config.js并使用compiler hook-令人惊讶的简单,请参阅一个很好的答案here,以获取更多插件说明。 webpack完成编译后,插件的代码将触发nodemon

带有done钩子的自定义插件:

const { spawn } = require("child_process")

function InitialBuildActionPlugin() {
  let isInitialBuild = true
  return {
    apply: compiler => {
      compiler.hooks.done.tap("InitialBuildActionPlugin", compilation => {
        if (isInitialBuild) {
          /* 
           * This is the main code. Start nodemon once after the initial build has 
           * finished and not again after a code change (assuming you run webpack
           * in --watch mode). nodemon is included in PATH in this case.
           * Alternatively, invoke it as npm script (`npm run watch`)
           */
          isInitialBuild = false
          spawn("nodemon dist/index.js --watch dist", {
            stdio: "inherit",
            shell: true
          })
        }
      })
    }
  }
}

您还可以在插件中开始另一个Webpack构建,例如,如果您有多个构建目标,例如electron-mainelectron-preloadweb(这就是我的来历)。

webpack.config.js:

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

package.json:

"scripts": {
  "dev"  : "webpack --watch"
  // if you run nodemon as npm script, see above plugin code
  // "watch" : "nodemon dist/index.js --watch dist"
},

另一种选择是wait-on软件包,但是上述解决方案的优点是:

  • 您可以在webpack配置中访问构建/环境变量
  • 可以使用内置的webpack功能
  • 不需要第三方软件包
  • 不创建虚拟文件

希望,它会有所帮助。

答案 7 :(得分:0)

我尝试了上面提供的大部分解决方案。我认为最好的方法是使用 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 仅在观看模式下有效。

答案 8 :(得分:-1)

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