Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5da6039

Browse files
committedFeb 7, 2021
update failure points in plugin to do nothing instead
1 parent 19228c4 commit 5da6039

7 files changed

+133
-106
lines changed
 

‎helpers/doesNotNeedPlugin.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Checks all the cases for which the plugin should do nothing
2+
const isStaticExportProject = require('./isStaticExportProject')
3+
const doesSiteUseNextOnNetlify = require('./doesSiteUseNextOnNetlify')
4+
const hasCorrectNextConfig = require('./hasCorrectNextConfig')
5+
6+
const doesNotNeedPlugin = ({ netlifyConfig, packageJson, nextConfigPath }) => {
7+
const { build } = netlifyConfig
8+
const { name, scripts = {} } = packageJson
9+
10+
return (
11+
isStaticExportProject({ build, scripts }) ||
12+
doesSiteUseNextOnNetlify({ packageJson }) ||
13+
!hasCorrectNextConfig(nextConfigPath)
14+
)
15+
}
16+
17+
module.exports = doesNotNeedPlugin

‎helpers/doesSiteUseNextOnNetlify.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Checks if site is already using next-on-netlify
2+
const { name: pluginName } = require('../package.json')
3+
4+
const doesSiteUseNextOnNetlify = ({ packageJson }) => {
5+
const { name, scripts = {}, dependencies = {} } = packageJson
6+
7+
const hasNextOnNetlifyInstalled = dependencies['next-on-netlify'] !== undefined
8+
const hasNextOnNetlifyPostbuildScript =
9+
typeof scripts.postbuild === 'string' && scripts.postbuild.includes('next-on-netlify')
10+
const isUsingNextOnNetlify = (hasNextOnNetlifyInstalled || hasNextOnNetlifyPostbuildScript) && pluginName !== name
11+
if (isUsingNextOnNetlify) {
12+
console.log(
13+
`This plugin does not support sites that manually use next-on-netlify. Uninstall next-on-netlify as a dependency and/or remove it from your postbuild script to allow this plugin to run.`,
14+
)
15+
}
16+
17+
return isUsingNextOnNetlify
18+
}
19+
20+
module.exports = doesSiteUseNextOnNetlify

‎helpers/hasCorrectNextConfig.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const path = require('path')
2+
3+
// Checks if site has the correct next.cofig.js
4+
const hasCorrectNextConfig = (nextConfigPath) => {
5+
// In the plugin's case, no config is valid because we'll make it ourselves
6+
if (nextConfigPath === undefined) return true
7+
8+
// We cannot load `next` at the top-level because we validate whether the
9+
// site is using `next` inside `onPreBuild`.
10+
const { PHASE_PRODUCTION_BUILD } = require('next/constants')
11+
const { default: loadConfig } = require('next/dist/next-server/server/config')
12+
13+
// If the next config exists, log warning if target isnt in acceptableTargets
14+
const acceptableTargets = ['serverless', 'experimental-serverless-trace']
15+
const nextConfig = loadConfig(PHASE_PRODUCTION_BUILD, path.resolve('.'))
16+
const isValidTarget = acceptableTargets.includes(nextConfig.target)
17+
if (!isValidTarget) {
18+
console.log(
19+
`Your next.config.js must set the "target" property to one of: ${acceptableTargets.join(', ')}. Update the
20+
target property to allow this plugin to run.`,
21+
)
22+
}
23+
24+
return isValidTarget
25+
}
26+
27+
module.exports = hasCorrectNextConfig

