ホームページ >ウェブフロントエンド >jsチュートリアル >package.json スクリプトで「npm run dev」をスーパーチャージする

package.json スクリプトで「npm run dev」をスーパーチャージする

PHPz
PHPzオリジナル
2024-07-24 12:02:51663ブラウズ

Supercharge `npm run dev` with package.json scripts

npm run dev は「Web サイトをローカルで実行する」ための標準ですが、どのように機能するのでしょうか?どうすればその機能を拡張できるでしょうか?この投稿では次のことを見ていきます:

  • npm run dev の動作を構成する方法。
  • 複雑なコマンドを詳細な単位に分解する方法。
  • 複数のコマンドを並行して実行する方法。
  • 通常の Ctrl-C の動作を失わずに前提条件を実行する方法。
  • Convex バックエンドの起動時にシード データを追加する方法 (存在しない場合)。

やる気を起こさせる例として、convex-helpers サンプル アプリで定義されているスクリプトをいくつか示します。各部分の機能について説明します

  "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 のようなコマンドからリポジトリを開始するときに、次のコマンドが含まれることがよくあります。

  • dev: 開発環境を実行します。これには、多くの場合、ファイル変更時の UI の自動再読み込みが含まれます。 Vite の場合、これは vite であり、Next.js は次の dev です。
  • build: デプロイメント用の Web サイトを構築します。これにより、通常、すべての HTML、CSS、JavaScript がコンパイルされてバンドルされます。 Vite の場合、これは vite ビルドであり、Next.js は次のビルドです。
  • test: テストを実行します。Jest を使用している場合は、単に "test": "jest" または Vitest の場合は vitest です。

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 を呼び出してみてはいかがでしょうか?正当な理由がいくつかあります:

  1. コマンドのデフォルトのパラメータを保存できるため、何かを開始する「標準的な」方法を覚えたり文書化したりする必要がありません。コマンドをチェーンし、他のコマンドを並行して実行するように設定する方法を以下で説明します。
  2. npm によってインストールされるが、シェル (ターミナル) からグローバルにアクセスできないコマンドを簡単に実行できます。1 npm install -D vitest などをインストールすると、vitest が node_modules/ にインストールされます。 .bin.2 シェル 3 で vitest を直接実行することはできませんが、次のような構成を使用できます。 "scripts": { "test": "vitest" } npm run test は vitest を実行します。
  3. サブディレクトリにいる場合でも、常にパッケージ フォルダーのルートを「現在のディレクトリ」として実行します。したがって、「foo」: 「./myscript.sh」のようなスクリプトを定義すると、パッケージ ルート (package.json と同じディレクトリ内) で常に myscript.sh が検索されます。注: INIT_CWD 環境変数を介して、呼び出された現在のディレクトリにアクセスできます。
  4. npm run からスクリプトを実行すると、package.json 内の変数を簡単に参照できます。たとえば、js の process.env.npm_package_version やスクリプトの $npm_package_version など、npm_package_version 環境変数を使用してパッケージの「バージョン」にアクセスできます。
  5. 複数のワークスペースがある場合 (「workspaces」構成を持つ親 package.json に構成された独自の package.json を持つ多数のディレクトリ)、npm test --workspaces を使用してすべてのワークスペースで同じコマンドを実行するか、npm test --workspaces を使用して 1 つのワークスペースで同じコマンドを実行できます。 npm run lint --workspace apps/web.

npm run dev は、yarn / pnpm / bun で動作しますか?

はい!別のパッケージ マネージャーを使用して依存関係をインストールした場合でも、npm を使用してパッケージ スクリプトを実行できます。

yarn # similar to `npm install`
npm run dev # still works!

npm run dev がyarn dev (またはyarn run dev) にマップされることを覚えておく必要はありません。同じことが npx にも当てはまります。npx convex dev は、インストールに使用したパッケージ マネージャーに関係なく機能します。

コマンドを並行して実行する

コマンドを同時に実行するために使用できるパッケージがいくつかあります:4

  1. npm-run-all
  2. 同時に

ここでは npm-run-all についてのみ見ていきます。私たちの例を考えてみましょう:

  "scripts": {
    "dev": "npm-run-all --parallel dev:backend dev:frontend",
    "dev:backend": "convex dev",
    "dev:frontend": "vite",
  },

これは 3 つのスクリプトを定義します。

  1. npm run dev:backend は convex dev を実行します。
  2. npm run dev:frontend は vite を実行します。
  3. npm run dev は、npm-run-all を介して convex dev と vite の両方を並行して実行します。

