📦

[CDK]とりあえずProjenのコマンド一通り叩いてみた

2024/05/25に公開

周回遅れでprojenを勉強

いつだったか忘れてしまうくらい前に少し気にしていたものの、その後放ったらかしだったprojenへの興味をもう少し先に進めてみようと思い触ってみる事にしました。

お読みいただいた方の学びが多い内容になっている記事とは言い難いですが、こんな感じなのねと一緒に見て貰えれば幸いです。

ページの最後にわかりやすい記事のリンクを貼ってあります。そちらも合わせてご覧ください。

https://projen.io/
https://github.com/projen/projen
https://aws.amazon.com/jp/blogs/news/getting-started-with-projen-and-aws-cdk/

Projen のメリットと課題
メリット

一貫性: Projen を使用することで、標準的なプロジェクトテンプレートを定義できるため、異なるプロジェクト間での一貫性を確保できます。異なるプロジェクト生成ツールを使用する必要がなく、Projen のみを使用できます。
バージョン管理: プロジェクト設定がコードで定義されているため、変更履歴の追跡や他者とのコラボレーションが容易になります。
拡張性: Projen は、さまざまなプラグインと拡張機能をサポートしているため、特定のニーズに合わせてプロジェクト設定をカスタマイズできます。
AWS CDK との統合: Projen は AWS CDK とのシームレスな統合を提供し、クラウドリソースの定義とデプロイプロセスを簡略化します。
多言語対応 CDK コンストラクトライブラリ: 一度のビルドによって、複数のランタイムで実行できます。Projen は、TypeScript で開発された CDK コンストラクトを、JSII のサポートにより Java (Maven) や Python (PyPI) に変換および公開できます。
API ドキュメント: CDK コンストラクトの構築時には、コメントから API ドキュメントを生成します。

課題

Microsoft Windows のサポート。Projen が Windows 環境で完全に動作しないという未解決の issue がいくつかあります (https://github.com/projen/projen/issues/2427https://github.com/projen/projen/issues/498)。
フレームワークの Projen は、アーキテクチャ、ベストプラクティス、規約についてのいくつかの前提が存在します。
Projen はまだ GA (General Availability、正式リリース版) ではなく、この記事を書いている時点でのバージョンは v0.77.5 です。


記事にあった手順をとりあえず試してみる

projen new awscdk-app-ts

任意のフォルダを作成し、中でprojen new awscdk-app-tsコマンド実行します。

$ mkdir testProject && cd testProject && npx projen new awscdk-app-ts

Need to install the following packages:
projen@0.81.15
Ok to proceed? (y) y
👾 Project definition file was created at /Users/hoge/testProject/.projenrc.ts
👾 Installing dependencies...
👾 install | yarn install --check-files
yarn install v1.22.19
info No lockfile found.
[1/4] 🔍  Resolving packages...
warning eslint > file-entry-cache > flat-cache > rimraf > glob > inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
warning projen > glob > inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
warning Your current version of Yarn is out of date. The latest version is "1.22.22", while you're on "1.22.19".
info To upgrade, run the following command:
$ curl --compressed -o- -L https://yarnpkg.com/install.sh | bash
✨  Done in 45.73s.
👾 Installing dependencies...
👾 install | yarn install --check-files
yarn install v1.22.19
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
✨  Done in 5.28s.

> testProject@0.0.0 eslint
> npx projen eslint

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

WARNING: You are currently running a version of TypeScript which is not officially supported by @typescript-eslint/typescript-estree.

You may find that it works just fine, or you may not.

SUPPORTED TYPESCRIPT VERSIONS: >=4.3.5 <5.4.0

YOUR TYPESCRIPT VERSION: 5.4.5

Please only submit bug reports when using the officially supported version.

=============
Initialized empty Git repository in /Users/hoge/testProject/.git/
[main (root-commit) 69140b5] chore: project created with projen
 22 files changed, 5471 insertions(+)
 create mode 100644 .eslintrc.json
 create mode 100644 .gitattributes
 create mode 100644 .github/pull_request_template.md
 create mode 100644 .github/workflows/build.yml
 create mode 100644 .github/workflows/pull-request-lint.yml
 create mode 100644 .github/workflows/upgrade.yml
 create mode 100644 .gitignore
 create mode 100644 .mergify.yml
 create mode 100644 .npmignore
 create mode 100644 .projen/deps.json
 create mode 100644 .projen/files.json
 create mode 100644 .projen/tasks.json
 create mode 100644 .projenrc.ts
 create mode 100644 LICENSE
 create mode 100644 README.md
 create mode 100644 cdk.json
 create mode 100644 package.json
 create mode 100644 src/main.ts
 create mode 100644 test/main.test.ts
 create mode 100644 tsconfig.dev.json
 create mode 100644 tsconfig.json
 create mode 100644 yarn.lock

🔻
完了しました。
VS Codeで開いてみます。

$ code .

🔻
以下構成となりました。

🔻
以下ファイルに変更を入れます。

projenrc.ts
name: 'testProject2', //2を追加

🔻

projen

公式ドキュメントによると今回のようにしてprojenコマンドを実行するとすべてのファイルを再生成→変更をかけた値の更新を行ってくれるとの事です。

$ npx projen
👾 default | ts-node --project tsconfig.dev.json .projenrc.ts
👾 Installing dependencies...
👾 install | yarn install --check-files
yarn install v1.22.19
[1/4] 🔍  Resolving packages...
success Already up-to-date.
✨  Done in 0.99s.

🔻
package.jsonで反映が確認出来ました。

package.json
{
  "name": "testProject2",
//以下省略(jsonコメント書けない認識ですがお許しを。)

🔻
ちょっとスタック名気持ち悪い事になっていますが、そのまま進めます。
手順通りS3リソースを追加します。

main.ts
import { App, CfnOutput, Stack, StackProps } from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';

export class MyStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps = {}) {
    super(scope, id, props);

    const bucket = new s3.Bucket(this, 'MyBucket', {
      versioned: true,
    });

    new CfnOutput(this, 'TestBucket', { value: bucket.bucketArn });
  }
}

