Open7

Nxの検証メモ

tokku5552tokku5552

新規で検証用ワークスペース作成

% npx create-nx-workspace@
latest
Need to install the following packages:
  create-nx-workspace@15.4.2
Ok to proceed? (y) y

 >  NX   Let's create a new workspace [https://nx.dev/getting-started/intro]

✔ Choose what to create                 · package-based
✔ Repository name                       · nx-workspace-poc
✔ Enable distributed caching to make your CI faster · Yes

 >  NX   Nx is creating your v15.4.2 workspace.

   To make sure the command works reliably in all environments, and that the preset is applied correctly,
   Nx will run "npm install" several times. Please wait.

✔ Installing dependencies with npm
✔ Nx has successfully created the workspace: nx-workspace-poc.
✔ NxCloud has been set up successfully

 >  NX   Successfully initialized git.

出来上がったディレクトリはこんな感じ

% tree -L 2 -a -I node_modules -I .git
.
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .vscode
│   └── extensions.json
├── README.md
├── nx.json
├── package-lock.json
├── package.json
└── packages
    └── .gitkeep
tokku5552tokku5552

公式のドキュメントを見ていたら、--preset=nextをつけたほうが最初からnextjsありきの環境でできるっぽい。

% npx create-nx-workspace@latest --preset=next

 >  NX   Let's create a new workspace [https://nx.dev/getting-started/intro]

✔ Repository name                       · nx-nextjs-workspace-poc
✔ Application name                      · sample-app
✔ Default stylesheet format             · css
✔ Enable distributed caching to make your CI faster · Yes

 >  NX   Nx is creating your v15.4.2 workspace.

   To make sure the command works reliably in all environments, and that the preset is applied correctly,
   Nx will run "npm install" several times. Please wait.

✔ Installing dependencies with npm
✔ Nx has successfully created the workspace: nx-nextjs-workspace-poc.
✔ NxCloud has been set up successfully

 >  NX   Successfully initialized git.
...

ディレクトリ構造はこんな感じ。

% tree -a -L 4 -I dist -I node_modules -I .git
.
├── .editorconfig
├── .eslintrc.json
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .vscode
│   └── extensions.json
├── README.md
├── apps
│   ├── .gitkeep
│   ├── sample-app
│   │   ├── .eslintrc.json
│   │   ├── .next
│   │   │   ├── build-manifest.json
│   │   │   ├── cache
│   │   │   ├── package.json
│   │   │   ├── react-loadable-manifest.json
│   │   │   ├── server
│   │   │   ├── static
│   │   │   └── trace
│   │   ├── index.d.ts
│   │   ├── jest.config.ts
│   │   ├── next-env.d.ts
│   │   ├── next.config.js
│   │   ├── pages
│   │   │   ├── _app.tsx
│   │   │   ├── index.module.css
│   │   │   ├── index.tsx
│   │   │   └── styles.css
│   │   ├── project.json
│   │   ├── public
│   │   │   └── .gitkeep
│   │   ├── specs
│   │   │   └── index.spec.tsx
│   │   ├── tsconfig.json
│   │   └── tsconfig.spec.json
│   └── sample-app-e2e
│       ├── .eslintrc.json
│       ├── cypress.config.ts
│       ├── project.json
│       ├── src
│       │   ├── e2e
│       │   ├── fixtures
│       │   └── support
│       └── tsconfig.json
├── babel.config.json
├── jest.config.ts
├── jest.preset.js
├── libs
│   └── .gitkeep
├── nx.json
├── package-lock.json
├── package.json
├── tools
│   ├── generators
│   │   └── .gitkeep
│   └── tsconfig.tools.json
└── tsconfig.base.json

こちらで色々検証してみる。

tokku5552tokku5552

適当に動かしてみる。

  • ビルド(というかサーブ)
npx nx run sample-app:serve


高速だしホットリロードも問題ない。

  • ユニットテスト(最初からjestで簡単なテストが書かれている)
% npx nx test sample-app