両方の出力はストリーミング出力され、Ctrl-C を押すと両方のスクリプトが中断されます。

プレデバ?ポストビルド?

コマンドに preX または postX という名前を付けることで、別のコマンド (X など) の前 (pre) または後 (post) に実行するコマンドを指定できます。例では:

  "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」コマンドの前に、convex dev --until-success が実行されます。

Chaining with "&&"

For those used to shell scripting, you can run two commands in sequence if the previous one succeeds with commandA && commandB. This works on both Windows and Unix (mac / linux).

However, there's a couple advantages to just using pre-scripts:

  1. You can run either command with npm run dev --ignore-scripts to not do the "predev" script, or npm run predev to explicitly only do the "predev" step.
  2. The Ctrl-C behavior is more predictable in my experience. In different shell environments, doing Ctrl-C (which sends an interrupt signal to the current process) would sometimes kill the first script but still run the second script. After many attempts we decided to switch to "predev" as the pattern.

Run interactive steps first

For Convex, when you first run npx convex dev (or npm run dev with the above scripts), it will ask you to log in if you aren't already, and ask you to set up your project if one isn't already set up. This is great, but interactive commands that update the output text don't work well when the output is being streamed by multiple commands at once. This is the motivation for running npx convex dev --until-success before npx convex dev.

  • convex dev syncs your functions and schema whenever it doesn't match what you have deployed, watching for file changes.
  • The --until-success flag syncs your functions and schema only until it succeeds once, telling you what to fix if something is wrong and retrying automatically until it succeeds or you Ctrl-C it.
  • By running npx convex dev --until-success, we can go through the login, project configuration, and an initial sync, all before trying to start up the frontend and backend.
  • The initial sync is especially helpful if it catches issues like missing environment variables which need to be set before your app can function.
  • This way the frontend doesn't start until the backend is ready to handle requests with the version of functions it expects.

Seeding data on startup

If you change your "predev" command for Convex to include --run it will run a server-side function before your frontend has started.

  "scripts": {
      //...
    "predev": "convex dev --until-success --run init",
        //...
  },

The --run init command will run a function that is the default export in convex/init.ts. You could also have run --run myFolder/myModule:myFunction. See docs on naming here. See this post on seeding data but the gist is that you can define an internalMutation that checks if the database is empty, and if so inserts a collection of records for testing / setup purposes.

tsc?

If you use TypeScript, you can run a type check / compile your typescript files with a bare tsc. If your tsconfig.json is configured to emit types, it will write out the types. If not, it will just validate the types. This is great to do as part of the build, so you don't build anything that has type errors. This is why the above example did:

    "build": "tsc && vite build",

How to pass arguments?

If you want to pass arguments to a command, for instance passing arguments to your testing command to specify what test to run, you can pass them after a -- to separate the command from the argument. Technically you don't need -- if your arguments are positional instead of --prefixed, but it doesn't hurt to always do it in case you forget which to do it for.

npm run test -- --grep="pattern"

Summary

We looked at some ways of using package.json scripts to simplify our workflows. Who knew how much power could rest behind a simple npm run dev? Looking at our original example:

  "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"
  },
  • dev runs the frontend and backend in parallel, after predev.
  • build does type checking via tsc before building the static site.
  • dev:backend continuously deploys the backend functions to your development environment as you edit files.
  • dev:frontend runs a local frontend server that auto-reloads as you edit files.
  • predev runs before dev and does an initial deployment, handling login, configuration, and an initial sync as necessary.
  • test uses Vitest to run tests. Note: npm test is shorthand for npm run test along with other commands, but they're special cases. npm run test is the habit I suggest.

  1. The way your shell finds which command to run when you type npm is to check the shell's PATH environment variable (on unix machines anyways). You can see your own with echo "$PATH". It checks all the places specified in $PATH and uses the first one.  ↩

  2. Technically you can override & specify where npm installs binaries. ↩

  3. 本当に必要な場合は、npm exec vitest、略して npx vitest、./npm_modules/.bin/vitest を直接実行するか、.npm_modules/.bin を PATH に追加します。 ↩

  4. バックグラウンドで 1 つのタスクを実行するために、裸の & を使用する人もいますが、これは Windows ではサポートされておらず、一方のコマンドを中断しても、必ずしも他方のコマンドが強制終了されるわけではありません。 ↩

以上がpackage.json スクリプトで「npm run dev」をスーパーチャージするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。