Webpack --watch 和启动 nodemon?

Posted

技术标签:

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

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

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

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

【问题讨论】:

【参考方案1】:
    安装以下依赖项:

npm install npm-run-all webpack nodemon

    将您的 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 文件夹。

依赖关系

    npm-run-all - 用于并行或顺序运行多个 npm 脚本的 CLI 工具。 webpack - webpack 是一个模块打包器。它的主要目的是捆绑 javascript 文件以在浏览器中使用,但它也能够转换、捆绑或打包几乎任何资源或资产。 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 的答案非常接近正确。但是当有人第一次运行手表时它会出错。您需要修改解决方案以防止出现错误。

    运行npm install npm-run-all webpack nodemon

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

    var fs = require('fs');
    
    if (!fs.existsSync('./dist')) 
        fs.mkdir('./dist');
        fs.writeFileSync('./dist/bundle.js', '');
    
    

    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 只能在手表模式下工作。

【讨论】:

以上是关于Webpack --watch 和启动 nodemon?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 webpack watch 没有更新我的代码?

Nodemon 与 gulp watch 绑定时崩溃并重新启动两次以上

webpack笔记

Webpack5中的文件监听与热更新

Webpack5中的文件监听与热更新

Webpack中的文件监听与热更新