> nx run sample-app:test  [existing outputs match the cache, left as is]

 PASS   sample-app  apps/sample-app/specs/index.spec.tsx
  Index
    ✓ should render successfully (37 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.271 s
Ran all test suites.

 ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

 >  NX   Successfully ran target test for project sample-app (113ms)

これも速い。テストコードが簡単なだけかもしれないが。

  • lint
% npx nx lint sample-app

> nx run sample-app:lint


Linting "sample-app"...

All files pass linting.


 ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

 >  NX   Successfully ran target lint for project sample-app (5s)

問題なく実行できる。そもそもeslintとprettierの設定が最初から入っているのがありがたすぎる。

  • e2e(Cypressのコードも最初から用意されていて設定済み)
% npx nx run sample-app-e2e:e2e

> nx run sample-app-e2e:e2e  [existing outputs match the cache, left as is]

info  - automatically enabled Fast Refresh for 1 custom loader
event - compiled client and server successfully in 2.1s (152 modules)
[ ready ] on http://localhost:4200
wait  - compiling /_error (client and server)...
event - compiled client and server successfully in 136 ms (153 modules)

====================================================================================================

  (Run Starting)

  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ Cypress:        11.2.0                                                                         │
  │ Browser:        Electron 106 (headless)                                                        │
  │ Node Version:   v18.12.1 (/Users/tokudashinnosuke/.nodebrew/node/v18.12.1/bin/node)            │
  │ Specs:          1 found (app.cy.ts)                                                            │
  │ Searched:       src/**/*.cy.{js,jsx,ts,tsx}                                                    │
  └────────────────────────────────────────────────────────────────────────────────────────────────┘


────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                    
  Running:  app.cy.ts                                                                       (1 of 1)


  sample-app
wait  - compiling / (client and server)...
event - compiled client and server successfully in 325 ms (159 modules)
    ✓ should display welcome message (1967ms)


  1 passing (2s)


  (Results)

  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ Tests:        1                                                                                │
  │ Passing:      1                                                                                │
  │ Failing:      0                                                                                │
  │ Pending:      0                                                                                │
  │ Skipped:      0                                                                                │
  │ Screenshots:  0                                                                                │
  │ Video:        true                                                                             │
  │ Duration:     2 seconds                                                                        │
  │ Spec Ran:     app.cy.ts                                                                        │
  └────────────────────────────────────────────────────────────────────────────────────────────────┘


  (Video)

  -  Started processing:  Compressing to 32 CRF                                                     
  -  Finished processing: /Users/tokudashinnosuke/VSCode/nx-nextjs-workspace-poc/dist    (2 seconds)
                          /cypress/apps/sample-app-e2e/videos/app.cy.ts.mp4                         


====================================================================================================

  (Run Finished)


       Spec                                              Tests  Passing  Failing  Pending  Skipped  
  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ ✔  app.cy.ts                                00:02        1        1        -        -        - │
  └────────────────────────────────────────────────────────────────────────────────────────────────┘
    ✔  All specs passed!                        00:02        1        1        -        -        -  


 ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

 >  NX   Successfully ran target e2e for project sample-app-e2e (107ms)

上記は2度目の実行なのでキャッシュが効いていてありえないくらい速いが、e2eはまぁそんなに体感するほどの速さはなかった。ただキャッシュ効いているので開発中はありがたいと思う。

tokku5552tokku5552

Nx ConsoleというVSCodeの拡張機能が公式に用意されていて、コマンドリファレンスを見なくてもなんとなく実行できてしまうのも良さげ。
コンポーネントを追加してみる。

適当に値を入れたら勝手にdry-runが走って何が作られるのか教えてくれる。

tokku5552tokku5552

nxのcdkに関するプラグインはコミュニティのものが2つ

https://github.com/adrian-goe/nx-aws-cdk-v2

https://github.com/codebrewlab/nx-plugins/tree/main/packages/nx-aws-cdk

v2がついていない方はv1なので、実質1種類しかない。
cdkのコマンドが微妙に用意されていない。

project.json
...
targets": {
    "deploy": {
      "executor": "@ago-dev/nx-aws-cdk-v2:deploy",
      "options": {}
    },
    "destroy": {
      "executor": "@ago-dev/nx-aws-cdk-v2:destroy",
      "options": {}
    },
    "bootstrap": {
      "executor": "@ago-dev/nx-aws-cdk-v2:bootstrap",
      "options": {}
    },
    "lint": {
      "executor": "@nrwl/linter:eslint",
      "outputs": ["{options.outputFile}"],
      "options": {
        "lintFilePatterns": ["apps/sample-app-cdk/**/*.ts"]
      }
    },
...

cdk synthがないので、現状ではCodePipelineには載せられない?

tokku5552tokku5552

pluginを自作しないと無理なのかと思ってここ数日色々調べまくってたけど、project.jsonにちょっと追記するだけで行けた。

...
"targets": {
    "synth": {
      "executor": "nx:run-commands",
      "options": { "command": "cdk synth", "cwd": "apps/sample-app-cdk" }
    },