@netlify/plugin-nextjs 3.9.1 → 4.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +18 -56
  2. package/lib/constants.js +21 -0
  3. package/lib/helpers/cache.js +20 -0
  4. package/lib/helpers/config.js +115 -0
  5. package/lib/helpers/files.js +48 -0
  6. package/lib/helpers/functions.js +64 -0
  7. package/lib/helpers/verification.js +79 -0
  8. package/lib/index.js +47 -0
  9. package/lib/templates/getHandler.js +164 -0
  10. package/lib/templates/getPageResolver.js +24 -0
  11. package/lib/templates/ipx.js +8 -0
  12. package/manifest.yml +1 -1
  13. package/package.json +46 -53
  14. package/LICENSE.md +0 -7
  15. package/helpers/cacheBuild.js +0 -31
  16. package/helpers/checkNxConfig.js +0 -56
  17. package/helpers/copyUnstableIncludedDirs.js +0 -27
  18. package/helpers/doesNotNeedPlugin.js +0 -49
  19. package/helpers/doesSiteUseNextOnNetlify.js +0 -20
  20. package/helpers/getNextConfig.js +0 -46
  21. package/helpers/getNextRoot.js +0 -20
  22. package/helpers/isStaticExportProject.js +0 -20
  23. package/helpers/resolveNextModule.js +0 -30
  24. package/helpers/usesBuildCommand.js +0 -37
  25. package/helpers/validateNextUsage.js +0 -53
  26. package/helpers/verifyBuildTarget.js +0 -69
  27. package/index.js +0 -175
  28. package/src/index.js +0 -94
  29. package/src/lib/config.js +0 -58
  30. package/src/lib/constants/regex.js +0 -9
  31. package/src/lib/helpers/addDefaultLocaleRedirect.js +0 -25
  32. package/src/lib/helpers/addLocaleRedirects.js +0 -19
  33. package/src/lib/helpers/asyncForEach.js +0 -7
  34. package/src/lib/helpers/convertToBasePathRedirects.js +0 -80
  35. package/src/lib/helpers/copyDynamicImportChunks.js +0 -39
  36. package/src/lib/helpers/formatRedirectTarget.js +0 -9
  37. package/src/lib/helpers/getDataRouteForRoute.js +0 -30
  38. package/src/lib/helpers/getFilePathForRoute.js +0 -10
  39. package/src/lib/helpers/getI18n.js +0 -10
  40. package/src/lib/helpers/getNetlifyFunctionName.js +0 -38
  41. package/src/lib/helpers/getNetlifyRoutes.js +0 -45
  42. package/src/lib/helpers/getNextDistDir.js +0 -12
  43. package/src/lib/helpers/getNextSrcDir.js +0 -5
  44. package/src/lib/helpers/getPagesManifest.js +0 -19
  45. package/src/lib/helpers/getPrerenderManifest.js +0 -40
  46. package/src/lib/helpers/getPreviewModeFunctionName.js +0 -5
  47. package/src/lib/helpers/getRoutesManifest.js +0 -12
  48. package/src/lib/helpers/getSortedRedirects.js +0 -37
  49. package/src/lib/helpers/handleFileTracking.js +0 -61
  50. package/src/lib/helpers/isApiRoute.js +0 -4
  51. package/src/lib/helpers/isDynamicRoute.js +0 -6
  52. package/src/lib/helpers/isFrameworkRoute.js +0 -5
  53. package/src/lib/helpers/isHtmlFile.js +0 -4
  54. package/src/lib/helpers/isRootCatchAllRedirect.js +0 -6
  55. package/src/lib/helpers/isRouteInPrerenderManifest.js +0 -23
  56. package/src/lib/helpers/isRouteWithDataRoute.js +0 -13
  57. package/src/lib/helpers/isRouteWithFallback.js +0 -12
  58. package/src/lib/helpers/logger.js +0 -44
  59. package/src/lib/helpers/removeFileExtension.js +0 -4
  60. package/src/lib/helpers/runJobsQueue.js +0 -18
  61. package/src/lib/helpers/setupNetlifyFunctionForPage.js +0 -44
  62. package/src/lib/helpers/setupStaticFileForPage.js +0 -18
  63. package/src/lib/pages/api/pages.js +0 -22
  64. package/src/lib/pages/api/redirects.js +0 -13
  65. package/src/lib/pages/api/setup.js +0 -15
  66. package/src/lib/pages/getInitialProps/pages.js +0 -40
  67. package/src/lib/pages/getInitialProps/redirects.js +0 -26
  68. package/src/lib/pages/getInitialProps/setup.js +0 -15
  69. package/src/lib/pages/getServerSideProps/pages.js +0 -43
  70. package/src/lib/pages/getServerSideProps/redirects.js +0 -44
  71. package/src/lib/pages/getServerSideProps/setup.js +0 -15
  72. package/src/lib/pages/getStaticProps/pages.js +0 -26
  73. package/src/lib/pages/getStaticProps/redirects.js +0 -70
  74. package/src/lib/pages/getStaticProps/setup.js +0 -68
  75. package/src/lib/pages/getStaticPropsWithFallback/pages.js +0 -24
  76. package/src/lib/pages/getStaticPropsWithFallback/redirects.js +0 -51
  77. package/src/lib/pages/getStaticPropsWithFallback/setup.js +0 -29
  78. package/src/lib/pages/getStaticPropsWithRevalidate/pages.js +0 -45
  79. package/src/lib/pages/getStaticPropsWithRevalidate/redirects.js +0 -55
  80. package/src/lib/pages/getStaticPropsWithRevalidate/setup.js +0 -40
  81. package/src/lib/pages/withoutProps/pages.js +0 -27
  82. package/src/lib/pages/withoutProps/redirects.js +0 -51
  83. package/src/lib/pages/withoutProps/setup.js +0 -34
  84. package/src/lib/pages/worker.js +0 -19
  85. package/src/lib/steps/copyNextAssets.js +0 -31
  86. package/src/lib/steps/copyPublicFiles.js +0 -18
  87. package/src/lib/steps/prepareFolders.js +0 -39
  88. package/src/lib/steps/setupHeaders.js +0 -37
  89. package/src/lib/steps/setupImageFunction.js +0 -17
  90. package/src/lib/steps/setupPages.js +0 -25
  91. package/src/lib/steps/setupRedirects.js +0 -105
  92. package/src/lib/templates/getHandlerFunction.js +0 -209
  93. package/src/lib/templates/getTemplate.js +0 -15
  94. package/src/lib/templates/imageFunction.js +0 -135
  95. package/src/next-on-netlify.js +0 -22
