Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on May 10, 2021. It is now read-only.

Commit 2371424

Browse files
track NoN files when configured dirs are used, clean before each new run (#134)
* track NoN files when configured dirs are used and clean before running NoN * some cleanup and extra test case
1 parent c0deace commit 2371424

File tree

6 files changed

+279
-14
lines changed

6 files changed

+279
-14
lines changed

‎index.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@ const {
1616
* publishDir: string to path
1717
* }
1818
*/
19+
1920
const nextOnNetlify = (options = {}) => {
2021
const functionsPath = options.functionsDir || NETLIFY_FUNCTIONS_PATH;
2122
const publishPath = options.publishDir || NETLIFY_PUBLISH_PATH;
2223

23-
prepareFolders({ functionsPath, publishPath });
24+
const trackNextOnNetlifyFiles = prepareFolders({
25+
functionsPath,
26+
publishPath,
27+
});
2428

2529
copyPublicFiles(publishPath);
2630

@@ -33,6 +37,8 @@ const nextOnNetlify = (options = {}) => {
3337
setupRedirects(publishPath);
3438

3539
setupHeaders(publishPath);
40+
41+
trackNextOnNetlifyFiles();
3642
};
3743

3844
module.exports = nextOnNetlify;

‎lib/helpers/handleFileTracking.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
const { join } = require("path");
2+
const {
3+
existsSync,
4+
readdirSync,
5+
readFileSync,
6+
writeFileSync,
7+
removeSync,
8+
} = require("fs-extra");
9+
const findCacheDir = require("find-cache-dir");
10+
const { NETLIFY_PUBLISH_PATH, NETLIFY_FUNCTIONS_PATH } = require("../config");
11+
12+
const TRACKING_FILE_SEPARATOR = "---";
13+
14+
// Clean configured publish and functions folders and track next-on-netlify files
15+
// for future cleans
16+
const handleFileTracking = ({ functionsPath, publishPath }) => {
17+
const isConfiguredFunctionsDir = functionsPath !== NETLIFY_FUNCTIONS_PATH;
18+
const isConfiguredPublishDir = publishPath !== NETLIFY_PUBLISH_PATH;
19+
20+
const cacheDir = findCacheDir({ name: "next-on-netlify", create: true });
21+
const trackingFilePath = join(cacheDir, ".nonfiletracking");
22+
23+
if (existsSync(trackingFilePath)) {
24+
const trackingFile = readFileSync(trackingFilePath, "utf8");
25+
const [trackedFunctions, trackedPublish] = trackingFile.split(
26+
TRACKING_FILE_SEPARATOR
27+
);
28+
29+
const cleanConfiguredFiles = (trackedFiles) => {
30+
trackedFiles.forEach((file) => {
31+
const filePath = join(publishPath, file);
32+
if (file !== "" && existsSync(filePath)) {
33+
removeSync(filePath);
34+
}
35+
});
36+
};
37+
38+
if (isConfiguredPublishDir) {
39+
cleanConfiguredFiles(trackedPublish.split("\n"));
40+
}
41+
if (isConfiguredFunctionsDir) {
42+
cleanConfiguredFiles(trackedFunctions.split("\n"));
43+
}
44+
}
45+
46+
const functionsBeforeRun = existsSync(functionsPath)
47+
? readdirSync(functionsPath)
48+
: [];
49+
const publishBeforeRun = existsSync(publishPath)
50+
? readdirSync(publishPath)
51+
: [];
52+
53+
// this callback will run at the end of nextOnNetlify()
54+
const trackNewFiles = () => {
55+
const functionsAfterRun = isConfiguredFunctionsDir
56+
? readdirSync(functionsPath)
57+
: functionsBeforeRun;
58+
const publishAfterRun = isConfiguredPublishDir
59+
? readdirSync(publishPath)
60+
: publishBeforeRun;
61+
const getDifference = (before, after) =>
62+
after.filter((filePath) => !before.includes(filePath));
63+
const newFunctionsFiles = getDifference(
64+
functionsBeforeRun,
65+
functionsAfterRun
66+
);
67+
const newPublishFiles = getDifference(publishBeforeRun, publishAfterRun);
68+
69+
const allTrackedFiles = [
70+
...newFunctionsFiles,
71+
TRACKING_FILE_SEPARATOR,
72+
...newPublishFiles,
73+
];
74+
writeFileSync(trackingFilePath, allTrackedFiles.join("\n"));
75+
};
76+
77+
return trackNewFiles;
78+
};
79+
80+
module.exports = handleFileTracking;

‎lib/steps/prepareFolders.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,37 @@
1+
const { join } = require("path");
12
const { emptyDirSync } = require("fs-extra");
3+
const findCacheDir = require("find-cache-dir");
24
const { logTitle, log } = require("../helpers/logger");
35
const { NETLIFY_PUBLISH_PATH, NETLIFY_FUNCTIONS_PATH } = require("../config");
6+
const handleFileTracking = require("../helpers/handleFileTracking");
47

5-
// Empty existing publish and functions folders
8+
// Clean existing publish and functions folders
69
const prepareFolders = ({ functionsPath, publishPath }) => {
710
logTitle("🚀 Next on Netlify 🚀");
811

9-
if (functionsPath === NETLIFY_FUNCTIONS_PATH) {
12+
const isNotConfiguredFunctionsDir = functionsPath === NETLIFY_FUNCTIONS_PATH;
13+
const isNotConfiguredPublishDir = publishPath === NETLIFY_PUBLISH_PATH;
14+
15+
if (isNotConfiguredFunctionsDir) {
1016
log(" ", "Functions directory: ", functionsPath);
1117
}
12-
if (publishPath===NETLIFY_PUBLISH_PATH) {
18+
if (isNotConfiguredPublishDir) {
1319
log(" ", "Publish directory: ", publishPath);
1420
}
15-
if (
16-
functionsPath === NETLIFY_FUNCTIONS_PATH ||
17-
publishPath === NETLIFY_PUBLISH_PATH
18-
) {
21+
if (isNotConfiguredFunctionsDir || isNotConfiguredPublishDir) {
1922
log(" ", "Make sure these are set in your netlify.toml file.");
2023
}
2124

22-
if (publishPath === NETLIFY_PUBLISH_PATH) emptyDirSync(publishPath);
23-
if (functionsPath === NETLIFY_FUNCTIONS_PATH) emptyDirSync(functionsPath);
25+
// We can empty these dirs knowing there will only be stale NoN-generated files inside
26+
if (isNotConfiguredPublishDir) {
27+
emptyDirSync(publishPath);
28+
}
29+
if (isNotConfiguredFunctionsDir) {
30+
emptyDirSync(functionsPath);
31+
}
32+
33+
// This returns a function that runs as the last step of nextOnNetlify()
34+
return handleFileTracking({ functionsPath, publishPath });
2435
};
2536

2637
module.exports = prepareFolders;

‎tests/configurableDirs.test.js

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
// Test next-on-netlify when config is set from a function in next.config.js
2+
// See: https://github.com/netlify/next-on-netlify/issues/25
3+
4+
const { parse, join } = require("path");
5+
const { existsSync, readdirSync, readFileSync } = require("fs-extra");
6+
const buildNextApp = require("./helpers/buildNextApp");
7+
8+
// The name of this test file (without extension)
9+
const FILENAME = parse(__filename).name;
10+
11+
// The directory which will be used for testing.
12+
// We simulate a NextJS app within that directory, with pages, and a
13+
// package.json file.
14+
const PROJECT_PATH = join(__dirname, "builds", FILENAME);
15+
const FUNCTIONS_DIR = "my-functions";
16+
const PUBLISH_DIR = "my-publish";
17+
18+
// Capture the output to verify successful build
19+
let buildOutput;
20+
21+
beforeAll(
22+
async () => {
23+
runOutput = await buildNextApp()
24+
.forTest(__filename)
25+
.withPages("pages")
26+
.withNextConfig("next.config.js")
27+
.withPackageJson("package.json")
28+
.withCustomFunctions("my-functions")
29+
.runWithRequire({ functionsDir: FUNCTIONS_DIR, publishDir: PUBLISH_DIR });
30+
},
31+
// time out after 180 seconds
32+
180 * 1000
33+
);
34+
35+
describe("next-on-netlify", () => {
36+
const functionsDir = join(PROJECT_PATH, FUNCTIONS_DIR);
37+
38+
test("builds successfully", () => {
39+
expect(runOutput).toMatch("Built successfully!");
40+
});
41+
42+
test("copies custom Netlify Function to configured functions directory", () => {
43+
expect(existsSync(join(functionsDir, "someTestFunction.js"))).toBe(true);
44+
});
45+
46+
test("creates a Netlify Function for each SSR page", () => {
47+
expect(existsSync(join(functionsDir, "next_index", "next_index.js"))).toBe(
48+
true
49+
);
50+
expect(
51+
existsSync(join(functionsDir, "next_shows_id", "next_shows_id.js"))
52+
).toBe(true);
53+
expect(
54+
existsSync(
55+
join(functionsDir, "next_shows_params", "next_shows_params.js")
56+
)
57+
).toBe(true);
58+
expect(
59+
existsSync(
60+
join(
61+
functionsDir,
62+
"next_getServerSideProps_static",
63+
"next_getServerSideProps_static.js"
64+
)
65+
)
66+
).toBe(true);
67+
expect(
68+
existsSync(
69+
join(
70+
functionsDir,
71+
"next_getServerSideProps_id",
72+
"next_getServerSideProps_id.js"
73+
)
74+
)
75+
).toBe(true);
76+
});
77+
78+
test("copies static pages to output directory", () => {
79+
const OUTPUT_PATH = join(PROJECT_PATH, PUBLISH_DIR);
80+
81+
expect(existsSync(join(OUTPUT_PATH, "static.html"))).toBe(true);
82+
expect(existsSync(join(OUTPUT_PATH, "static/[id].html"))).toBe(true);
83+
});
84+
85+
test("copies static assets to out_publish/_next/ directory", () => {
86+
const dirs = readdirSync(
87+
join(PROJECT_PATH, PUBLISH_DIR, "_next", "static")
88+
);
89+
90+
expect(dirs.length).toBe(2);
91+
expect(dirs).toContain("chunks");
92+
});
93+
});
94+
95+
describe("clean up of NoN files", () => {
96+
test("creates a .nonfiletracking to audit NoN-specific files between builds", () => {
97+
const cacheDir = join(PROJECT_PATH, "/node_modules/.cache/next-on-netlify");
98+
const dirs = readdirSync(cacheDir);
99+
expect(dirs[0]).toEqual(".nonfiletracking");
100+
});
101+
102+
test(".nonfiletracking contains NoN-specific files", () => {
103+
const cacheDir = join(PROJECT_PATH, "/node_modules/.cache/next-on-netlify");
104+
const fileList = readFileSync(join(cacheDir, ".nonfiletracking"), "utf8");
105+
// had to test equality this way because of windows :)
106+
const isSameList = (arr1, arr2) =>
107+
arr1.reduce((isSame, func) => {
108+
if (arr2.includes(func)) {
109+
isSame = true;
110+
} else {
111+
isSame = false;
112+
}
113+
return isSame;
114+
}, true);
115+
const nextFunctions = [
116+
"next_api_shows_id",
117+
"next_api_shows_params",
118+
"next_api_static",
119+
"next_getServerSideProps_all_slug",
120+
"next_getServerSideProps_id",
121+
"next_getServerSideProps_static",
122+
"next_getStaticProps_id",
123+
"next_getStaticProps_static",
124+
"next_getStaticProps_withFallback_id",
125+
"next_getStaticProps_withFallback_slug",
126+
"next_getStaticProps_withRevalidate_id",
127+
"next_getStaticProps_withRevalidate_withFallback_id",
128+
"next_getStaticProps_withrevalidate",
129+
"next_index",
130+
"next_shows_id",
131+
"next_shows_params",
132+
];
133+
const fileListFunctions = fileList.split("---")[0].split("\n");
134+
expect(isSameList(nextFunctions, fileListFunctions)).toBe(true);
135+
expect(fileListFunctions.includes("someTestFunction.js")).toBe(false);
136+
const publishFiles = [
137+
"404.html",
138+
"_next",
139+
"_redirects",
140+
"getStaticProps",
141+
"static",
142+
"static.html",
143+
];
144+
const fileListPublish = fileList.split("---")[1].split("\n");
145+
expect(isSameList(publishFiles, fileListPublish)).toBe(true);
146+
});
147+
});

‎tests/fixtures/my-functions/someTestFunction.js

Whitespace-only changes.

‎tests/helpers/buildNextApp.js

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ class NextAppBuilder {
4646
return this.withFile(packageJsonFile, "package.json");
4747
}
4848

49+
withCustomFunctions(functionsDir) {
50+
return this.withFile(functionsDir);
51+
}
52+
4953
// Copy a file from the fixtures folder to the app's staging folder
5054
withFile(fixture, target = null) {
5155
// If no target file name is given, use the same name as the fixture
@@ -61,9 +65,8 @@ class NextAppBuilder {
6165
return this;
6266
}
6367

64-
// Build the application with next build
65-
async build() {
66-
// Generate a cach hash ID from the current contents of the staging folder.
68+
async buildNextApp() {
69+
// Generate a cache hash ID from the current contents of the staging folder.
6770
const { hash: cacheHash } = await hashElement(this.__stagingPath, {
6871
encoding: "hex",
6972
});
@@ -83,11 +86,29 @@ class NextAppBuilder {
8386
// run next-on-netlify
8487
copySync(this.__cachePath, this.__appPath);
8588

86-
// Run next-on-netlify
89+
process.chdir(this.__appPath);
90+
}
91+
92+
async build() {
93+
await this.buildNextApp();
94+
95+
// Run next-on-netlify as postbuild script
8796
const { stdout } = await npmRun("next-on-netlify", this.__appPath);
8897
return stdout;
8998
}
9099

100+
async runWithRequire(options) {
101+
await this.buildNextApp();
102+
103+
// Run next-on-netlify as an imported module
104+
const nextOnNetlify = require("../..");
105+
nextOnNetlify({
106+
functionsDir: join(this.__appPath, options.functionsDir),
107+
publishDir: join(this.__appPath, options.publishDir),
108+
});
109+
return "Built successfully!";
110+
}
111+
91112
/*****************************************************************************
92113
* Private functions
93114
****************************************************************************/

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /