Webpack --watch and launching nodemon?

馋奶兔 提交于 2020-05-24 08:25:10

问题


Thanks to an excellent answer by @McMath I now have webpack compiling both my client and my server. I'm now on to trying to make webpack --watch be 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.

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?


回答1:


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

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

So, thats my scripts in 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':

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 nodemon works as intended




回答2:


  1. Install the following dependencies:

npm install npm-run-all webpack nodemon

  1. Configure your package.json file to something as seen below:

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.

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

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.



回答3:


I like the simplicity of nodemon-webpack-plugin

webpack.config.js

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

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

then just run webpack with the watch flag

webpack --watch



回答4:


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

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



回答5:


You don't need any plugins to use webpack and nodemon, just use this scripts on your 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"
},



回答6:


@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.

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

  2. Create a file called watch-shim.js in 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.js file 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/*\""
        }
        ...
    },
    



回答7:


In addition to @Ling's good answer:

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 nodemon in the done hook once after webpack has finished its compilation (see also this helpful post).

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"
},

Hope, it helps.




回答8:


Assuming nodemon server.js touch the server.js file 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
      });
    }
  ]
}


来源:https://stackoverflow.com/questions/35545093/webpack-watch-and-launching-nodemon

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!