Skip to content

Commit

Permalink
fix: destroy with no bundling (#193)
Browse files Browse the repository at this point in the history
* fix: destroy with no bundling

* updated docs

* yarn build
  • Loading branch information
onhate authored Jan 4, 2024
1 parent 3fd02bb commit bc9694b
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 5 deletions.
18 changes: 18 additions & 0 deletions docs/code-deployment-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ Deep dive into `Nextjs` constructs code deployment flow - how your Next.js code
_Only applicable for PNPM Monorepos_
PNPM Monorepos use symlinks between workspace node_modules and the top level node_modules. CDK Assets do not support symlinks despite the configuration options available. Therefore, we must zip up the assets ourselves. Also, `nextjs-bucket-deployment.ts` handles symlinks to unzip and zip symlinks within Lambda Custom Resources (for ServerFnBucketDeployment).


## Conditional Build Logic

`NextjjsBuild` will use the following logic to determine if a build is required or not to proceed.

```
| bundlingRequired | skipBuild | Scenario | Action |
|------------------|-----------|---------------------------------|---------------------------------------------------|
| true | true | deploy/synth with reused bundle | no build, check .open-next exists, fail if not |
| true | false | regular deploy/synth | build, .open-next will exist |
| false | false | destroy | no build, check if .open-next exists, if not mock |
| false | true | destroy with reused bundle | no build, check if .open-next exists, if not mock |
```

*bundlingRequired* = `Stack.of(this).bundlingRequired` [see](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#bundlingrequired)
*skipBuild* = `NextjsProps.skipBuild`


Relevant GitHub Issues:
- https://github.com/aws/aws-cdk/issues/9251
- https://github.com/Stuk/jszip/issues/386#issuecomment-634773343
52 changes: 47 additions & 5 deletions src/NextjsBuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { Stack, Token } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import {
NEXTJS_BUILD_DIR,
NEXTJS_BUILD_DYNAMODB_PROVIDER_FN_DIR,
NEXTJS_BUILD_IMAGE_FN_DIR,
NEXTJS_BUILD_REVALIDATE_FN_DIR,
NEXTJS_BUILD_SERVER_FN_DIR,
NEXTJS_STATIC_DIR,
NEXTJS_CACHE_DIR,
NEXTJS_BUILD_DYNAMODB_PROVIDER_FN_DIR,
NEXTJS_STATIC_DIR,
} from './constants';
import type { NextjsProps } from './Nextjs';
import { NextjsBucketDeployment } from './NextjsBucketDeployment';
Expand Down Expand Up @@ -103,9 +103,21 @@ export class NextjsBuild extends Construct {
super(scope, id);
this.props = props;
this.validatePaths();
// when `cdk deploy "NonNextjsStack" --exclusively` is run, don't run build
if (Stack.of(this).bundlingRequired && !this.props.skipBuild) {
this.build();

const bundlingRequired = Stack.of(this).bundlingRequired;
const skipBuild = this.props.skipBuild;

// for more info see docs/code-deployment-flow.md Conditional Build Logic section
if (bundlingRequired) {
// deploy/synth
if (skipBuild) {
this.assertBuildDirExists(true);
} else {
this.build();
}
} else {
// destroy
this.mockNextBuildDir();
}
}

Expand Down Expand Up @@ -171,6 +183,17 @@ export class NextjsBuild extends Construct {
return listDirectory(this.nextStaticDir).map((file) => path.join('/', path.relative(this.nextStaticDir, file)));
}

private assertBuildDirExists(throwIfMissing = true) {
const dir = this.getNextBuildDir();
if (!fs.existsSync(dir)) {
if (throwIfMissing) {
throw new Error(`Build directory "${dir}" does not exist. Try removing skipBuild: true option.`);
}
return false;
}
return true;
}

private getNextBuildDir(): string {
const dir = path.resolve(this.props.nextjsPath, NEXTJS_BUILD_DIR);
this.warnIfMissing(dir);
Expand All @@ -182,4 +205,23 @@ export class NextjsBuild extends Construct {
console.warn(`Warning: ${dir} does not exist.`);
}
}

private mockNextBuildDir() {
function createMockDirAndFile(dir: string) {
fs.mkdirSync(dir, { recursive: true });
fs.writeFileSync(path.join(dir, 'package.json'), '{}', 'utf8');
}

const buildDirExists = this.assertBuildDirExists(false);
if (!buildDirExists) {
// mock .open-next
createMockDirAndFile(this.getNextBuildDir());
createMockDirAndFile(this.nextServerFnDir);
createMockDirAndFile(this.nextImageFnDir);
createMockDirAndFile(this.nextRevalidateFnDir);
createMockDirAndFile(this.nextRevalidateDynamoDBProviderFnDir);
createMockDirAndFile(this.nextStaticDir);
createMockDirAndFile(this.nextCacheDir);
}
}
}

0 comments on commit bc9694b

Please sign in to comment.