Skip to content

Commit da89b54

Browse files
committed
adjust plugin to require functions dir to be set as out_functions and catch other edge cases
1 parent 98472e2 commit da89b54

File tree

2 files changed

+58
-24
lines changed

2 files changed

+58
-24
lines changed

helpers/isStaticExportProject.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Takes 1. Netlify config's build details and
2+
// 2. the project's package.json scripts to determine if
3+
// the Next.js app uses static HTML export
4+
5+
const isStaticExportProject = ({ build, scripts }) => {
6+
const NEXT_EXPORT_COMMAND = 'next export';
7+
const isSetInNetlifyConfig = build && build.command && build.command.includes(NEXT_EXPORT_COMMAND);
8+
const isSetInNpmScript = Object.keys(scripts).find((script) => {
9+
return scripts[script].includes(NEXT_EXPORT_COMMAND);
10+
});
11+
return isSetInNetlifyConfig || isSetInNpmScript;
12+
};
13+
14+
module.exports = isStaticExportProject;

index.js

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,13 @@ const { PHASE_PRODUCTION_BUILD } = require('next/constants');
88
const { default: loadConfig } = require('next/dist/next-server/server/config');
99
const makeDir = require('make-dir');
1010
const cpx = require('cpx');
11+
const isStaticExportProject = require('./helpers/isStaticExportProject');
1112

1213
const _isNextProject = async () => {
1314
const frameworks = await listFrameworks();
1415
return !!frameworks.find(({ name }) => name === 'next');
1516
};
1617

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-
2218
// * Helpful Plugin Context *
2319
// - Between the prebuild and build steps, the project's build command is run
2420
// - Between the build and postbuild steps, any functions are bundled
@@ -30,18 +26,40 @@ module.exports = {
3026
const { failBuild } = utils.build;
3127

3228
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) {
29+
// TO-DO: Post alpha, try to remove this workaround for missing deps in
30+
// the next-on-netlify function template
31+
await utils.run.command('npm install next-on-netlify@latest');
32+
33+
// Require the project's package.json for access to its scripts
34+
// and dependencies in order to check existing project configuration
35+
let packageJson;
36+
if (existsSync(path.resolve(constants.PUBLISH_DIR, 'package.json'))) {
37+
packageJson = require(path.resolve(constants.PUBLISH_DIR, 'package.json'));
38+
} else if (existsSync(path.resolve(constants.PUBLISH_DIR, '..', 'package.json'))) {
39+
packageJson = require(path.resolve(constants.PUBLISH_DIR, '..', 'package.json'));
40+
} else {
41+
failBuild(`Cannot locate your package.json file. Please make sure your package.json is
42+
at the root of your project or in your publish directory.`
43+
);
44+
}
45+
46+
const { scripts, dependencies } = packageJson;
47+
48+
if (isStaticExportProject({ build, scripts })) {
3649
failBuild(`** Static HTML export next.js projects do not require this plugin **`);
3750
}
3851

39-
// TO-DO: read dependencies from package.json
40-
// fail build if next-on-netlify is already installed or in a script?
52+
// TO-DO: check scripts to make sure the app isn't manually running NoN
53+
// For now, we'll make it clear in the README
54+
// const isAlreadyUsingNextOnNetlify = Object.keys(dependencies).find((dep) => dep === 'next-on-netlify');
55+
// if (isAlreadyUsingNextOnNetlify) {
56+
// failBuild(`This plugin cannot support apps that manually use next-on-netlify. Uninstall next-on-netlify as a dependency to resolve.`);
57+
// }
4158

42-
const hasFunctionsDirectorySet = build && netlifyConfig.functions;
43-
if (!hasFunctionsDirectorySet) {
44-
failBuild
59+
const isFunctionsDirectoryCorrect = build && build.functions && build.functions === path.resolve('out_functions');
60+
if (!isFunctionsDirectoryCorrect) {
61+
// to do rephrase
62+
failBuild(`You must designate a functions directory named "out_functions" in your netlify.toml or in your app's build settings on Netlify. See docs for more info: https://docs.netlify.com/functions/configure-and-deploy/#configure-the-functions-folder`);
4563
}
4664

4765
if (existsSync('next.config.js')) {
@@ -75,18 +93,20 @@ module.exports = {
7593

7694
// Next-on-netlify puts its files into out_functions and out_publish
7795
// 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);
96+
97+
// TO-DO: use FUNCTIONS_DIST when internal bug is fixed
98+
const { PUBLISH_DIR } = constants;
99+
// if (!existsSync(FUNCTIONS_DIST)) {
100+
// await makeDir(FUNCTIONS_DIST);
101+
// }
102+
if (!existsSync(PUBLISH_DIR)) {
103+
await makeDir(PUBLISH_DIR);
104+
}
105+
106+
// TO-DO: make sure FUNCTIONS_DIST doesnt have a custom function name conflict
107+
// with function names that next-on-netlify can generate
108+
// cpx.copySync('out_functions/**/*', FUNCTIONS_SRC);
82109
cpx.copySync('out_publish/**/*', PUBLISH_DIR);
83110
}
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);
91111
}
92112
}

0 commit comments

Comments
 (0)