From 618c435f127800ceeecd0f9b0f45cb89967e3c75 Mon Sep 17 00:00:00 2001 From: lukqw Date: Tue, 3 Dec 2024 14:51:05 +0100 Subject: [PATCH 1/3] add hotreloading capabilities --- Makefile | 14 +++ package.json | 1 + packages/backend/package.json | 4 +- packages/infra/cdk/notes-api.ts | 11 ++- yarn.lock | 170 +++++++++++++++++++++++++++++++- 5 files changed, 192 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 511e63c..14b561e 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,9 @@ install: build: yarn && yarn build:backend; +hotreload: + yarn && yarn hotreload:backend; + bootstrap: yarn cdklocal bootstrap; @@ -34,6 +37,9 @@ prepare-frontend-local: build-frontend: yarn build:frontend +start-frontend: + yarn start:frontend + bootstrap-frontend: yarn cdklocal bootstrap --app="node dist/aws-sdk-js-notes-app-frontend.js"; @@ -54,4 +60,12 @@ ready: logs: @localstack logs > logs.txt +setup-challenge: + yarn install + make build + make bootstrap + make deploy + make prepare-frontend-local + make hotreload + .PHONY: usage install run start stop ready logs diff --git a/package.json b/package.json index 2dec396..2dd3914 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "cdk": "cd packages/infra && yarn cdk", "cdklocal": "cd packages/infra && yarn cdklocal", "build:backend": "cd packages/backend && yarn build", + "hotreload:backend": "cd packages/backend && yarn hotreload", "prepare:frontend": "node packages/scripts/populate-frontend-config.js", "prepare:frontend-local": "node packages/scripts/populate-frontend-config.js --local", "build:frontend": "cd packages/frontend && yarn build", diff --git a/packages/backend/package.json b/packages/backend/package.json index 9e0a355..e02ef62 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -5,11 +5,13 @@ "description": "Backend for notes app created using modular AWS SDK for JavaScript", "dependencies": { "@aws-sdk/client-dynamodb": "3.245.0", - "@aws-sdk/util-dynamodb": "3.245.0" + "@aws-sdk/util-dynamodb": "3.245.0", + "nodemon": "^3.1.7" }, "scripts": { "build": "tsc --noEmit && node build.js", "build:backend": "cd .. && yarn build:backend", + "hotreload": "nodemon --watch src --ext '*' --exec 'node build.js'", "cdk": "cd .. && yarn cdk" }, "keywords": [ diff --git a/packages/infra/cdk/notes-api.ts b/packages/infra/cdk/notes-api.ts index 5608708..9ecfb39 100644 --- a/packages/infra/cdk/notes-api.ts +++ b/packages/infra/cdk/notes-api.ts @@ -1,4 +1,8 @@ -import { aws_dynamodb as dynamodb, aws_lambda as lambda } from "aws-cdk-lib"; +import { + aws_dynamodb as dynamodb, + aws_lambda as lambda, + aws_s3 as s3, +} from "aws-cdk-lib"; import { Construct } from "constructs"; export interface NotesApiProps { @@ -21,7 +25,10 @@ export class NotesApi extends Construct { runtime: lambda.Runtime.NODEJS_18_X, handler: "app.handler", // ToDo: find a better way to pass lambda code - code: lambda.Code.fromAsset(`../backend/dist/${id}`), + code: lambda.Code.fromBucket( + s3.Bucket.fromBucketName(this, "hot-reload", "hot-reload"), + `${__dirname}/../../backend/dist/${id}` + ), environment: { NOTES_TABLE_NAME: table.tableName, }, diff --git a/yarn.lock b/yarn.lock index afc1442..6ccb844 100644 --- a/yarn.lock +++ b/yarn.lock @@ -158,6 +158,7 @@ __metadata: "@typescript-eslint/parser": ^5.48.1 esbuild: 0.12.17 eslint: ^8.31.0 + nodemon: ^3.1.7 typescript: ~4.9.4 languageName: unknown linkType: soft @@ -2505,6 +2506,16 @@ __metadata: languageName: node linkType: hard +"anymatch@npm:~3.1.2": + version: 3.1.3 + resolution: "anymatch@npm:3.1.3" + dependencies: + normalize-path: ^3.0.0 + picomatch: ^2.0.4 + checksum: 3e044fd6d1d26545f235a9fe4d7a534e2029d8e59fa7fd9f2a6eb21230f6b5380ea1eaf55136e60cbf8e613544b3b766e7a6fa2102e2a3a117505466e3025dc2 + languageName: node + linkType: hard + "argparse@npm:^2.0.1": version: 2.0.1 resolution: "argparse@npm:2.0.1" @@ -2590,6 +2601,13 @@ __metadata: languageName: node linkType: hard +"binary-extensions@npm:^2.0.0": + version: 2.3.0 + resolution: "binary-extensions@npm:2.3.0" + checksum: bcad01494e8a9283abf18c1b967af65ee79b0c6a9e6fcfafebfe91dbe6e0fc7272bafb73389e198b310516ae04f7ad17d79aacf6cb4c0d5d5202a7e2e52c7d98 + languageName: node + linkType: hard + "bootstrap@npm:^5.3.2": version: 5.3.2 resolution: "bootstrap@npm:5.3.2" @@ -2634,6 +2652,15 @@ __metadata: languageName: node linkType: hard +"braces@npm:~3.0.2": + version: 3.0.3 + resolution: "braces@npm:3.0.3" + dependencies: + fill-range: ^7.1.1 + checksum: b95aa0b3bd909f6cd1720ffcf031aeaf46154dd88b4da01f9a1d3f7ea866a79eba76a6d01cbc3c422b2ee5cdc39a4f02491058d5df0d7bf6e6a162a832df1f69 + languageName: node + linkType: hard + "browserslist@npm:^4.21.9": version: 4.22.1 resolution: "browserslist@npm:4.22.1" @@ -2738,6 +2765,25 @@ __metadata: languageName: node linkType: hard +"chokidar@npm:^3.5.2": + version: 3.6.0 + resolution: "chokidar@npm:3.6.0" + dependencies: + anymatch: ~3.1.2 + braces: ~3.0.2 + fsevents: ~2.3.2 + glob-parent: ~5.1.2 + is-binary-path: ~2.1.0 + is-glob: ~4.0.1 + normalize-path: ~3.0.0 + readdirp: ~3.6.0 + dependenciesMeta: + fsevents: + optional: true + checksum: d2f29f499705dcd4f6f3bbed79a9ce2388cf530460122eed3b9c48efeab7a4e28739c6551fd15bec9245c6b9eeca7a32baa64694d64d9b6faeb74ddb8c4a413d + languageName: node + linkType: hard + "chownr@npm:^2.0.0": version: 2.0.0 resolution: "chownr@npm:2.0.0" @@ -2902,6 +2948,18 @@ __metadata: languageName: node linkType: hard +"debug@npm:^4": + version: 4.3.7 + resolution: "debug@npm:4.3.7" + dependencies: + ms: ^2.1.3 + peerDependenciesMeta: + supports-color: + optional: true + checksum: 822d74e209cd910ef0802d261b150314bbcf36c582ccdbb3e70f0894823c17e49a50d3e66d96b633524263975ca16b6a833f3e3b7e030c157169a5fabac63160 + languageName: node + linkType: hard + "dedent@npm:^0.7.0": version: 0.7.0 resolution: "dedent@npm:0.7.0" @@ -3523,6 +3581,15 @@ __metadata: languageName: node linkType: hard +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" + dependencies: + to-regex-range: ^5.0.1 + checksum: b4abfbca3839a3d55e4ae5ec62e131e2e356bf4859ce8480c64c4876100f4df292a63e5bb1618e1d7460282ca2b305653064f01654474aa35c68000980f17798 + languageName: node + linkType: hard + "find-up@npm:^5.0.0": version: 5.0.0 resolution: "find-up@npm:5.0.0" @@ -3696,7 +3763,7 @@ __metadata: languageName: node linkType: hard -"glob-parent@npm:^5.1.2": +"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" dependencies: @@ -3922,6 +3989,13 @@ __metadata: languageName: node linkType: hard +"ignore-by-default@npm:^1.0.1": + version: 1.0.1 + resolution: "ignore-by-default@npm:1.0.1" + checksum: 441509147b3615e0365e407a3c18e189f78c07af08564176c680be1fabc94b6c789cad1342ad887175d4ecd5225de86f73d376cec8e06b42fd9b429505ffcf8a + languageName: node + linkType: hard + "ignore@npm:^5.2.0, ignore@npm:^5.2.1": version: 5.3.0 resolution: "ignore@npm:5.3.0" @@ -4003,6 +4077,15 @@ __metadata: languageName: node linkType: hard +"is-binary-path@npm:~2.1.0": + version: 2.1.0 + resolution: "is-binary-path@npm:2.1.0" + dependencies: + binary-extensions: ^2.0.0 + checksum: 84192eb88cff70d320426f35ecd63c3d6d495da9d805b19bc65b518984b7c0760280e57dbf119b7e9be6b161784a5a673ab2c6abe83abb5198a432232ad5b35c + languageName: node + linkType: hard + "is-callable@npm:^1.1.3": version: 1.2.7 resolution: "is-callable@npm:1.2.7" @@ -4042,7 +4125,7 @@ __metadata: languageName: node linkType: hard -"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3": +"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1": version: 4.0.3 resolution: "is-glob@npm:4.0.3" dependencies: @@ -4553,6 +4636,13 @@ __metadata: languageName: node linkType: hard +"ms@npm:^2.1.3": + version: 2.1.3 + resolution: "ms@npm:2.1.3" + checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d + languageName: node + linkType: hard + "nanoid@npm:^3.3.6": version: 3.3.7 resolution: "nanoid@npm:3.3.7" @@ -4610,6 +4700,26 @@ __metadata: languageName: node linkType: hard +"nodemon@npm:^3.1.7": + version: 3.1.7 + resolution: "nodemon@npm:3.1.7" + dependencies: + chokidar: ^3.5.2 + debug: ^4 + ignore-by-default: ^1.0.1 + minimatch: ^3.1.2 + pstree.remy: ^1.1.8 + semver: ^7.5.3 + simple-update-notifier: ^2.0.0 + supports-color: ^5.5.0 + touch: ^3.1.0 + undefsafe: ^2.0.5 + bin: + nodemon: bin/nodemon.js + checksum: c500ac2feb278ddb187049ac8ede6423c1fb074cc3dabf74882568d5e93401293c10039e184a9d1bfc617c983ddb432437d396b421926914d04ebba671a7d8b8 + languageName: node + linkType: hard + "nopt@npm:^7.0.0": version: 7.2.0 resolution: "nopt@npm:7.2.0" @@ -4621,7 +4731,7 @@ __metadata: languageName: node linkType: hard -"normalize-path@npm:^3.0.0": +"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0": version: 3.0.0 resolution: "normalize-path@npm:3.0.0" checksum: 88eeb4da891e10b1318c4b2476b6e2ecbeb5ff97d946815ffea7794c31a89017c70d7f34b3c2ebf23ef4e9fc9fb99f7dffe36da22011b5b5c6ffa34f4873ec20 @@ -4792,7 +4902,7 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:^2.2.2, picomatch@npm:^2.3.1": +"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.2, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf @@ -4891,6 +5001,13 @@ __metadata: languageName: node linkType: hard +"pstree.remy@npm:^1.1.8": + version: 1.1.8 + resolution: "pstree.remy@npm:1.1.8" + checksum: 5cb53698d6bb34dfb278c8a26957964aecfff3e161af5fbf7cee00bbe9d8547c7aced4bd9cb193bce15fb56e9e4220fc02a5bf9c14345ffb13a36b858701ec2d + languageName: node + linkType: hard + "pump@npm:^3.0.0": version: 3.0.0 resolution: "pump@npm:3.0.0" @@ -5045,6 +5162,15 @@ __metadata: languageName: node linkType: hard +"readdirp@npm:~3.6.0": + version: 3.6.0 + resolution: "readdirp@npm:3.6.0" + dependencies: + picomatch: ^2.2.1 + checksum: 1ced032e6e45670b6d7352d71d21ce7edf7b9b928494dcaba6f11fba63180d9da6cd7061ebc34175ffda6ff529f481818c962952004d273178acd70f7059b320 + languageName: node + linkType: hard + "regenerator-runtime@npm:^0.14.0": version: 0.14.0 resolution: "regenerator-runtime@npm:0.14.0" @@ -5226,6 +5352,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.5.3": + version: 7.6.3 + resolution: "semver@npm:7.6.3" + bin: + semver: bin/semver.js + checksum: 4110ec5d015c9438f322257b1c51fe30276e5f766a3f64c09edd1d7ea7118ecbc3f379f3b69032bacf13116dc7abc4ad8ce0d7e2bd642e26b0d271b56b61a7d8 + languageName: node + linkType: hard + "set-function-length@npm:^1.1.1": version: 1.1.1 resolution: "set-function-length@npm:1.1.1" @@ -5268,6 +5403,15 @@ __metadata: languageName: node linkType: hard +"simple-update-notifier@npm:^2.0.0": + version: 2.0.0 + resolution: "simple-update-notifier@npm:2.0.0" + dependencies: + semver: ^7.5.3 + checksum: 9ba00d38ce6a29682f64a46213834e4eb01634c2f52c813a9a7b8873ca49cdbb703696f3290f3b27dc067de6d9418b0b84bef22c3eb074acf352529b2d6c27fd + languageName: node + linkType: hard + "slash@npm:^3.0.0": version: 3.0.0 resolution: "slash@npm:3.0.0" @@ -5429,7 +5573,7 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^5.3.0": +"supports-color@npm:^5.3.0, supports-color@npm:^5.5.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" dependencies: @@ -5498,6 +5642,15 @@ __metadata: languageName: node linkType: hard +"touch@npm:^3.1.0": + version: 3.1.1 + resolution: "touch@npm:3.1.1" + bin: + nodetouch: bin/nodetouch.js + checksum: fb8c54207500eb760b6b9d77b9c5626cc027c9ad44431eed4268845f00f8c6bbfc95ce7e9da8e487f020aa921982a8bc5d8e909d0606e82686bd0a08a8e0539b + languageName: node + linkType: hard + "tslib@npm:^1.11.1, tslib@npm:^1.8.1": version: 1.14.1 resolution: "tslib@npm:1.14.1" @@ -5589,6 +5742,13 @@ __metadata: languageName: node linkType: hard +"undefsafe@npm:^2.0.5": + version: 2.0.5 + resolution: "undefsafe@npm:2.0.5" + checksum: f42ab3b5770fedd4ada175fc1b2eb775b78f609156f7c389106aafd231bfc210813ee49f54483d7191d7b76e483bc7f537b5d92d19ded27156baf57592eb02cc + languageName: node + linkType: hard + "undici-types@npm:~5.26.4": version: 5.26.5 resolution: "undici-types@npm:5.26.5" From b7e811b7cd33e0f6167979ccbd5a6e5f85258e60 Mon Sep 17 00:00:00 2001 From: lukqw Date: Wed, 4 Dec 2024 11:31:54 +0100 Subject: [PATCH 2/3] conditionally enable hotreloading --- Makefile | 4 ++-- packages/infra/cdk/notes-api.ts | 15 ++++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 14b561e..d2b2fcc 100644 --- a/Makefile +++ b/Makefile @@ -63,8 +63,8 @@ logs: setup-challenge: yarn install make build - make bootstrap - make deploy + IS_LOCAL_DEV=true make bootstrap + IS_LOCAL_DEV=true make deploy make prepare-frontend-local make hotreload diff --git a/packages/infra/cdk/notes-api.ts b/packages/infra/cdk/notes-api.ts index 9ecfb39..f2f0fc4 100644 --- a/packages/infra/cdk/notes-api.ts +++ b/packages/infra/cdk/notes-api.ts @@ -21,14 +21,19 @@ export class NotesApi extends Construct { const { table, grantActions } = props; + const isLocalDev = process.env.IS_LOCAL_DEV; + + const codeConfig = isLocalDev + ? lambda.Code.fromBucket( + s3.Bucket.fromBucketName(this, "hot-reload", "hot-reload"), + `${__dirname}/../../backend/dist/${id}` + ) + : lambda.Code.fromAsset(`../backend/dist/${id}`); + this.handler = new lambda.Function(this, "handler", { runtime: lambda.Runtime.NODEJS_18_X, handler: "app.handler", - // ToDo: find a better way to pass lambda code - code: lambda.Code.fromBucket( - s3.Bucket.fromBucketName(this, "hot-reload", "hot-reload"), - `${__dirname}/../../backend/dist/${id}` - ), + code: codeConfig, environment: { NOTES_TABLE_NAME: table.tableName, }, From 50fbdd769db11c8a228150127ccc966ec042f9e0 Mon Sep 17 00:00:00 2001 From: lukqw Date: Wed, 4 Dec 2024 12:53:45 +0100 Subject: [PATCH 3/3] adjust check for localdev --- Makefile | 2 +- packages/infra/cdk/notes-api.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index d2b2fcc..2927237 100644 --- a/Makefile +++ b/Makefile @@ -63,7 +63,7 @@ logs: setup-challenge: yarn install make build - IS_LOCAL_DEV=true make bootstrap + make bootstrap IS_LOCAL_DEV=true make deploy make prepare-frontend-local make hotreload diff --git a/packages/infra/cdk/notes-api.ts b/packages/infra/cdk/notes-api.ts index f2f0fc4..9c12b50 100644 --- a/packages/infra/cdk/notes-api.ts +++ b/packages/infra/cdk/notes-api.ts @@ -21,7 +21,7 @@ export class NotesApi extends Construct { const { table, grantActions } = props; - const isLocalDev = process.env.IS_LOCAL_DEV; + const isLocalDev = ["true", true].includes(process.env.IS_LOCAL_DEV); const codeConfig = isLocalDev ? lambda.Code.fromBucket(