// for development, use account/region from cdk cli
const devEnv = {
  account: process.env.CDK_DEFAULT_ACCOUNT,
  region: process.env.CDK_DEFAULT_REGION,
};

const app = new App();

new MyStack(app, 'testProject-dev', { env: devEnv });
// new MyStack(app, 'testProject-prod', { env: prodEnv });

app.synth();

🔻
既にBootStrapしているのでリージョンにToolKitはありますが、手順通り実行します。

$ npx cdk bootstrap
 ⏳  Bootstrapping environment aws://012345678901/ap-northeast-1...
Trusted accounts for deployment: (none)
Trusted accounts for lookup: (none)
Using default execution policy of 'arn:aws:iam::aws:policy/AdministratorAccess'. Pass '--cloudformation-execution-policies' to customize.
CDKToolkit: creating CloudFormation changeset...
 ✅  Environment aws://012345678901/ap-northeast-1 bootstrapped.

🔻

projen build

Buildします。

$ npx projen build
👾 build » default | ts-node --project tsconfig.dev.json .projenrc.ts
👾 build » post-compile » synth:silent | cdk synth -q

👾 build » test | jest --passWithNoTests --updateSnapshot
 PASS  test/main.test.ts
  ✓ Snapshot (19 ms)1 snapshot written.
----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |
 main.ts  |     100 |      100 |     100 |     100 |
----------|---------|----------|---------|---------|-------------------
Snapshot Summary
 › 1 snapshot written from 1 test suite.

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   1 written, 1 total
Time:        3.923 s
Ran all test suites.
👾 build » test » eslint | eslint --ext .ts,.tsx --fix --no-error-on-unmatched-pattern  src test build-tools projenrc .projenrc.ts
=============

🔻

projen deploy

Deployします。

$ npx projen deploy
👾 deploy | cdk deploy

✨  Synthesis time: 4.17s

testProject-dev:  start: Building xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:012345678901-ap-northeast-1
testProject-dev:  success: Built xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:012345678901-ap-northeast-1a
testProject-dev:  start: Publishing xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:012345678901-ap-northeast-1
testProject-dev:  success: Published xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:012345678901-ap-northeast-1
testProject-dev: deploying... [1/1]
testProject-dev: creating CloudFormation changeset...

 ✅  testProject-dev

✨  Deployment time: 40.8s

Outputs:
testProject-dev.TestBucket = arn:aws:s3:::testproject-dev-mybucketXXXXXXXX-plfizqkimruk
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:012345678901:stack/testProject-dev/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx

✨  Total time: 44.97s

🔻
完了したので結果を見てみます。

open https://ap-northeast-1.console.aws.amazon.com/cloudformation/

🔻
無事作成されました。

🔻

projen destroy

確認済んだので片付けます。

npx projen destroy
👾 destroy | cdk destroy

Are you sure you want to delete: testProject-dev (y/n)? y
testProject-dev: destroying... [1/1]

 ✅  testProject-dev: destroyed

記事内の体験手順は終わりです。


その他のコマンドも確認

