【问题标题】:Webpack --watch and launching nodemon?Webpack --watch 和启动 nodemon?
【发布时间】:2016-06-03 08:59:42
【问题描述】:

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

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

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

【问题讨论】:

    标签: node.js webpack browser-sync nodemon


    【解决方案1】:
    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 应用程序的简单监控脚本。

    【讨论】:

    • 它有效。但是有点马虎。如果您的文件夹 dist 在首次运行时不存在,您可能会收到错误消息。
    • 不要忘记'--inspect'标志。
    • @Ling 虽然这不会为客户端和服务器启动两个构建。
    【解决方案2】:

    遇到了同样的问题,找到了下一个解决方案——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",
    }
    

    如果我运行“启动”脚本,它会启动下一个脚本序列: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”事件仅在首次构建后触发一次,重建不会触发“onBuildEnd”,因此 nodemon 可以按预期工作

    【讨论】:

    • 你能分享文件的其余部分webpack.server.config.js吗?
    • 因为当我尝试这些时它不起作用:`“start”:“cross-env NODE_ENV=development webpack --watch”,“poststart”:“cross-env NODE_ENV=development webpack - -watch --config webpack.server.config.js"` ` var WebpackShellPlugin = require('webpack-shell-plugin') module.exports = { plugins: (process.env.NODE_ENV !== 'production') ? [新的 WebpackShellPlugin({ onBuildEnd: [ 'cross-env NODE_ENV=development nodemon server/server.js --watch ./dist' ] }) ] : [] } `
    【解决方案3】:

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

    【讨论】:

    • 如果我需要构建客户端和服务器,并且服务器依赖于客户端文件,因为它是通用应用程序(首先构建客户端,然后使用'watch'键构建服务器并运行它)怎么办?这种方式行不通。
    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      @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 文件成功运行时运行 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/*\""
            }
            ...
        },
        

      【讨论】:

        【解决方案6】:

        我喜欢nodemon-webpack-plugin的简洁

        webpack.config.js

        const NodemonPlugin = require('nodemon-webpack-plugin')
        
        module.exports = {
          plugins: [new NodemonPlugin()]
        }
        

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

        webpack --watch
        

        【讨论】:

          【解决方案7】:

          除了@Ling 的好回答:

          如果您想构建一次项目,在使用nodemon 观看之前,您可以使用 webpack compiler hook。在 webpack 完成编译后,插件的代码会在 done 钩子中触发 nodemon(另请参阅这个有用的 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"
          },
          

          希望,它会有所帮助。

          【讨论】:

            【解决方案8】:

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

            【讨论】:

            • 我真的不确定为什么这个答案被否决了两次,它对我来说非常好,解决了我所有的问题。它的作用是在发出 webpack 输出(也就是所有内容都编译到磁盘)之后,它运行execSync 调用中指定的命令。我用它来运行yalc push,它会更新我的本地包注册表。像魅力一样工作,包括在手表模式下!
            【解决方案9】:

            我尝试了上面提供的大部分解决方案。我相信最好的方法是使用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 只能在手表模式下工作。

            【讨论】:

              猜你喜欢
              • 2014-06-23
              • 2018-06-28
              • 1970-01-01
              • 2014-09-24
              • 2017-09-26
              • 2014-02-24
              • 2019-06-22
              • 2018-03-05
              • 2019-03-23
              相关资源
              最近更新 更多