npm run dev 是“本地运行我的网站”的标准,但它是如何工作的呢?我们如何扩展它的功能?在这篇文章中,我们将看看:
作为一个激励示例,以下是凸帮助程序示例应用程序中定义的一些脚本。我们将介绍每个部分的作用
"scripts": { "dev": "npm-run-all --parallel dev:backend dev:frontend", "build": "tsc && vite build", "dev:backend": "convex dev", "dev:frontend": "vite", "predev": "convex dev --until-success", "test": "vitest" },
npm run 运行项目工作区中 package.json 中定义的命令。当您从 npm create vite@latest 等命令启动存储库时,这些命令通常是预先配置的,其中的命令为:
这是来自 next.js 的基本示例:
// in package.json { // ... "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint" }, //...
在这里你可以运行 npm run dev 或 npm run lint 等
您可以在文档中了解有关 npm run 的更多信息。
这是一个公平的问题,为什么人们会将已经如此简单的命令放入包脚本中。为什么不直接调用 jest 或 vite 或 next build 呢?有几个很好的理由:
是的!即使您使用其他包管理器安装依赖项,您仍然可以使用 npm 运行包脚本。
yarn # similar to `npm install` npm run dev # still works!
您不必记住 npm run dev 映射到yarn dev(或yarn run dev)。 npx 也是如此:无论您使用什么包管理器来安装东西,npx 凸开发都可以工作。
有几个包可以用来同时运行命令:4
我们在这里只看一下 npm-run-all 。考虑我们的例子:
"scripts": { "dev": "npm-run-all --parallel dev:backend dev:frontend", "dev:backend": "convex dev", "dev:frontend": "vite", },
这定义了三个脚本。
两个输出都会流出,并且执行 ctrl-c 会中断两个脚本。
您可以通过将命令命名为 prex 或 postx 来指定在另一个命令(例如 x)之前(前)或之后(后)运行的命令。在示例中:
"scripts": { "dev": "npm-run-all --parallel dev:backend dev:frontend", "dev:backend": "convex dev", "dev:frontend": "vite", "predev": "convex dev --until-success", },
这将在 npm-run-all --parallel dev:backend dev:frontend 的“dev”命令之前运行凸开发 --until-success。
对于习惯 shell 脚本的人来说,如果前一个命令成功,则可以按顺序运行两个命令:commanda && commandb。这适用于 windows 和 unix (mac / linux)。
但是,仅使用预先脚本有几个优点:
对于 convex,当您第一次运行 npx 凸开发(或使用上述脚本的 npm run dev)时,如果您还没有登录,它会要求您登录;如果尚未登录,它会要求您设置项目设置。这很棒,但是当多个命令同时传输输出时,更新输出文本的交互式命令不能很好地工作。这是在 npx 凸 dev 之前运行 npx 凸 dev --until-success 的动机。
如果您将 convex 的“predev”命令更改为包含 --run ,它将在前端启动之前运行服务器端功能。
"scripts": { //... "predev": "convex dev --until-success --run init", //... },
--run init 命令将运行凸/init.ts 中默认导出的函数。您还可以运行 --run myfolder/mymodule:myfunction。请参阅此处有关命名的文档。请参阅这篇关于播种数据的文章,但要点是您可以定义一个内部突变来检查数据库是否为空,如果是,则插入一组记录以用于测试/设置目的。
如果您使用 typescript,您可以使用裸 tsc 运行类型检查/编译您的 typescript 文件。如果您的 tsconfig.json 配置为发出类型,它将写出类型。如果没有,它只会验证类型。作为构建的一部分,这非常好,因此您不会构建任何有类型错误的东西。这就是上面例子的原因:
"build": "tsc && vite build",
如果您想将参数传递给命令,例如将参数传递给测试命令以指定要运行的测试,您可以在after之后传递它们 - 以将命令与参数分开。从技术上讲,你不需要 -- 如果你的参数是位置参数而不是 -- 前缀,但总是这样做也没什么坏处,以防你忘记为哪个而做。
npm run test -- --grep="pattern"
我们研究了一些使用 package.json 脚本来简化工作流程的方法。谁知道一个简单的 npm run dev 背后可以蕴含多少力量?看看我们原来的例子:
"scripts": { "dev": "npm-run-all --parallel dev:backend dev:frontend", "build": "tsc && vite build", "dev:backend": "convex dev", "dev:frontend": "vite", "predev": "convex dev --until-success", "test": "vitest" },
输入 npm 时 shell 查找要运行的命令的方法是检查 shell 的 path 环境变量(无论如何在 unix 机器上)。您可以使用 echo "$path" 看到您自己的。它检查 $path 中指定的所有位置并使用第一个位置。 ↩
从技术上讲,您可以覆盖并指定 npm 安装二进制文件的位置。 ↩
如果你真的想,你可以直接运行 npm exec vitest,简称 npx vitest,./npm_modules/.bin/vitest,或者将 .npm_modules/.bin 添加到你的 path 中。 ↩
有些人使用裸 & 在后台运行一项任务,但这在 windows 上不受支持,并且中断一个命令不一定会杀死另一个命令。 ↩