まずは--helpを表示

npx projen --help
projen [command]

Commands:
  projen new [PROJECT-TYPE-NAME] [OPTIONS]  Creates a new projen project

                                            For a complete list of the available options for a
                                            specific project type, run:
                                            projen new [PROJECT-TYPE-NAME] --help
  projen build                              Full release build
  projen bundle                             Prepare assets
  projen clobber                            hard resets to HEAD of origin and cleans the local repo
  projen compile                            Only compile
  projen default                            Synthesize project files
  projen deploy                             Deploys your CDK app to the AWS cloud
  projen destroy                            Destroys your cdk app in the AWS cloud
  projen diff                               Diffs the currently deployed app against your code
  projen eject                              Remove projen from the project
  projen eslint                             Runs eslint against the codebase
  projen install                            Install project dependencies and update lockfile
                                            (non-frozen)
  projen install:ci                         Install project dependencies using frozen lockfile
  projen package                            Creates the distribution package
  projen post-compile                       Runs after successful compilation
  projen post-upgrade                       Runs after upgrading dependencies
  projen pre-compile                        Prepare the project for compilation
  projen synth                              Synthesizes your cdk app into cdk.out
  projen synth:silent                       Synthesizes your cdk app into cdk.out and suppresses
                                            the template in stdout (part of "yarn build")
  projen test                               Run tests
  projen test:watch                         Run jest in watch mode
  projen upgrade                            upgrade dependencies
  projen watch                              Watches changes in your source code and rebuilds and
                                            deploys to the current account
  projen completion                         generate completion script

Options:
      --post     Run post-synthesis steps such as installing dependencies. Use --no-post to skip
                                                                          [boolean] [default: true]
  -w, --watch    Keep running and resynthesize when projenrc changes     [boolean] [default: false]
      --debug    Debug logs                                              [boolean] [default: false]
      --rc       path to .projenrc.js file
               [deprecated] [string] [default: "/Users/hoge/testProject/.projenrc.js"]
      --help     Show help                                                                [boolean]
      --version  Show version number

馴染みのありそうな響きのものから実行していきます。
この時点で表示されているコマンドを本当に実行してみるだけになります。
何も結果が返ってないもの等説明文から適宜想像ください。

projen diff

Diffs the currently deployed app against your code
現在デプロイされているアプリとあなたのコードを比較します。

$  npx projen diff
👾 diff | cdk diff
Stack testProject-dev
Parameters
[+] Parameter BootstrapVersion BootstrapVersion: {"Type":"AWS::SSM::Parameter::Value<String>","Default":"/cdk-bootstrap/hnb659fds/version","Description":"Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"}

Resources
[+] AWS::S3::Bucket MyBucket MyBucketXXXXXXXX

Outputs
[+] Output TestBucket TestBucket: {"Value":{"Fn::GetAtt":["MyBucketXXXXXXXX","Arn"]}}

Other Changes
[+] Unknown Rules: {"CheckBootstrapVersion":{"Assertions":[{"Assert":{"Fn::Not":[{"Fn::Contains":[["1","2","3","4","5"],{"Ref":"BootstrapVersion"}]}]},"AssertDescription":"CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."}]}}


✨  Number of stacks with differences: 1

projen synth

Synthesizes your cdk app into cdk.out
cdkアプリをcdk.outに合成する

$ npx projen synth
👾 synth | cdk synth
Resources:
  MyBucketF68F3FF0:
    Type: AWS::S3::Bucket
    Properties:
      VersioningConfiguration:
        Status: Enabled
    UpdateReplacePolicy: Retain
    DeletionPolicy: Retain
Outputs:
  TestBucket:
    Value:
      Fn::GetAtt:
        - MyBucketF68F3FF0
        - Arn

※MetaDataやBootstrap ver排出はこのタイミングで抑制

projen synth:silent

Synthesizes your cdk app into cdk.out and suppresses
cdkアプリをcdk.outに合成し、以下を抑制します。

$ npx projen synth:silent
👾 synth:silent | cdk synth -q

projen test

Run tests
テストの実行

