Skip to content

Commit c7a95c3

Browse files
committed
progress
1 parent ef114f2 commit c7a95c3

File tree

3 files changed

+73
-25
lines changed

3 files changed

+73
-25
lines changed

packages/@apphosting/adapter-nextjs/e2e/run-local.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,9 @@ const scenarios: Scenario[] = [
5353
tests: ["middleware.spec.ts"], // Only run middleware-specific tests
5454
},
5555
...configOverrideTestScenarios.map(
56-
(scenario: { name: string; config: string; file: string }) => ({
56+
(scenario: { name: string; config?: string; file?: string }) => ({
5757
name: scenario.name,
5858
setup: async (cwd: string) => {
59-
const configContent = scenario.config;
6059
const files = await fsExtra.readdir(cwd);
6160
const configFiles = files
6261
.filter((file) => file.startsWith("next.config."))
@@ -67,6 +66,12 @@ const scenarios: Scenario[] = [
6766
console.log(`Removed existing config file: ${file}`);
6867
}
6968

69+
// skip creating the test config if data is not provided
70+
if (!scenario.config || !scenario.file) {
71+
return
72+
}
73+
74+
const configContent = scenario.config;
7075
await fsExtra.writeFile(join(cwd, scenario.file), configContent);
7176
console.log(`Created ${scenario.file} file with ${scenario.name} config`);
7277
},

packages/@apphosting/adapter-nextjs/src/overrides.spec.ts

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -172,20 +172,32 @@ describe("next config overrides", () => {
172172
...config,
173173
images: {
174174
...(config.images || {}),
175-
...(config.images?.unoptimized === undefined && config.images?.loader === undefined
176-
? { unoptimized: true }
175+
...(config.images?.unoptimized === undefined && config.images?.loader === undefined
176+
? { unoptimized: true }
177177
: {}),
178178
},
179179
});
180180
181-
const config = typeof originalConfig === 'function'
181+
const config = typeof originalConfig === 'function'
182182
? async (...args) => {
183183
const resolvedConfig = await originalConfig(...args);
184184
return fahOptimizedConfig(resolvedConfig);
185185
}
186186
: fahOptimizedConfig(originalConfig);
187187
`;
188188

189+
const defaultNextConfig = `
190+
// @ts-nocheck
191+
192+
/** @type {import('next').NextConfig} */
193+
const nextConfig = {
194+
images: {
195+
unoptimized: true,
196+
}
197+
}
198+
199+
module.exports = nextConfig
200+
`
189201
beforeEach(() => {
190202
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "test-overrides"));
191203
});
@@ -194,12 +206,12 @@ describe("next config overrides", () => {
194206
const { overrideNextConfig } = await importOverrides;
195207
const originalConfig = `
196208
// @ts-check
197-
209+
198210
/** @type {import('next').NextConfig} */
199211
const nextConfig = {
200212
/* config options here */
201213
}
202-
214+
203215
module.exports = nextConfig
204216
`;
205217

@@ -213,7 +225,7 @@ describe("next config overrides", () => {
213225
normalizeWhitespace(`
214226
// @ts-nocheck
215227
const originalConfig = require('./next.config.original.js');
216-
228+
217229
${nextConfigOverrideBody}
218230
219231
module.exports = config;
@@ -225,14 +237,14 @@ describe("next config overrides", () => {
225237
const { overrideNextConfig } = await importOverrides;
226238
const originalConfig = `
227239
// @ts-check
228-
240+
229241
/**
230242
* @type {import('next').NextConfig}
231243
*/
232244
const nextConfig = {
233245
/* config options here */
234246
}
235-
247+
236248
export default nextConfig
237249
`;
238250

@@ -257,7 +269,7 @@ describe("next config overrides", () => {
257269
const { overrideNextConfig } = await importOverrides;
258270
const originalConfig = `
259271
// @ts-check
260-
272+
261273
export default (phase, { defaultConfig }) => {
262274
/**
263275
* @type {import('next').NextConfig}
@@ -280,7 +292,7 @@ describe("next config overrides", () => {
280292
import originalConfig from './next.config.original.mjs';
281293
282294
${nextConfigOverrideBody}
283-
295+
284296
export default config;
285297
`),
286298
);
@@ -290,11 +302,11 @@ describe("next config overrides", () => {
290302
const { overrideNextConfig } = await importOverrides;
291303
const originalConfig = `
292304
import type { NextConfig } from 'next'
293-
305+
294306
const nextConfig: NextConfig = {
295307
/* config options here */
296308
}
297-
309+
298310
export default nextConfig
299311
`;
300312

@@ -307,22 +319,21 @@ describe("next config overrides", () => {
307319
normalizeWhitespace(`
308320
// @ts-nocheck
309321
import originalConfig from './next.config.original';
310-
322+
311323
${nextConfigOverrideBody}
312-
324+
313325
module.exports = config;
314326
`),
315327
);
316328
});
317329

318-
it("should not do anything if no next.config.* file exists", async () => {
330+
it("should create a default next.config.js file if one does not exist yet", async () => {
319331
const { overrideNextConfig } = await importOverrides;
320332
await overrideNextConfig(tmpDir, "next.config.js");
321-
322-
// Assert that no next.config* files were created
323-
const files = fs.readdirSync(tmpDir);
324-
const nextConfigFiles = files.filter((file) => file.startsWith("next.config"));
325-
assert.strictEqual(nextConfigFiles.length, 0, "No next.config files should exist");
333+
const updatedConfig = fs.readFileSync(path.join(tmpDir, "next.config.js"), "utf-8");
334+
assert.equal(
335+
normalizeWhitespace(updatedConfig), normalizeWhitespace(defaultNextConfig),
336+
);
326337
});
327338
});
328339

packages/@apphosting/adapter-nextjs/src/overrides.ts

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import {
1010
import { join, extname } from "path";
1111
import { rename as renamePromise } from "fs/promises";
1212

13+
const DEFAULT_NEXT_CONFIG_FILE = 'next.config.js'
14+
1315
/**
1416
* Overrides the user's Next Config file (next.config.[ts|js|mjs]) to add configs
1517
* optimized for Firebase App Hosting.
@@ -19,11 +21,21 @@ export async function overrideNextConfig(projectRoot: string, nextConfigFileName
1921
// Check if the file exists in the current working directory
2022
const configPath = join(projectRoot, nextConfigFileName);
2123

22-
if (!(await exists(configPath))) {
23-
console.log(`No Next.js config file found at ${configPath}`);
24-
return;
24+
if (!(await exists(configPath))){
25+
console.log(`No Next config file found at ${configPath}, creating one with Firebase App Hosting overrides`);
26+
try {
27+
await writeFile(join(projectRoot, DEFAULT_NEXT_CONFIG_FILE), defaultNextConfigForFAH());
28+
} catch (error) {
29+
console.error(`Error creating ${DEFAULT_NEXT_CONFIG_FILE}: ${error}`);
30+
throw error;
31+
}
32+
33+
console.log(`Successfully created ${DEFAULT_NEXT_CONFIG_FILE} with Firebase App Hosting overrides`);
34+
return
2535
}
2636

37+
// A Next Config already exists in the user's project, so it needs to be overriden
38+
2739
// Determine the file extension
2840
const fileExtension = extname(nextConfigFileName);
2941
const originalConfigName = `next.config.original${fileExtension}`;
@@ -104,6 +116,26 @@ function getCustomNextConfig(importStatement: string, fileExtension: string) {
104116
`;
105117
}
106118

119+
/**
120+
* Returns the default Next Config file that is created in the user's project
121+
* if one does not exist already. This config ensures the Next.Js app is optimized
122+
* for Firebase App Hosting.
123+
*/
124+
function defaultNextConfigForFAH() {
125+
return `
126+
// @ts-nocheck
127+
128+
/** @type {import('next').NextConfig} */
129+
const nextConfig = {
130+
images: {
131+
unoptimized: true,
132+
}
133+
}
134+
135+
module.exports = nextConfig
136+
`
137+
}
138+
107139
/**
108140
* This function is used to validate the state of an app after running the
109141
* overrideNextConfig. It validates that:

0 commit comments

Comments
 (0)