‎helpers/isStaticExportProject.js

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Takes 1. Netlify config's build details and
22
// 2. the project's package.json scripts to determine if
33
// the Next.js app uses static HTML export
4-
54
const isStaticExportProject = ({ build, scripts }) => {
65
const NEXT_EXPORT_COMMAND = 'next export'
76

‎helpers/validateNextUsage.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const validateNextUsage = function (failBuild) {
2727
}
2828

2929
const MIN_VERSION = '9.5.3'
30-
const MIN_EXPERIMENTAL_VERSION = '10.0.0'
30+
const MIN_EXPERIMENTAL_VERSION = '11.0.0'
3131

3232
const hasPackage = function (packageName) {
3333
try {

‎index.js

+18-42
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
const fs = require('fs')
22
const path = require('path')
33
const util = require('util')
4-
54
const findUp = require('find-up')
65
const makeDir = require('make-dir')
76

8-
const { name: pluginName } = require('./package.json')
9-
const isStaticExportProject = require('./helpers/isStaticExportProject')
107
const validateNextUsage = require('./helpers/validateNextUsage')
8+
const doesNotNeedPlugin = require('./helpers/doesNotNeedPlugin')
119

1210
const pWriteFile = util.promisify(fs.writeFile)
1311

@@ -18,61 +16,37 @@ const pWriteFile = util.promisify(fs.writeFile)
1816
module.exports = {
1917
async onPreBuild({ netlifyConfig, packageJson, utils }) {
2018
const { failBuild } = utils.build
19+
const nextConfigPath = await findUp('next.config.js')
2120

2221
validateNextUsage(failBuild)
2322

24-
if (Object.keys(packageJson).length === 0) {
25-
return failBuild(`Could not find a package.json for this project`)
26-
}
27-
28-
const { build } = netlifyConfig
29-
const { name, scripts = {}, dependencies = {} } = packageJson
30-
31-
if (isStaticExportProject({ build, scripts })) {
32-
return failBuild(
33-
`Static HTML export Next.js projects do not require this plugin. Check your project's build command for 'next export'.`,
34-
)
23+
const hasNoPackageJson = Object.keys(packageJson).length === 0
24+
if (hasNoPackageJson) {
25+
failBuild('Could not find a package.json for this project')
3526
}
3627

37-
const hasNextOnNetlifyInstalled = dependencies['next-on-netlify'] !== undefined
38-
const hasNextOnNetlifyPostbuildScript =
39-
typeof scripts.postbuild === 'string' && scripts.postbuild.includes('next-on-netlify')
40-
const isAlreadyUsingNextOnNetlify =
41-
(hasNextOnNetlifyInstalled || hasNextOnNetlifyPostbuildScript) && pluginName !== name
42-
if (isAlreadyUsingNextOnNetlify) {
43-
return failBuild(
44-
`This plugin does not support sites that manually use next-on-netlify. Uninstall next-on-netlify as a dependency to resolve.`,
45-
)
28+
if (doesNotNeedPlugin({ netlifyConfig, packageJson, nextConfigPath })) {
29+
return
4630
}
4731

48-
const nextConfigPath = await findUp('next.config.js')
49-
if (nextConfigPath !== undefined) {
50-
// We cannot load `next` at the top-level because we validate whether the
51-
// site is using `next` inside `onPreBuild`.
52-
const { PHASE_PRODUCTION_BUILD } = require('next/constants')
53-
const { default: loadConfig } = require('next/dist/next-server/server/config')
54-
55-
// If the next config exists, fail build if target isnt in acceptableTargets
56-
const acceptableTargets = ['serverless', 'experimental-serverless-trace']
57-
const nextConfig = loadConfig(PHASE_PRODUCTION_BUILD, path.resolve('.'))
58-
const isValidTarget = acceptableTargets.includes(nextConfig.target)
59-
if (!isValidTarget) {
60-
return failBuild(
61-
`Your next.config.js must set the "target" property to one of: ${acceptableTargets.join(', ')}`,
62-
)
63-
}
64-
} else {
32+
if (nextConfigPath === undefined) {
6533
// Create the next config file with target set to serverless by default
6634
const nextConfig = `
6735
module.exports = {
6836
target: 'serverless'
6937
}
7038
`
7139
await pWriteFile('next.config.js', nextConfig)
72-
console.log(`** Adding next.config.js with target set to 'serverless' **`)
7340
}
41+
42+
return true
7443
},
75-
async onBuild({ constants: { PUBLISH_DIR, FUNCTIONS_SRC = DEFAULT_FUNCTIONS_SRC } }) {
44+
async onBuild({ netlifyConfig, packageJson, constants: { PUBLISH_DIR, FUNCTIONS_SRC = DEFAULT_FUNCTIONS_SRC } }) {
45+
const nextConfigPath = await findUp('next.config.js')
46+
if (doesNotNeedPlugin({ netlifyConfig, packageJson, nextConfigPath })) {
47+
return
48+
}
49+
7650
console.log(`** Running Next on Netlify package **`)
7751

7852
await makeDir(PUBLISH_DIR)
@@ -82,6 +56,8 @@ module.exports = {
8256
// inside `onPreBuild`.
8357
const nextOnNetlify = require('next-on-netlify')
8458
nextOnNetlify({ functionsDir: FUNCTIONS_SRC, publishDir: PUBLISH_DIR })
59+
60+
return true
8561
},
8662
}
8763

‎test/index.js

+50-62
Original file line numberDiff line numberDiff line change
@@ -61,71 +61,58 @@ const DUMMY_PACKAGE_JSON = { name: 'dummy', version: '1.0.0' }
6161
const netlifyConfig = { build: {} }
6262

6363
describe('preBuild()', () => {
64-
test('fail build if the app has static html export in npm script', async () => {
65-
await expect(
66-
plugin.onPreBuild({
67-
netlifyConfig: { build: { command: 'npm run build' } },
68-
packageJson: { ...DUMMY_PACKAGE_JSON, scripts: { build: 'next export' } },
69-
utils,
70-
constants: { FUNCTIONS_SRC: 'out_functions' },
71-
}),
72-
).rejects.toThrow(
73-
`Static HTML export Next.js projects do not require this plugin. Check your project's build command for 'next export'.`,
74-
)
64+
test('do nothing if the app has static html export in npm script', async () => {
65+
const output = await plugin.onPreBuild({
66+
netlifyConfig: { build: { command: 'npm run build' } },
67+
packageJson: { ...DUMMY_PACKAGE_JSON, scripts: { build: 'next export' } },
68+
utils,
69+
constants: { FUNCTIONS_SRC: 'out_functions' },
70+
})
71+
expect(output).toBe(undefined)
7572
})
7673

77-
test('do not fail build if the app has next export in an unused script', async () => {
78-
await expect(
79-
plugin.onPreBuild({
80-
netlifyConfig,
81-
packageJson: { ...DUMMY_PACKAGE_JSON, scripts: { export: 'next export' } },
82-
utils,
83-
constants: {},
84-
}),
85-
).resolves
74+
test('run plugin if the app has next export in an unused script', async () => {
75+
const output = await plugin.onPreBuild({
76+
netlifyConfig,
77+
packageJson: { ...DUMMY_PACKAGE_JSON, scripts: { export: 'next export' } },
78+
utils,
79+
constants: {},
80+
})
81+
expect(output).toBe(true)
8682
})
8783

88-
test('fail build if the app has static html export in toml/ntl config', async () => {
89-
await expect(
90-
plugin.onPreBuild({
91-
netlifyConfig: { build: { command: 'next build && next export' } },
92-
packageJson: DUMMY_PACKAGE_JSON,
93-
utils,
94-
constants: { FUNCTIONS_SRC: 'out_functions' },
95-
}),
96-
).rejects.toThrow(
97-
`Static HTML export Next.js projects do not require this plugin. Check your project's build command for 'next export'.`,
98-
)
84+
test('do nothing if app has static html export in toml/ntl config', async () => {
85+
const output = await plugin.onPreBuild({
86+
netlifyConfig: { build: { command: 'next build && next export' } },
87+
packageJson: DUMMY_PACKAGE_JSON,
88+
utils,
89+
constants: { FUNCTIONS_SRC: 'out_functions' },
90+
})
91+
expect(output).toBe(undefined)
9992
})
10093

101-
test('fail build if app has next-on-netlify installed', async () => {
94+
test('do nothing if app has next-on-netlify installed', async () => {
10295
const packageJson = {
10396
dependencies: { 'next-on-netlify': '123' },
10497
}
105-
await expect(
106-
plugin.onPreBuild({
107-
netlifyConfig,
108-
packageJson,
109-
utils,
110-
}),
111-
).rejects.toThrow(
112-
`This plugin does not support sites that manually use next-on-netlify. Uninstall next-on-netlify as a dependency to resolve.`,
113-
)
98+
const output = await plugin.onPreBuild({
99+
netlifyConfig,
100+
packageJson,
101+
utils,
102+
})
103+
expect(output).toBe(undefined)
114104
})
115105

116-
test('fail build if app has next-on-netlify postbuild script', async () => {
106+
test('do nothing if app has next-on-netlify postbuild script', async () => {
117107
const packageJson = {
118108
scripts: { postbuild: 'next-on-netlify' },
119109
}
120-
await expect(
121-
plugin.onPreBuild({
122-
netlifyConfig,
123-
packageJson,
124-
utils,
125-
}),
126-
).rejects.toThrow(
127-
`This plugin does not support sites that manually use next-on-netlify. Uninstall next-on-netlify as a dependency to resolve.`,
128-
)
110+
const output = await plugin.onPreBuild({
111+
netlifyConfig,
112+
packageJson,
113+
utils,
114+
})
115+
expect(output).toBe(undefined)
129116
})
130117

131118
test('fail build if the app has no package.json', async () => {
@@ -151,19 +138,16 @@ describe('preBuild()', () => {
151138
})
152139

153140
test.each(['invalid_next_config', 'deep_invalid_next_config'])(
154-
`fail build if the app's next config has an invalid target`,
141+
`do nothing if the app's next config has an invalid target`,
155142
async (fixtureName) => {
156143
await useFixture(fixtureName)
157-
await expect(
158-
plugin.onPreBuild({
159-
netlifyConfig,
160-
packageJson: DUMMY_PACKAGE_JSON,
161-
utils,
162-
constants: { FUNCTIONS_SRC: 'out_functions' },
163-
}),
164-
).rejects.toThrow(
165-
`Your next.config.js must set the "target" property to one of: serverless, experimental-serverless-trace`,
166-
)
144+
const output = await plugin.onPreBuild({
145+
netlifyConfig,
146+
packageJson: DUMMY_PACKAGE_JSON,
147+
utils,
148+
constants: { FUNCTIONS_SRC: 'out_functions' },
149+
})
150+
expect(output).toBe(undefined)
167151
},
168152
)
169153
})
@@ -174,6 +158,8 @@ describe('onBuild()', () => {
174158
await moveNextDist()
175159
const PUBLISH_DIR = 'publish'
176160
await plugin.onBuild({
161+
netlifyConfig,
162+
packageJson: DUMMY_PACKAGE_JSON,
177163
constants: {
178164
PUBLISH_DIR,
179165
FUNCTIONS_SRC: 'functions',
@@ -191,6 +177,8 @@ describe('onBuild()', () => {
191177
await useFixture('functions_copy_files')
192178
await moveNextDist()
193179
await plugin.onBuild({
180+
netlifyConfig,
181+
packageJson: DUMMY_PACKAGE_JSON,
194182
constants: {
195183
FUNCTIONS_SRC,
196184
PUBLISH_DIR: '.',

0 commit comments

Comments
 (0)
Please sign in to comment.