@@ -1,69 +0,0 @@
1
- const path = require('path')
2
-
3
- const { writeFile } = require('fs-extra')
4
-
5
- const getNextConfig = require('./getNextConfig')
6
- const getNextRoot = require('./getNextRoot')
7
- const resolveNextModule = require('./resolveNextModule')
8
-
9
- // Checks if site has the correct next.config.js
10
- const verifyBuildTarget = async ({ failBuild, netlifyConfig }) => {
11
- const nextRoot = getNextRoot({ netlifyConfig })
12
-
13
- const { target, configFile } = await getNextConfig(failBuild, nextRoot)
14
-
15
- if (!configFile) {
16
- await writeFile(
17
- path.resolve(nextRoot, 'next.config.js'),
18
- `module.exports = {
19
- // Supported targets are "serverless" and "experimental-serverless-trace"
20
- target: "serverless",
21
- generateBuildId: () => "build"
22
- }`,
23
- )
24
- }
25
-
26
- // If the next config exists, log warning if target isn't in acceptableTargets
27
- const acceptableTargets = ['serverless', 'experimental-serverless-trace']
28
- const isValidTarget = acceptableTargets.includes(target)
29
- if (isValidTarget) {
30
- return
31
- }
32
- console.log(
33
- `The "target" config property must be one of "${acceptableTargets.join(
34
- '", "',
35
- )}". Building with "serverless" target.`,
36
- )
37
-
38
- // We emulate Vercel so that we can set target to serverless if needed
39
- process.env.NOW_BUILDER = true
40
- // If no valid target is set, we use an internal Next env var to force it
41
- process.env.NEXT_PRIVATE_TARGET = 'serverless'
42
-
43
- // 🐉 We need Next to recalculate "isZeitNow" var so we can set the target, but it's
44
- // set as an import side effect so we need to clear the require cache first. 🐲
45
- // https://github.com/vercel/next.js/blob/canary/packages/next/telemetry/ci-info.ts
46
-
47
- delete require.cache[resolveNextModule('next/dist/telemetry/ci-info', nextRoot)]
48
- delete require.cache[
49
- resolveNextModule(
50
- [
51
- // next <= 11.0.1
52
- 'next/dist/next-server/server/config',
53
- // next > 11.0.1
54
- 'next/dist/server/config',
55
- ],
56
- nextRoot,
57
- )
58
- ]
59
-
60
- // Clear memoized cache
61
- getNextConfig.clear()
62
-
63
- // Force the new config to be generated
64
- await getNextConfig(failBuild, nextRoot)
65
- // Reset the value in case something else is looking for it
66
- process.env.NOW_BUILDER = false
67
- }
68
-
69
- module.exports = verifyBuildTarget
package/index.js DELETED
@@ -1,175 +0,0 @@
1
- const { readdirSync, existsSync } = require('fs')
2
- const path = require('path')
3
-
4
- const { yellowBright, greenBright, green } = require('chalk')
5
- const makeDir = require('make-dir')
6
- const { satisfies } = require('semver')
7
- const glob = require('tiny-glob')
8
-
9
- const { restoreCache, saveCache } = require('./helpers/cacheBuild')
10
- const checkNxConfig = require('./helpers/checkNxConfig')
11
- const copyUnstableIncludedDirs = require('./helpers/copyUnstableIncludedDirs')
12
- const doesNotNeedPlugin = require('./helpers/doesNotNeedPlugin')
13
- const getNextConfig = require('./helpers/getNextConfig')
14
- const getNextRoot = require('./helpers/getNextRoot')
15
- const validateNextUsage = require('./helpers/validateNextUsage')
16
- const verifyBuildTarget = require('./helpers/verifyBuildTarget')
17
- const nextOnNetlify = require('./src')
18
-
19
- // This is when the esbuild dynamic import support was added
20
- const REQUIRED_BUILD_VERSION = '>=15.11.5'
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({ netlifyConfig, packageJson, utils, constants = {} }) {
28
- const { FUNCTIONS_SRC = DEFAULT_FUNCTIONS_SRC, INTERNAL_FUNCTIONS_SRC, IS_LOCAL, NETLIFY_BUILD_VERSION } = constants
29
-
30
- const { failBuild } = utils.build
31
-
32
- validateNextUsage({ failBuild, netlifyConfig })
33
-
34
- const hasNoPackageJson = Object.keys(packageJson).length === 0
35
- if (hasNoPackageJson) {
36
- return failBuild('Could not find a package.json for this project')
37
- }
38
-
39
- if (doesNotNeedPlugin({ netlifyConfig, packageJson, failBuild })) {
40
- return
41
- }
42
- // We check for build version because that's what's available to us, but prompt about the cli because that's what they can upgrade
43
- if (IS_LOCAL && !satisfies(NETLIFY_BUILD_VERSION, REQUIRED_BUILD_VERSION, { includePrerelease: true })) {
44
- return failBuild(
45
- `This version of the Essential Next.js plugin requires netlify-cli@4.4.2 or higher. Please upgrade and try again.
46
- You can do this by running: "npm install -g netlify-cli@latest" or "yarn global add netlify-cli@latest"`,
47
- )
48
- }
49
-
50
- // Populates the correct config if needed
51
- await verifyBuildTarget({ netlifyConfig, packageJson, failBuild })
52
- const nextRoot = getNextRoot({ netlifyConfig })
53
-
54
- // Because we memoize nextConfig, we need to do this after the write file
55
- const nextConfig = await getNextConfig(utils.failBuild, nextRoot)
56
-
57
- // Nx needs special config handling, so check for it specifically
58
- const isNx = Boolean(
59
- (packageJson.devDependencies && packageJson.devDependencies['@nrwl/next']) ||
60
- (packageJson.dependencies && packageJson.dependencies['@nrwl/next']),
61
- )
62
-
63
- if (isNx) {
64
- console.log('Detected Nx site. Checking configuration...')
65
- checkNxConfig({ netlifyConfig, packageJson, nextConfig, failBuild, constants })
66
- }
67
-
68
- if (process.env.NEXT_IMAGE_ALLOWED_DOMAINS) {
69
- console.log(
70
- `The Essential Next.js plugin now supports reading image domains from your Next config, so using NEXT_IMAGE_ALLOWED_DOMAINS is now deprecated. Please set images.domains in next.config.js instead, and remove the NEXT_IMAGE_ALLOWED_DOMAINS variable.`,
71
- )
72
- }
73
-
74
- if (INTERNAL_FUNCTIONS_SRC && existsSync(FUNCTIONS_SRC)) {
75
- const oldFunctions = await glob('next_*', { cwd: FUNCTIONS_SRC })
76
-
77
- if (oldFunctions.length !== 0) {
78
- console.log(yellowBright`
79
- Detected the following functions that seem to have been generated by an old version of the Essential Next.js plugin.
80
- The plugin no longer uses these and they should be deleted to avoid conflicts.\n`)
81
- console.log(greenBright`• ${oldFunctions.join('\n• ')}
82
- `)
83
- }
84
- }
85
-
86
- await restoreCache({ cache: utils.cache, distDir: nextConfig.distDir, nextRoot })
87
-
88
- // Exit the build process on unhandled promise rejection. This is the default in Node 15+, but earlier versions just warn.
89
- // This causes problems as it doesn't then know the build has failed until we try to copy the assets.
90
- process.env.NODE_OPTIONS = [process.env.NODE_OPTIONS, '--unhandled-rejections=strict'].filter(Boolean).join(' ')
91
- },
92
- async onBuild({
93
- netlifyConfig,
94
- packageJson,
95
- constants: { PUBLISH_DIR = DEFAULT_PUBLISH_DIR, INTERNAL_FUNCTIONS_SRC, FUNCTIONS_SRC = DEFAULT_FUNCTIONS_SRC },
96
- utils,
97
- }) {
98
- const { failBuild } = utils.build
99
-
100
- const nextRoot = getNextRoot({ netlifyConfig })
101
-
102
- if (doesNotNeedPlugin({ netlifyConfig, packageJson, failBuild })) {
103
- return
104
- }
105
- console.log('Detected Next.js site. Copying files...')
106
-
107
- const { distDir, configFile } = await getNextConfig(failBuild, nextRoot)
108
- const dist = path.resolve(nextRoot, distDir)
109
-
110
- if (!existsSync(dist)) {
111
- failBuild(`
112
- Could not find "${distDir}" after building the site, which indicates that "next build" was not run or that we're looking in the wrong place.
113
- We're using the config file ${configFile}, and looking for the dist directory at ${dist}. If this is incorrect, try deleting the config file, or
114
- moving it to the correct place. Check that your build command includes "next build". If the site is a monorepo, see https://ntl.fyi/next-monorepo
115
- for information on configuring the site. If this is not a Next.js site or if it uses static export, you should remove the Essential Next.js plugin.
116
- See https://ntl.fyi/remove-plugin for instructions.
117
- `)
118
- }
119
-
120
- console.log(`** Running Next on Netlify package **`)
121
-
122
- await makeDir(PUBLISH_DIR)
123
- await nextOnNetlify({
124
- functionsDir: path.resolve(INTERNAL_FUNCTIONS_SRC || FUNCTIONS_SRC),
125
- publishDir: netlifyConfig.build.publish || PUBLISH_DIR,
126
- nextRoot,
127
- })
128
-
129
- if (!netlifyConfig.functions['*'].included_files) {
130
- // eslint-disable-next-line no-param-reassign
131
- netlifyConfig.functions['*'].included_files = []
132
- }
133
- netlifyConfig.functions['*'].included_files.push(
134
- '!node_modules/@next/swc-*/**/*',
135
- '!node_modules/next/dist/compiled/@ampproject/toolbox-optimizer/**/*',
136
- )
137
- },
138
-
139
- async onPostBuild({ netlifyConfig, packageJson, constants: { FUNCTIONS_DIST = DEFAULT_FUNCTIONS_DIST }, utils }) {
140
- if (doesNotNeedPlugin({ netlifyConfig, packageJson, utils })) {
141
- utils.status.show({
142
- title: 'Essential Next.js Build Plugin did not run',
143
- summary: netlifyConfig.build.command
144
- ? 'The site either uses static export, manually runs next-on-netlify, or is not a Next.js site'
145
- : 'The site config does not specify a build command',
146
- })
147
- return
148
- }
149
- const nextRoot = getNextRoot({ netlifyConfig })
150
-
151
- const nextConfig = await getNextConfig(utils.failBuild, nextRoot)
152
- const { distDir, generateBuildId } = nextConfig
153
- await saveCache({ cache: utils.cache, distDir, nextRoot })
154
- copyUnstableIncludedDirs({ nextConfig, functionsDist: path.resolve(FUNCTIONS_DIST) })
155
- utils.status.show({
156
- title: 'Essential Next.js Build Plugin ran successfully',
157
- summary: 'Generated serverless functions and stored the Next.js cache',
158
- })
159
-
160
- // The default generateBuildId function returns null, which causes it to use a random value from nanoid
161
- // eslint-disable-next-line no-self-compare
162
- if (generateBuildId() === null || generateBuildId() !== generateBuildId()) {
163
- console.warn(
164
- yellowBright`
165
- For faster deploy times, build IDs should be set to a static value.
166
- To do this, set ${green`generateBuildId: () => 'build'`} in your next.config.js`,
167
- // TODO: add shortlink when docs are updated
168
- )
169
- }
170
- },
171
- }
172
-
173
- const DEFAULT_FUNCTIONS_SRC = 'netlify/functions'
174
- const DEFAULT_FUNCTIONS_DIST = '.netlify/functions/'
175
- const DEFAULT_PUBLISH_DIR = 'out'
package/src/index.js DELETED
@@ -1,94 +0,0 @@
1
- const { normalize } = require('path')
2
-
3
- const chokidar = require('chokidar')
4
- const debounceFn = require('debounce-fn')
5
- const execa = require('execa')
6
-
7
- const getNextConfig = require('../helpers/getNextConfig')
8
-
9
- const { NETLIFY_PUBLISH_PATH, NETLIFY_FUNCTIONS_PATH, SRC_FILES } = require('./lib/config')
10
- const { logTitle } = require('./lib/helpers/logger')
11
- const copyNextAssets = require('./lib/steps/copyNextAssets')
12
- const copyPublicFiles = require('./lib/steps/copyPublicFiles')
13
- const prepareFolders = require('./lib/steps/prepareFolders')
14
- const setupHeaders = require('./lib/steps/setupHeaders')
15
- const setupImageFunction = require('./lib/steps/setupImageFunction')
16
- const setupPages = require('./lib/steps/setupPages')
17
- const setupRedirects = require('./lib/steps/setupRedirects')
18
-
19
- const build = async (functionsPath, publishPath, nextRoot) => {
20
- const trackNextOnNetlifyFiles = prepareFolders({
21
- functionsPath,
22
- publishPath,
23
- })
24
-
25
- // If we're in a monorepo we need to move into the Next site root
26
- const oldCwd = process.cwd()
27
- if (nextRoot !== oldCwd) {
28
- process.chdir(nextRoot)
29
- }
30
- copyPublicFiles(publishPath)
31
-
32
- await copyNextAssets(publishPath)
33
-
34
- await setupPages({ functionsPath, publishPath })
35
-
36
- const { images } = await getNextConfig()
37
-
38
- await setupImageFunction(functionsPath, images)
39
-
40
- await setupRedirects(publishPath)
41
-
42
- setupHeaders(publishPath)
43
-
44
- // ...and move back after
45
- if (nextRoot !== oldCwd) {
46
- process.chdir(oldCwd)
47
- }
48
-
49
- trackNextOnNetlifyFiles()
50
-
51
- logTitle('✅ Success! All done!')
52
- }
53
-
54
- const watch = (functionsPath, publishPath, nextRoot) => {
55
- logTitle(`👀 Watching source code for changes`)
56
-
57
- const runBuild = debounceFn(
58
- async () => {
59
- try {
60
- execa.sync('next', ['build'], { stdio: 'inherit', preferLocal: true, cwd: nextRoot })
61
- await build(functionsPath, publishPath, nextRoot)
62
- } catch (error) {
63
- console.log(error)
64
- }
65
- },
66
- {
67
- wait: 3000,
68
- },
69
- )
70
-
71
- chokidar.watch(SRC_FILES).on('all', runBuild)
72
- }
73
-
74
- // options param:
75
- // {
76
- // functionsDir: string to path
77
- // publishDir: string to path
78
- // watch: { directory: string to path }
79
- // }
80
- //
81
-
82
- const nextOnNetlify = async (options = {}) => {
83
- const functionsPath = normalize(options.functionsDir || NETLIFY_FUNCTIONS_PATH)
84
- const publishPath = normalize(options.publishDir || NETLIFY_PUBLISH_PATH)
85
- const nextRoot = normalize(options.nextRoot || process.cwd())
86
-
87
- if (options.watch) {
88
- watch(functionsPath, publishPath, nextRoot)
89
- } else {
90
- await build(functionsPath, publishPath, nextRoot)
91
- }
92
- }
93
-
94
- module.exports = nextOnNetlify
package/src/lib/config.js DELETED
@@ -1,58 +0,0 @@
1
- const { join } = require('path')
2
-
3
- const getNextSrcDirs = require('./helpers/getNextSrcDir')
4
-
5
- // This is where next-on-netlify will place all static files.
6
- // The publish key in netlify.toml should point to this folder.
7
- const NETLIFY_PUBLISH_PATH = join('.', 'out_publish')
8
-
9
- // This is where next-on-netlify will place all Netlify Functions.
10
- // The functions key in netlify.toml should point to this folder.
11
- const NETLIFY_FUNCTIONS_PATH = join('.', 'out_functions')
12
-
13
- // This is where static assets, such as images, can be placed. They will be
14
- // copied as-is to the Netlify publish folder.
15
- const PUBLIC_PATH = join('.', 'public')
16
-
17
- // This is the file where NextJS can be configured
18
- const NEXT_CONFIG_PATH = join('.', 'next.config.js')
19
-
20
- const NEXT_SRC_DIRS = getNextSrcDirs()
21
-
22
- // This is the folder with templates for Netlify Functions
23
- const TEMPLATES_DIR = join(__dirname, 'templates')
24
-
25
- // This is the Netlify Function template that wraps all SSR pages
26
- const FUNCTION_TEMPLATE_PATH = join(TEMPLATES_DIR, 'netlifyFunction.ts')
27
-
28
- // This is the Netlify Builder template that wraps ISR pages
29
- const BUILDER_TEMPLATE_PATH = join(TEMPLATES_DIR, 'netlifyOnDemandBuilder.ts')
30
-
31
- // This is the file where custom redirects can be configured
32
- const CUSTOM_REDIRECTS_PATH = join('.', '_redirects')
33
-
34
- // This is the file where custom headers can be configured
35
- const CUSTOM_HEADERS_PATH = join('.', '_headers')
36
-
37
- // This is the name used for copying our imageFunction template and for
38
- // creating the next/image redirect
39
- const NEXT_IMAGE_FUNCTION_NAME = 'next_image'
40
-
41
- const PREVIEW_MODE_COOKIES = ['Cookie=__prerender_bypass,__next_preview_data']
42
-
43
- const SRC_FILES = [PUBLIC_PATH, NEXT_CONFIG_PATH, CUSTOM_REDIRECTS_PATH, CUSTOM_HEADERS_PATH, ...NEXT_SRC_DIRS]
44
-
45
- module.exports = {
46
- NETLIFY_PUBLISH_PATH,
47
- NETLIFY_FUNCTIONS_PATH,
48
- PUBLIC_PATH,
49
- NEXT_CONFIG_PATH,
50
- TEMPLATES_DIR,
51
- FUNCTION_TEMPLATE_PATH,
52
- BUILDER_TEMPLATE_PATH,
53
- CUSTOM_REDIRECTS_PATH,
54
- CUSTOM_HEADERS_PATH,
55
- NEXT_IMAGE_FUNCTION_NAME,
56
- SRC_FILES,
57
- PREVIEW_MODE_COOKIES,
58
- }
@@ -1,9 +0,0 @@
1
- const CATCH_ALL_REGEX = /\/\[\.{3}(.*)](.json)?$/
2
- const OPTIONAL_CATCH_ALL_REGEX = /\/\[{2}\.{3}(.*)]{2}(.json)?$/
3
- const DYNAMIC_PARAMETER_REGEX = /\/\[(.*?)]/g
4
-
5
- module.exports = {
6
- CATCH_ALL_REGEX,
7
- OPTIONAL_CATCH_ALL_REGEX,
8
- DYNAMIC_PARAMETER_REGEX,
9
- }
@@ -1,25 +0,0 @@
1
- const getI18n = require('./getI18n')
2
- // In i18n projects, we need to create redirects from the "naked" route
3
- // to the defaultLocale-prepended route i.e. /static -> /en/static
4
- // Note: there can only one defaultLocale, but we put it in an array to simplify
5
- // logic in redirects.js files via concatenation
6
- const addDefaultLocaleRedirect = async (redirects, route, target, additionalParams) => {
7
- const i18n = await getI18n()
8
- const { defaultLocale } = i18n
9
-
10
- // If no i18n, skip
11
- if (!defaultLocale) return
12
-
13
- const routePieces = route.split('/')
14
- const [, routeLocale] = routePieces
15
- if (routeLocale === defaultLocale) {
16
- const nakedRoute = route === `/${routeLocale}` ? '/' : route.replace(`/${routeLocale}`, '')
17
- redirects.push({
18
- route: nakedRoute,
19
- target: target || route,
20
- ...additionalParams,
21
- })
22
- }
23
- }
24
-
25
- module.exports = addDefaultLocaleRedirect
@@ -1,19 +0,0 @@
1
- const asyncForEach = require('./asyncForEach')
2
- const getDataRouteForRoute = require('./getDataRouteForRoute')
3
- const getI18n = require('./getI18n')
4
-
5
- const addLocaleRedirects = async (redirects, route, target) => {
6
- const i18n = await getI18n()
7
- await asyncForEach(i18n.locales, async (locale) => {
8
- redirects.push({
9
- route: `/${locale}${route === '/' ? '' : route}`,
10
- target,
11
- })
12
- redirects.push({
13
- route: await getDataRouteForRoute(route, locale),
14
- target,
15
- })
16
- })
17
- }
18
-
19
- module.exports = addLocaleRedirects
@@ -1,7 +0,0 @@
1
- const asyncForEach = async (arr, callback) => {
2
- for (let i = 0; i < arr.length; i++) {
3
- await callback(arr[i], i, arr)
4
- }
5
- }
6
-
7
- module.exports = asyncForEach
@@ -1,80 +0,0 @@
1
- // This helper converts the collection of redirects for all page types into
2
- // the necessary redirects for a basePath-generated site
3
- // NOTE: /withoutProps/redirects.js has some of its own contained basePath logic
4
-
5
- const getBasePathDefaultRedirects = ({ basePath, nextRedirects }) => {
6
- if (!basePath) return []
7
- // In a basePath-configured site, all _next assets are fetched with the prepended basePath
8
- return [
9
- {
10
- route: `${basePath}/_next/*`,
11
- target: '/_next/:splat',
12
- statusCode: '301',
13
- force: true,
14
- },
15
- ]
16
- }
17
-
18
- const convertToBasePathRedirects = ({ basePath, nextRedirects }) => {
19
- if (!basePath) return nextRedirects
20
- const basePathRedirects = getBasePathDefaultRedirects({ basePath, nextRedirects })
21
- nextRedirects.forEach((r) => {
22
- if (r.route === '/') {
23
- // On Vercel, a basePath configured site 404s on /, but we can ensure it redirects to /basePath
24
- const indexRedirects = [
25
- {
26
- route: '/',
27
- target: basePath,
28
- statusCode: '301',
29
- force: true,
30
- },
31
- {
32
- route: basePath,
33
- target: r.target,
34
- },
35
- ]
36
- basePathRedirects.push(...indexRedirects)
37
- } else if (r.specialPreviewMode) {
38
- basePathRedirects.push({
39
- route: `${basePath}${r.route}`,
40
- target: r.target,
41
- force: true,
42
- conditions: r.conditions,
43
- })
44
- } else if (!r.route.includes('_next/') && r.target.includes('/.netlify/functions') && r.conditions) {
45
- // If this is a preview mode redirect, we need different behavior than other function targets below
46
- // because the conditions prevent us from doing a route -> basePath/route force
47
- basePathRedirects.push({
48
- route: `${basePath}${r.route}`,
49
- target: r.target,
50
- force: true,
51
- conditions: r.conditions,
52
- })
53
- basePathRedirects.push({
54
- route: `${basePath}${r.route}`,
55
- target: r.route,
56
- })
57
- } else if (!r.route.includes('_next/') && r.target.includes('/.netlify/functions')) {
58
- // This force redirect is necessary for non-preview mode function targets because the serverless lambdas
59
- // try to strip basePath and redirect to the plain route per https://github.com/vercel/next.js/blob/5bff9eac084b69affe3560c4f4cfd96724aa5e49/packages/next/next-server/lib/router/router.ts#L974
60
- const functionRedirects = [
61
- {
62
- route: r.route,
63
- target: `${basePath}${r.route}`,
64
- statusCode: '301',
65
- force: true,
66
- },
67
- {
68
- route: `${basePath}${r.route}`,
69
- target: r.target,
70
- },
71
- ]
72
- basePathRedirects.push(...functionRedirects)
73
- } else {
74
- basePathRedirects.push(r)
75
- }
76
- })
77
- return basePathRedirects
78
- }
79
-
80
- module.exports = convertToBasePathRedirects
@@ -1,39 +0,0 @@
1
- const { join } = require('path')
2
-
3
- const { copySync, existsSync, readdirSync } = require('fs-extra')
4
-
5
- const getNextDistDir = require('./getNextDistDir')
6
- const { logTitle } = require('./logger')
7
-
8
- // Check if there are dynamic import chunks and copy to the necessary function dir
9
- const copyDynamicImportChunks = async (functionPath) => {
10
- const nextDistDir = await getNextDistDir()
11
- const chunksPathWebpack4 = join(nextDistDir, 'serverless')
12
- const filesWP4 = readdirSync(chunksPathWebpack4)
13
- const chunkRegexWP4 = new RegExp(/^(\.?[-$~\w]+)+\.js$/g)
14
- const excludeFiles = new Set(['init-server.js.js', 'on-error-server.js.js'])
15
- const copyPathWP4 = join(functionPath, 'nextPage')
16
-
17
- filesWP4.forEach((file) => {
18
- if (!excludeFiles.has(file) && chunkRegexWP4.test(file)) {
19
- copySync(join(chunksPathWebpack4, file), join(copyPathWP4, file), {
20
- overwrite: false,
21
- errorOnExist: true,
22
- })
23
- }
24
- })
25
-
26
- // Chunks are copied into the nextPage directory, as a sibling to "pages" or "api".
27
- // This matches the Next output, so that imports work correctly
28
- const chunksPathWebpack5 = join(nextDistDir, 'serverless', 'chunks')
29
- const filesWP5 = existsSync(chunksPathWebpack5) ? readdirSync(chunksPathWebpack5) : []
30
- const copyPathWP5 = join(functionPath, 'nextPage', 'chunks')
31
-
32
- filesWP5.forEach((file) => {
33
- if (file.endsWith('.js')) {
34
- copySync(join(chunksPathWebpack5, file), join(copyPathWP5, file))
35
- }
36
- })
37
- }
38
-
39
- module.exports = copyDynamicImportChunks
@@ -1,9 +0,0 @@
1
- // Returns formatted redirect target
2
- const { DYNAMIC_PARAMETER_REGEX } = require('../constants/regex')
3
-
4
- const formatRedirectTarget = ({ basePath, target }) =>
5
- basePath && basePath !== '' && target.includes(basePath)
6
- ? target.replace(DYNAMIC_PARAMETER_REGEX, '/:$1').replace('[', '').replace(']', '').replace('...', '')
7
- : target
8
-
9
- module.exports = formatRedirectTarget
@@ -1,30 +0,0 @@
1
- const { join } = require('path')
2
-
3
- const { readFileSync } = require('fs-extra')
4
-
5
- const getFilePathForRoute = require('./getFilePathForRoute')
6
- const getNextDistDir = require('./getNextDistDir')
7
-
8
- const getPlainDataRoute = (route, buildId) => {
9
- const filePath = getFilePathForRoute(route, 'json')
10
- return `/_next/data/${buildId}${filePath}`
11
- }
12
-
13
- const getI18nDataRoute = (route, locale, buildId) => {
14
- const filePath = getFilePathForRoute(route, 'json')
15
- return route === '/' ? getPlainDataRoute(`/${locale}`, buildId) : `/_next/data/${buildId}/${locale}${filePath}`
16
- }
17
-
18
- // Return the data route for the given route
19
- const getDataRouteForRoute = async (route, locale) => {
20
- const nextDistDir = await getNextDistDir()
21
-
22
- // Get build ID that is used for data routes, e.g. /_next/data/BUILD_ID/...
23
- const fileContents = readFileSync(join(nextDistDir, 'BUILD_ID'))
24
- const buildId = fileContents.toString()
25
-
26
- if (locale) return getI18nDataRoute(route, locale, buildId)
27
- return getPlainDataRoute(route, buildId)
28
- }
29
-
30
- module.exports = getDataRouteForRoute
@@ -1,10 +0,0 @@
1
- // Return the file for the given route
2
- const getFilePathForRoute = (route, extension, locale) => {
3
- // Replace / with /index
4
- const path = route.replace(/^\/$/, '/index')
5
-
6
- if (locale) return `${locale}${path}.${extension}`
7
- return `${path}.${extension}`
8
- }
9
-
10
- module.exports = getFilePathForRoute
@@ -1,10 +0,0 @@
1
- // Get the i18n details specified in next.config.js, if any
2
- const getNextConfig = require('../../../helpers/getNextConfig')
3
-
4
- const getI18n = async () => {
5
- const nextConfig = await getNextConfig()
6
-
7
- return nextConfig.i18n || { locales: [] }
8
- }
9
-
10
- module.exports = getI18n