Skip to content

Commit 9d9c1d6

Browse files
committed
core foundation for alpha Next.js build plugin with config requirements
0 parents  commit 9d9c1d6

File tree

5 files changed

+4230
-0
lines changed

5 files changed

+4230
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

index.js

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
const fs = require('fs');
2+
const { existsSync, readFileSync } = require('fs');
3+
const path = require('path');
4+
const { appendFile, readdir } = require('fs').promises;
5+
const { listFrameworks } = require('@netlify/framework-info');
6+
const nextOnNetlify = require('next-on-netlify');
7+
const { PHASE_PRODUCTION_BUILD } = require('next/constants');
8+
const { default: loadConfig } = require('next/dist/next-server/server/config');
9+
const makeDir = require('make-dir');
10+
const cpx = require('cpx');
11+
12+
const _isNextProject = async () => {
13+
const frameworks = await listFrameworks();
14+
return !!frameworks.find(({ name }) => name === 'next');
15+
};
16+
17+
// TO-DO:
18+
// - add try catches and error handling
19+
// - edge cases:
20+
// - making sure functions_dir doesnt have a custom function named something that NoN could generate
21+
22+
// * Helpful Plugin Context *
23+
// - Between the prebuild and build steps, the project's build command is run
24+
// - Between the build and postbuild steps, any functions are bundled
25+
26+
module.exports = {
27+
async onPreBuild({ constants, netlifyConfig, utils }) {
28+
const isNextProject = await _isNextProject();
29+
const { build } = netlifyConfig;
30+
const { failBuild } = utils.build;
31+
32+
if (isNextProject) {
33+
// TO-DO: read scripts from package.json and test this there
34+
const isStaticExport = build && build.command && build.command.includes('next export');
35+
if (isStaticExport) {
36+
failBuild(`** Static HTML export next.js projects do not require this plugin **`);
37+
}
38+
39+
// TO-DO: read dependencies from package.json
40+
// fail build if next-on-netlify is already installed or in a script?
41+
42+
const hasFunctionsDirectorySet = build && netlifyConfig.functions;
43+
if (!hasFunctionsDirectorySet) {
44+
failBuild
45+
}
46+
47+
if (existsSync('next.config.js')) {
48+
// If the next config exists, fail build if target isnt in acceptableTargets
49+
const acceptableTargets = ['serverless', 'experimental-serverless-trace'];
50+
const nextConfig = loadConfig(PHASE_PRODUCTION_BUILD, path.resolve('.'));
51+
const isValidTarget = acceptableTargets.includes(nextConfig.target);
52+
if (!isValidTarget) {
53+
failBuild(`next.config.js must be one of: ${acceptableTargets.join(', ')}`);
54+
}
55+
} else {
56+
// Create the next config file with target set to serverless by default
57+
const nextConfig = `
58+
module.exports = {
59+
target: 'serverless'
60+
}
61+
`;
62+
await appendFile('next.config.js', nextConfig);
63+
console.log(`** Adding next.config.js with target set to 'serverless' **`);
64+
}
65+
} else {
66+
failBuild(`This application does not use Next.js.`);
67+
}
68+
},
69+
async onBuild({ constants }) {
70+
const isNextProject = await _isNextProject();
71+
72+
if (isNextProject) {
73+
console.log(`** Running Next on Netlify package **`);
74+
nextOnNetlify();
75+
76+
// Next-on-netlify puts its files into out_functions and out_publish
77+
// Copy files from next-on-netlify's output to the right functions/publish dirs
78+
const { FUNCTIONS_DIST, PUBLISH_DIR } = constants;
79+
await makeDir(FUNCTIONS_DIST);
80+
await makeDir(PUBLISH_DIR);
81+
cpx.copySync('out_functions/**/*', FUNCTIONS_DIST);
82+
cpx.copySync('out_publish/**/*', PUBLISH_DIR);
83+
}
84+
},
85+
async onPostBuild({ constants }) {
86+
const { FUNCTIONS_DIST, PUBLISH_DIR } = constants;
87+
await makeDir(FUNCTIONS_DIST);
88+
await makeDir(PUBLISH_DIR);
89+
cpx.copySync('out_functions/**/*', FUNCTIONS_DIST);
90+
cpx.copySync('out_publish/**/*', PUBLISH_DIR);
91+
}
92+
}

manifest.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
name: netlify-plugin-nextjs

0 commit comments

Comments
 (0)