Skip to content

Commit

Permalink
fix: Fixes for placeholder mode (#16)
Browse files Browse the repository at this point in the history
* Fixes for placeholder mode

* chore: self mutation

Signed-off-by: github-actions <[email protected]>

* WIP

* readme

* index.html

* index.html

Signed-off-by: github-actions <[email protected]>
Co-authored-by: github-actions <[email protected]>
  • Loading branch information
revmischa and github-actions authored Nov 9, 2022
1 parent 58c4b9d commit 1b75ab4
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 43 deletions.
14 changes: 7 additions & 7 deletions API.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,12 @@ class NextjsSst extends Nextjs {
nextjsPath: path.isAbsolute(props.nextjsPath) ? path.relative(app.appPath, props.nextjsPath) : props.nextjsPath,
});

this.registerSiteEnvironment();
if (props.environment) this.registerSiteEnvironment(props.environment);
}

protected registerSiteEnvironment() {
protected registerSiteEnvironment(environment: Record<string, string>) {
const environmentOutputs: Record<string, string> = {};
for (const [key, value] of Object.entries(this.props.environment || {})) {
for (const [key, value] of Object.entries(environment)) {
const outputId = `SstSiteEnv_${key}`;
const output = new CfnOutput(this, outputId, { value });
environmentOutputs[key] = Stack.of(this).getLogicalId(output);
Expand All @@ -131,7 +131,7 @@ class NextjsSst extends Nextjs {
path: this.props.nextjsPath,
stack: Stack.of(this).node.id,
environmentOutputs,
} as BaseSiteEnvironmentOutputsInfo);
});
}
}
```
Expand Down
4 changes: 4 additions & 0 deletions assets/index.html → assets/PlaceholderSite/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
<h1>NextJS AWS</h1>
<p>This is a placeholder.</p>
<p>Probably you want to connect to your local NextJS dev server.</p>
<p>
Please feel free to peruse <a href="https://github.com/jetbridge/cdk-nextjs#readme">the documentation</a> for
this NextJS construct.
</p>
</section>
</body>
</html>
6 changes: 3 additions & 3 deletions src/Nextjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,8 @@ export class Nextjs extends Construct {
// handle placeholder
if (this.props.isPlaceholder) {
return new cloudfront.Distribution(this, 'Distribution', {
defaultRootObject: 'placeholder/index.html',
errorResponses: buildErrorResponsesForRedirectToIndex('placeholder/index.html'),
defaultRootObject: 'index.html',
errorResponses: buildErrorResponsesForRedirectToIndex('index.html'),
domainNames,
certificate: this.certificate,
defaultBehavior: {
Expand Down Expand Up @@ -545,7 +545,7 @@ export class Nextjs extends Construct {
}),
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
},
...this.props.cdk?.distribution,
...this.props.cdk?.distribution, // not sure if needed
});
}

Expand Down
5 changes: 2 additions & 3 deletions src/NextjsAssetsDeployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export class NextJsAssetsDeployment extends Construct {
this.deployments = this.uploadS3Assets(this.staticTempDir);

// do rewrites of unresolved CDK tokens in static files
if (this.props.environment) {
if (this.props.environment && !this.props.isPlaceholder) {
const rewriter = new NextjsS3EnvRewriter(this, 'NextjsS3EnvRewriter', {
...props,
s3Bucket: this.bucket,
Expand Down Expand Up @@ -93,7 +93,7 @@ export class NextJsAssetsDeployment extends Construct {
// path to public folder; root static assets
const staticDir = this.props.nextBuild.nextStaticDir;
let publicDir = this.props.isPlaceholder
? path.resolve(__dirname, '../assets/placeholder-site')
? path.resolve(__dirname, '../assets/PlaceholderSite')
: this.props.nextBuild.nextPublicDir;

if (!this.props.isPlaceholder && fs.existsSync(staticDir)) {
Expand Down Expand Up @@ -132,7 +132,6 @@ export class NextJsAssetsDeployment extends Construct {

const deployment = new BucketDeployment(this, 'NextStaticAssetsS3Deployment', {
destinationBucket: this.bucket,
destinationKeyPrefix: this.props.isPlaceholder ? '/placeholder' : '/',
sources: [Source.asset(archiveZipFilePath)],
distribution: this.props.distribution,
prune: this.props.prune,
Expand Down
9 changes: 7 additions & 2 deletions src/NextjsBuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,12 @@ export class NextjsBuild extends Construct {
}

private runNpmBuild() {
const { nextjsPath } = this.props;
const { nextjsPath, isPlaceholder, quiet } = this.props;

if (isPlaceholder) {
if (!quiet) console.debug(`Skipping build for placeholder NextjsBuild at ${nextjsPath}`);
return;
}

// validate site path exists
if (!fs.existsSync(nextjsPath)) {
Expand Down Expand Up @@ -145,7 +150,7 @@ export class NextjsBuild extends Construct {
const nextDir = this._getNextBuildDir();
const standaloneDir = path.join(nextDir, NEXTJS_BUILD_STANDALONE_DIR);

if (!fs.existsSync(standaloneDir)) {
if (!fs.existsSync(standaloneDir) && !this.props.isPlaceholder) {
throw new Error(`Could not find ${standaloneDir} directory.`);
}
return standaloneDir;
Expand Down
51 changes: 27 additions & 24 deletions src/NextjsLambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ const RUNTIME = lambda.Runtime.NODEJS_16_X;
* Build a lambda function from a NextJS application to handle server-side rendering, API routes, and image optimization.
*/
export class NextJsLambda extends Construct {
configBucket: Bucket;
configBucket?: Bucket;
lambdaFunction: Function;

constructor(scope: Construct, id: string, props: NextjsLambdaProps) {
super(scope, id);
const { nextBuild, function: functionOptions } = props;
const { nextBuild, function: functionOptions, isPlaceholder } = props;

// bundle server handler
// delete default nextjs handler if it exists
Expand Down Expand Up @@ -98,7 +98,7 @@ export class NextJsLambda extends Construct {

// upload the lambda package to S3
const s3asset = new s3Assets.Asset(scope, 'MainFnAsset', { path: zipFilePath });
const code = props.isPlaceholder
const code = isPlaceholder
? lambda.Code.fromInline(
"module.exports.handler = async () => { return { statusCode: 200, body: 'SST placeholder site' } }"
)
Expand All @@ -119,28 +119,31 @@ export class NextJsLambda extends Construct {
});
this.lambdaFunction = fn;

// put JSON file with env var replacements in S3
const [configBucket, configDeployment] = this.createConfigBucket(props);
this.configBucket = configBucket;

// replace env var placeholders in the lambda package with resolved values
const rewriter = new NextjsS3EnvRewriter(this, 'LambdaCodeRewriter', {
...props,
s3Bucket: s3asset.bucket,
s3keys: [s3asset.s3ObjectKey],
replacementConfig: {
// use json file in S3 for replacement values
// this can contain backend secrets so better to not have them in custom resource logs
jsonS3Bucket: configDeployment.deployedBucket,
jsonS3Key: CONFIG_ENV_JSON_PATH,
},
debug: true, // enable for more verbose output from the rewriter function
});
rewriter.node.addDependency(s3asset);
// rewrite env var placeholders in server code
if (!isPlaceholder) {
// put JSON file with env var replacements in S3
const [configBucket, configDeployment] = this.createConfigBucket(props);
this.configBucket = configBucket;

// replace env var placeholders in the lambda package with resolved values
const rewriter = new NextjsS3EnvRewriter(this, 'LambdaCodeRewriter', {
...props,
s3Bucket: s3asset.bucket,
s3keys: [s3asset.s3ObjectKey],
replacementConfig: {
// use json file in S3 for replacement values
// this can contain backend secrets so better to not have them in custom resource logs
jsonS3Bucket: configDeployment.deployedBucket,
jsonS3Key: CONFIG_ENV_JSON_PATH,
},
debug: true, // enable for more verbose output from the rewriter function
});
rewriter.node.addDependency(s3asset);

// in order to create this dependency, the lambda function needs to be a child of the current construct
// meaning we can't inherit from Function
fn.node.addDependency(rewriter); // don't deploy lambda until rewriter is done - we are sort of 'intercepting' the deployment package
// in order to create this dependency, the lambda function needs to be a child of the current construct
// meaning we can't inherit from Function
fn.node.addDependency(rewriter); // don't deploy lambda until rewriter is done - we are sort of 'intercepting' the deployment package
}
}

// this can hold our resolved environment vars for the server
Expand Down

0 comments on commit 1b75ab4

Please sign in to comment.