$ npx projen test
👾 test | jest --passWithNoTests --updateSnapshot
 PASS  test/main.test.ts
  ✓ Snapshot (23 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |
 main.ts  |     100 |      100 |     100 |     100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   1 passed, 1 total
Time:        4.237 s
Ran all test suites.
👾 test » eslint | eslint --ext .ts,.tsx --fix --no-error-on-unmatched-pattern  src test build-tools projenrc .projenrc.ts
=============

projen test:watch

Run jest in watch mode
ウォッチモードでjestを実行する

$ npx projen test:watch
 PASS  test/main.test.ts
  ✓ Snapshot (27 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |
 main.ts  |     100 |      100 |     100 |     100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   1 passed, 1 total
Time:        3.777 s, estimated 5 s
Ran all test suites related to changed files.

Watch Usage
 › Press a to run all tests.
 › Press f to run only failed tests.
 › Press p to filter by a filename regex pattern.
 › Press t to filter by a test name regex pattern.
 › Press q to quit watch mode.
 › Press Enter to trigger a test run.

projen upgrade

upgrade dependencies
依存関係のアップグレード

$ npx projen upgrade
👾 upgrade | npx npm-check-updates@16 --upgrade --target=minor --peer --dep=dev,peer,prod,optional --filter=@types/jest,esbuild,eslint-import-resolver-typescript,eslint-plugin-import,jest,projen,ts-jest,ts-node,typescript
npm WARN exec The following package was not found and will be installed: npm-check-updates@16.14.20
npm WARN deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm WARN deprecated @npmcli/move-file@2.0.1: This functionality has been moved to @npmcli/fs
npm WARN deprecated are-we-there-yet@3.0.1: This package is no longer supported.
npm WARN deprecated gauge@4.0.4: This package is no longer supported.
npm WARN deprecated npmlog@6.0.2: This package is no longer supported.
npm WARN deprecated read-package-json@6.0.4: This package is no longer supported. Please use @npmcli/package-json instead.
Using yarn
Upgrading /Users/hoge/testProject/package.json
[====================] 9/9 100%

All dependencies match the minor package versions :)
👾 upgrade | yarn install --check-files
yarn install v1.22.19
[1/4] 🔍  Resolving packages...
success Already up-to-date.
✨  Done in 1.07s.
👾 upgrade | yarn upgrade @types/jest @types/node @typescript-eslint/eslint-plugin @typescript-eslint/parser aws-cdk esbuild eslint-import-resolver-typescript eslint-plugin-import eslint jest jest-junit projen ts-jest ts-node typescript aws-cdk-lib constructs
yarn upgrade v1.22.19
[1/4] 🔍  Resolving packages...
warning eslint > file-entry-cache > flat-cache > rimraf > glob > inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
warning projen > glob > inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Rebuilding all packages...
success Saved lockfile.
success Saved 354 new dependencies.
info Direct dependencies
├─ @types/jest@29.5.12
├─ @types/node@18.19.33
├─ @typescript-eslint/eslint-plugin@6.21.0
├─ @typescript-eslint/parser@6.21.0
├─ aws-cdk-lib@2.143.0
├─ aws-cdk@2.143.0
├─ constructs@10.3.0
├─ esbuild@0.21.4
├─ eslint-import-resolver-typescript@3.6.1
├─ eslint-plugin-import@2.29.1
├─ eslint@8.57.0
├─ jest-junit@15.0.0
├─ jest@29.7.0
├─ projen@0.81.15
├─ ts-jest@29.1.3
├─ ts-node@10.9.2
└─ typescript@5.4.5
info All dependencies
├─ @ampproject/remapping@2.3.0
├─ @aws-cdk/asset-awscli-v1@2.2.202
├─ @aws-cdk/asset-kubectl-v20@2.1.2
├─ @aws-cdk/asset-node-proxy-agent-v6@2.0.3
├─ @babel/compat-data@7.24.6
├─ @babel/core@7.24.6
├─ @babel/helper-compilation-targets@7.24.6
├─ @babel/helper-function-name@7.24.6
├─ @babel/helper-hoist-variables@7.24.6
├─ @babel/helper-module-imports@7.24.6
├─ @babel/helper-module-transforms@7.24.6
├─ @babel/helper-simple-access@7.24.6
├─ @babel/helper-string-parser@7.24.6
├─ @babel/helper-validator-option@7.24.6
├─ @babel/helpers@7.24.6
├─ @babel/highlight@7.24.6
├─ @babel/parser@7.24.6
├─ @babel/plugin-syntax-async-generators@7.8.4
├─ @babel/plugin-syntax-bigint@7.8.3
├─ @babel/plugin-syntax-class-properties@7.12.13
├─ @babel/plugin-syntax-import-meta@7.10.4
├─ @babel/plugin-syntax-json-strings@7.8.3
├─ @babel/plugin-syntax-jsx@7.24.6
├─ @babel/plugin-syntax-logical-assignment-operators@7.10.4
├─ @babel/plugin-syntax-nullish-coalescing-operator@7.8.3
├─ @babel/plugin-syntax-numeric-separator@7.10.4
├─ @babel/plugin-syntax-object-rest-spread@7.8.3
├─ @babel/plugin-syntax-optional-catch-binding@7.8.3
├─ @babel/plugin-syntax-optional-chaining@7.8.3
├─ @babel/plugin-syntax-top-level-await@7.14.5
├─ @babel/plugin-syntax-typescript@7.24.6
├─ @babel/template@7.24.6
├─ @babel/traverse@7.24.6
├─ @balena/dockerignore@1.0.2
├─ @bcoe/v8-coverage@0.2.3
├─ @cspotcode/source-map-support@0.8.1
├─ @esbuild/darwin-x64@0.21.4
├─ @eslint-community/eslint-utils@4.4.0
├─ @eslint-community/regexpp@4.10.0
├─ @eslint/eslintrc@2.1.4
├─ @eslint/js@8.57.0
├─ @humanwhocodes/config-array@0.11.14
├─ @humanwhocodes/module-importer@1.0.1
├─ @humanwhocodes/object-schema@2.0.3
├─ @iarna/toml@2.2.5
├─ @istanbuljs/load-nyc-config@1.1.0
├─ @jest/globals@29.7.0
├─ @jest/reporters@29.7.0
├─ @jest/source-map@29.6.3
├─ @jest/test-sequencer@29.7.0
├─ @jridgewell/resolve-uri@3.1.2
├─ @jridgewell/set-array@1.2.1
├─ @nodelib/fs.scandir@2.1.5
├─ @nodelib/fs.stat@2.0.5
├─ @nodelib/fs.walk@1.2.8
├─ @oozcitak/dom@1.15.10
├─ @oozcitak/url@1.0.4
├─ @sinclair/typebox@0.27.8
├─ @sinonjs/commons@3.0.1
├─ @sinonjs/fake-timers@10.3.0
├─ @tsconfig/node10@1.0.11
├─ @tsconfig/node12@1.0.11
├─ @tsconfig/node14@1.0.3
├─ @tsconfig/node16@1.0.4
├─ @types/babel__generator@7.6.8
├─ @types/babel__template@7.4.4
├─ @types/babel__traverse@7.20.6
├─ @types/graceful-fs@4.1.9
├─ @types/istanbul-lib-coverage@2.0.6
├─ @types/istanbul-lib-report@3.0.3
├─ @types/istanbul-reports@3.0.4
├─ @types/jest@29.5.12
├─ @types/json-schema@7.0.15
├─ @types/json5@0.0.29
├─ @types/node@18.19.33
├─ @types/semver@7.5.8
├─ @types/stack-utils@2.0.3
├─ @types/yargs-parser@21.0.3
├─ @types/yargs@17.0.32
├─ @typescript-eslint/eslint-plugin@6.21.0
├─ @typescript-eslint/parser@6.21.0
├─ @typescript-eslint/type-utils@6.21.0
├─ @ungap/structured-clone@1.2.0
├─ acorn-jsx@5.3.2
├─ acorn-walk@8.3.2
├─ acorn@8.11.3
├─ ansi-regex@5.0.1
├─ anymatch@3.1.3
├─ arg@4.1.3
├─ argparse@1.0.10
├─ array-includes@3.1.8
├─ array-timsort@1.0.3
├─ array-union@2.1.0
├─ array.prototype.findlastindex@1.2.5
├─ array.prototype.flat@1.3.2
├─ array.prototype.flatmap@1.3.2
├─ arraybuffer.prototype.slice@1.0.3
├─ astral-regex@2.0.0
├─ aws-cdk-lib@2.143.0
├─ aws-cdk@2.143.0
├─ babel-jest@29.7.0
├─ babel-plugin-jest-hoist@29.6.3
├─ babel-preset-jest@29.6.3
├─ braces@3.0.3
├─ browserslist@4.23.0
├─ bs-logger@0.2.6
├─ bser@2.1.1
├─ buffer-from@1.1.2
├─ camelcase@6.3.0
├─ caniuse-lite@1.0.30001621
├─ case@1.6.3
├─ chalk@4.1.2
├─ char-regex@1.0.2
├─ cjs-module-lexer@1.3.1
├─ cliui@8.0.1
├─ co@4.6.0
├─ color-convert@2.0.1
├─ color-name@1.1.4
├─ comment-json@4.2.2
├─ concat-map@0.0.1
├─ constructs@10.3.0
├─ conventional-changelog-config-spec@2.1.0
├─ core-util-is@1.0.3
├─ create-jest@29.7.0
├─ create-require@1.1.1
├─ cross-spawn@7.0.3
├─ data-view-buffer@1.0.1
├─ data-view-byte-length@1.0.1
├─ data-view-byte-offset@1.0.0
├─ dedent@1.5.3
├─ deep-is@0.1.4
├─ deepmerge@4.3.1
├─ detect-newline@3.1.0
├─ diff-sequences@29.6.3
├─ diff@4.0.2
├─ dir-glob@3.0.1
├─ doctrine@2.1.0
├─ electron-to-chromium@1.4.783
├─ emoji-regex@8.0.0
├─ enhanced-resolve@5.16.1
├─ error-ex@1.3.2
├─ es-abstract@1.23.3
├─ es-set-tostringtag@2.0.3
├─ es-to-primitive@1.2.1
├─ esbuild@0.21.4
├─ escalade@3.1.2
├─ escape-string-regexp@4.0.0
├─ eslint-import-resolver-node@0.3.9
├─ eslint-import-resolver-typescript@3.6.1
├─ eslint-module-utils@2.8.1
├─ eslint-plugin-import@2.29.1
├─ eslint-scope@7.2.2
├─ eslint@8.57.0
├─ espree@9.6.1
├─ esprima@4.0.1
├─ esquery@1.5.0
├─ esrecurse@4.3.0
├─ execa@5.1.1
├─ fast-glob@3.3.2
├─ fast-json-patch@3.1.1
├─ fast-levenshtein@2.0.6
├─ fastq@1.17.1
├─ fb-watchman@2.0.2
├─ file-entry-cache@6.0.1
├─ fill-range@7.1.1
├─ find-up@4.1.0
├─ flat-cache@3.2.0
├─ flatted@3.3.1
├─ fs-extra@11.2.0
├─ fsevents@2.3.2
├─ function.prototype.name@1.1.6
├─ gensync@1.0.0-beta.2
├─ get-caller-file@2.0.5
├─ get-package-type@0.1.0
├─ get-stream@6.0.1
├─ get-symbol-description@1.0.2
├─ get-tsconfig@4.7.5
├─ glob-parent@6.0.2
├─ glob@7.2.3
├─ globalthis@1.0.4
├─ globby@11.1.0
├─ graceful-fs@4.2.11
├─ has-bigints@1.0.2
├─ has-own-prop@2.0.0
├─ has-symbols@1.0.3
├─ html-escaper@2.0.2
├─ human-signals@2.1.0
├─ ignore@5.3.1
├─ import-fresh@3.3.0
├─ ini@2.0.0
├─ internal-slot@1.0.7
├─ interpret@1.4.0
├─ is-arrayish@0.2.1
├─ is-bigint@1.0.4
├─ is-boolean-object@1.1.2
├─ is-callable@1.2.7
├─ is-date-object@1.0.5
├─ is-extglob@2.1.1
├─ is-generator-fn@2.1.0
├─ is-negative-zero@2.0.3
├─ is-number-object@1.0.7
├─ is-number@7.0.0
├─ is-path-inside@3.0.3
├─ is-shared-array-buffer@1.0.3
├─ is-stream@2.0.1
├─ is-string@1.0.7
├─ is-symbol@1.0.4
├─ is-weakref@1.0.2
├─ isarray@2.0.5
├─ isexe@2.0.0
├─ istanbul-lib-instrument@6.0.2
├─ istanbul-lib-source-maps@4.0.1
├─ istanbul-reports@3.1.7
├─ jest-changed-files@29.7.0
├─ jest-circus@29.7.0
├─ jest-cli@29.7.0
├─ jest-docblock@29.7.0
├─ jest-each@29.7.0
├─ jest-junit@15.0.0
├─ jest-leak-detector@29.7.0
├─ jest-pnp-resolver@1.2.3
├─ jest-resolve-dependencies@29.7.0
├─ jest-util@29.7.0
├─ jest@29.7.0
├─ js-tokens@4.0.0
├─ js-yaml@3.14.1
├─ jsesc@2.5.2
├─ json-buffer@3.0.1
├─ json-parse-even-better-errors@2.3.1
├─ json-schema-traverse@0.4.1
├─ json-stable-stringify-without-jsonify@1.0.1
├─ jsonfile@6.1.0
├─ jsonschema@1.4.1
├─ keyv@4.5.4
├─ kleur@3.0.3
├─ leven@3.1.0
├─ lines-and-columns@1.2.4
├─ locate-path@5.0.0
├─ lodash.memoize@4.1.2
├─ lodash.merge@4.6.2
├─ lodash.truncate@4.4.2
├─ lru-cache@5.1.1
├─ make-dir@4.0.0
├─ make-error@1.3.6
├─ makeerror@1.0.12
├─ merge2@1.4.1
├─ mime-db@1.52.0
├─ mime-types@2.1.35
├─ mimic-fn@2.1.0
├─ minimist@1.2.8
├─ mkdirp@1.0.4
├─ ms@2.1.2
├─ node-int64@0.4.0
├─ node-releases@2.0.14
├─ normalize-path@3.0.0
├─ npm-run-path@4.0.1
├─ object.assign@4.1.5
├─ object.fromentries@2.0.8
├─ object.groupby@1.0.3
├─ object.values@1.2.0
├─ onetime@5.1.2
├─ optionator@0.9.4
├─ p-locate@4.1.0
├─ p-try@2.2.0
├─ parent-module@1.0.1
├─ parse-json@5.2.0
├─ path-is-absolute@1.0.1
├─ path-key@3.1.1
├─ path-parse@1.0.7
├─ path-type@4.0.0
├─ picocolors@1.0.1
├─ picomatch@2.3.1
├─ pirates@4.0.6
├─ pkg-dir@4.2.0
├─ projen@0.81.15
├─ prompts@2.4.2
├─ punycode@2.3.1
├─ pure-rand@6.1.0
├─ queue-microtask@1.2.3
├─ react-is@18.3.1
├─ rechoir@0.6.2
├─ regexp.prototype.flags@1.5.2
├─ repeat-string@1.6.1
├─ require-directory@2.1.1
├─ require-from-string@2.0.2
├─ resolve-cwd@3.0.0
├─ resolve-pkg-maps@1.0.0
├─ resolve.exports@2.0.2
├─ resolve@1.22.8
├─ reusify@1.0.4
├─ rimraf@3.0.2
├─ run-parallel@1.2.0
├─ safe-array-concat@1.1.2
├─ safe-regex-test@1.0.3
├─ semver@7.6.2
├─ set-function-length@1.2.2
├─ set-function-name@2.0.2
├─ shebang-command@2.0.0
├─ shebang-regex@3.0.0
├─ shelljs@0.8.5
├─ shx@0.3.4
├─ side-channel@1.0.6
├─ signal-exit@3.0.7
├─ sisteransi@1.0.5
├─ slice-ansi@4.0.0
├─ source-map-support@0.5.13
├─ source-map@0.6.1
├─ sprintf-js@1.0.3
├─ string.prototype.trim@1.2.9
├─ string.prototype.trimend@1.0.8
├─ string.prototype.trimstart@1.0.8
├─ strip-bom@3.0.0
├─ strip-final-newline@2.0.0
├─ supports-preserve-symlinks-flag@1.0.0
├─ table@6.8.2
├─ tapable@2.2.1
├─ test-exclude@6.0.0
├─ text-table@0.2.0
├─ tmpl@1.0.5
├─ to-fast-properties@2.0.0
├─ to-regex-range@5.0.1
├─ ts-jest@29.1.3
├─ ts-node@10.9.2
├─ tsconfig-paths@3.15.0
├─ type-check@0.4.0
├─ type-detect@4.0.8
├─ type-fest@0.20.2
├─ typed-array-buffer@1.0.2
├─ typed-array-byte-length@1.0.1
├─ typed-array-byte-offset@1.0.2
├─ typed-array-length@1.0.6
├─ typescript@5.4.5
├─ unbox-primitive@1.0.2
├─ update-browserslist-db@1.0.16
├─ uri-js@4.4.1
├─ uuid@8.3.2
├─ v8-compile-cache-lib@3.0.1
├─ v8-to-istanbul@9.2.0
├─ walker@1.0.8
├─ which-boxed-primitive@1.0.2
├─ which-typed-array@1.1.15
├─ which@2.0.2
├─ word-wrap@1.2.5
├─ wrap-ansi@7.0.0
├─ write-file-atomic@4.0.2
├─ xml@1.0.1
├─ xmlbuilder2@3.1.1
├─ y18n@5.0.8
├─ yallist@3.1.1
├─ yaml@1.10.2
├─ yargs-parser@21.1.1
├─ yargs@17.7.2
├─ yn@3.1.1
└─ yocto-queue@0.1.0
✨  Done in 29.14s.
👾 upgrade | npx projen
👾 default | ts-node --project tsconfig.dev.json .projenrc.ts

projen watch

Watches changes in your source code and rebuilds and deploys to the current account
公式ドキュメントにもこうありました。

$ npx projen watch
👾 watch | cdk deploy --hotswap

✨  Synthesis time: 4.15s

⚠️ The --hotswap and --hotswap-fallback flags deliberately introduce CloudFormation drift to speed up deployments
⚠️ They should only be used for development - never use them for your production Stacks!

testProject-dev: deploying... [1/1]

 ✨ hotswap deployment skipped - no changes were detected (use --force to override)


 ✅  testProject-dev (no changes)

✨  Deployment time: 0.73s

Outputs:
testProject-dev.TestBucket = arn:aws:s3:::testproject-dev-mybucketXXXXXXXX-wqpj5o9i0ryv
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:0123456789:stack/testProject-dev/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

✨  Total time: 4.89s

projen completion

generate completion script
完了スクリプトの生成

$ npx projen completion
###-begin-projen-completions-###
#
# yargs command completion script
#
# Installation: /Users/hoge/testProject/node_modules/.bin/projen completion >> ~/.bashrc
#    or /Users/hoge/testProject/node_modules/.bin/projen completion >> ~/.bash_profile on OSX.
#
_projen_yargs_completions()
{
    local cur_word args type_list

    cur_word="${COMP_WORDS[COMP_CWORD]}"
    args=("${COMP_WORDS[@]}")

    # ask yargs to generate completions.
    type_list=$(/Users/hoge/testProject/node_modules/.bin/projen --get-yargs-completions "${args[@]}")

    COMPREPLY=( $(compgen -W "${type_list}" -- ${cur_word}) )

    # if no match was found, fall back to filename completion
    if [ ${#COMPREPLY[@]} -eq 0 ]; then
      COMPREPLY=()
    fi

    return 0
}
complete -o bashdefault -o default -F _projen_yargs_completions projen
###-end-projen-completions-###

projen bundle

Prepare assets
アセットの準備

$  npx projen bundle

projen clobber

hard resets to HEAD of origin
オリジンのHEADのハードリセット

$ npx projen clobber
👾 clobber | condition: git diff --exit-code > /dev/null
👾 clobber | condition exited with non-zero - skipping

projen compile

Only compile
コンパイルのみ

$ npx projen compile

projen default

Synthesize project files
プロジェクトファイルを合成する

$ npx projen default
👾 default | ts-node --project tsconfig.dev.json .projenrc.ts

projen eslint

Runs eslint against the codebase
コードベースに対してeslintを実行する。

$ npx projen eslint
👾 eslint | eslint --ext .ts,.tsx --fix --no-error-on-unmatched-pattern  src test build-tools projenrc .projenrc.ts
=============

projen install

Install project dependencies and update lockfile
プロジェクトの依存関係をインストールし、ロックファイルを更新する

$ npx projen install
👾 install | yarn install --check-files
yarn install v1.22.19
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...

✨  Done in 3.58s.

projen install:ci

Install project dependencies using frozen lockfile
凍結されたロックファイルを使ってプロジェクトの依存関係をインストールする

$ npx projen install:ci
👾 install:ci | yarn install --check-files --frozen-lockfile
yarn install v1.22.19
[1/4] 🔍  Resolving packages...
success Already up-to-date.
✨  Done in 1.03s.

projen package

Creates the distribution package
配布パッケージを作成する

$ npx projen package

projen post-compile

Runs after successful compilation
コンパイル成功後に実行

$ npx projen post-compile
👾 post-compile » synth:silent | cdk synth -q

projen post-upgrade

Runs after upgrading dependencies
依存関係のアップグレード後に実行

$ npx projen post-upgrade

projen pre-compile

Prepare the project for compilation
プロジェクトのコンパイルの準備

$ npx projen pre-compile

projen eject

Remove projen from the project
プロジェクトからprojenを削除する

$ npx projen eject
👾 eject » default | ts-node --project tsconfig.dev.json .projenrc.ts
👾 Installing dependencies...
👾 install | yarn install --check-files
yarn install v1.22.19
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...

success Saved lockfile.
✨  Done in 3.62s.

終わりに

この後ドキュメントを一通り読んでみました。
依然として理解したと胸を張れるレベルでない為引き続き勉強して使えるレベルまで引き上げていきたいと思います。


projenについて書いてある記事

https://qiita.com/hayao_k/items/194dfb051f18a38b6dbd
https://dev.classmethod.jp/articles/cdk-day-projen-try/
https://dev.classmethod.jp/articles/cdk-app-dev-projen/
https://qiita.com/ufoo68/items/162c0e91f959a03ea268
https://zenn.dev/lea/articles/c8d61bc5351c1a
https://dev.to/jolodev/thoughts-about-projen-5fi6

Discussion