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
。
将模块添加到开发中通常没有添加到生产中那么糟糕。无论如何,大多数情况下你都会将它用于开发。
这也不需要任何额外的包,如nodemon
或npm-run-all
等。
另外nodemon-webpack-plugin
只能在手表模式下工作。
【讨论】:
以上是关于Webpack --watch 和启动 nodemon?的主要内容,如果未能解决你的问题,请参考以下文章