@netlify/plugin-nextjs 3.9.2 → 4.0.0-beta.4

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 +20 -55
  2. package/lib/constants.js +21 -0
  3. package/lib/helpers/cache.js +20 -0
  4. package/lib/helpers/config.js +119 -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 +47 -54
  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,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
@@ -1,38 +0,0 @@
1
- const path = require('path')
2
-
3
- // Generate the Netlify Function name for the given file path.
4
- // The file path will be pages/directory/subdirectory/[id].js
5
- // The function name will be next_directory_subdirectory_[id]
6
- // We do this because every function needs to be at the top-level, i.e.
7
- // nested functions are not allowed.
8
- const getNetlifyFunctionName = (filePath, isApiPage) => {
9
- // Remove pages/ from file path:
10
- // pages/directory/page.js > directory/page.js
11
- const relativeFilePath = path.relative('pages', filePath)
12
-
13
- // Extract directory path and file name without extension
14
- const { dir: directoryPath, name } = path.parse(relativeFilePath)
15
-
16
- // Combine next, directory path, and file name:
17
- // next/directory/page
18
- const filePathWithoutExtension = path.join('next', directoryPath, name)
19
-
20
- // Replace slashes with underscores:
21
- // next/directory/page > next_directory_page
22
- let functionName = filePathWithoutExtension.split(path.sep).join('_')
23
-
24
- // Netlify Function names may not contain periods or square brackets.
25
- // To be safe, we keep only alphanumeric characters and underscores.
26
- // See: https://community.netlify.com/t/failed-to-upload-functions-file-function-too-large/3549/8
27
- const cleanNameRegex = new RegExp(/[^\w\d]/g)
28
- // Allow users to use background functions for /api pages *only*
29
- // Note: this means that there is a chance a Next on Netlify user could
30
- // unknowingly create a background function if they're not familiar with them
31
- // and their syntax
32
- const allowBackgroundRegex = new RegExp(/[^\w\d-]|-(?!background$)/g)
33
- functionName = functionName.replace(isApiPage ? allowBackgroundRegex : cleanNameRegex, '')
34
-
35
- return functionName
36
- }
37
-
38
- module.exports = getNetlifyFunctionName
@@ -1,45 +0,0 @@
1
- // Adapted from @sls-next/lambda-at-edge (v1.2.0-alpha.3)
2
- // See: https://github.com/danielcondemarin/serverless-next.js/blob/57142970b08e6bc3faf0fc70749b3b0501ad7869/packages/lambda-at-edge/src/lib/expressifyDynamicRoute.ts#L4
3
-
4
- const { CATCH_ALL_REGEX, OPTIONAL_CATCH_ALL_REGEX, DYNAMIC_PARAMETER_REGEX } = require('../constants/regex')
5
-
6
- // Convert dynamic NextJS routes into their Netlify-equivalent
7
- // Note that file endings (.json) must be removed for catch-all and optional
8
- // catch-all routes to work. That's why the regexes defined above include
9
- // the (.json)? option
10
- const getNetlifyRoutes = (nextRoute) => {
11
- let netlifyRoutes = [nextRoute]
12
-
13
- // If the route is an optional catch-all route, we need to add a second
14
- // Netlify route for the base path (when no parameters are present).
15
- // The file ending must be present!
16
- if (OPTIONAL_CATCH_ALL_REGEX.test(nextRoute)) {
17
- let netlifyRoute = nextRoute.replace(OPTIONAL_CATCH_ALL_REGEX, '$2')
18
-
19
- // When optional catch-all route is at top-level, the regex on line 19 will
20
- // create an empty string, but actually needs to be a forward slash
21
- if (netlifyRoute === '') netlifyRoute = '/'
22
-
23
- // When optional catch-all route is at top-level, the regex on line 19 will
24
- // create an incorrect route for the data route. For example, it creates
25
- // /_next/data/%BUILDID%.json, but NextJS looks for
26
- // /_next/data/%BUILDID%/index.json
27
- netlifyRoute = netlifyRoute.replace(/(\/_next\/data\/[^/]+).json/, '$1/index.json')
28
-
29
- // Add second route to the front of the array
30
- netlifyRoutes.unshift(netlifyRoute)
31
- }
32
-
33
- // Replace catch-all, e.g., [...slug]
34
- netlifyRoutes = netlifyRoutes.map((route) => route.replace(CATCH_ALL_REGEX, '/:$1/*'))
35
-
36
- // Replace optional catch-all, e.g., [[...slug]]
37
- netlifyRoutes = netlifyRoutes.map((route) => route.replace(OPTIONAL_CATCH_ALL_REGEX, '/*'))
38
-
39
- // Replace dynamic parameters, e.g., [id]
40
- netlifyRoutes = netlifyRoutes.map((route) => route.replace(DYNAMIC_PARAMETER_REGEX, '/:$1'))
41
-
42
- return netlifyRoutes
43
- }
44
-
45
- module.exports = getNetlifyRoutes
@@ -1,12 +0,0 @@
1
- // Get the NextJS distDir specified in next.config.js
2
- const { join } = require('path')
3
-
4
- const getNextConfig = require('../../../helpers/getNextConfig')
5
-
6
- const getNextDistDir = async () => {
7
- const nextConfig = await getNextConfig()
8
-
9
- return join('.', nextConfig.distDir)
10
- }
11
-
12
- module.exports = getNextDistDir
@@ -1,5 +0,0 @@
1
- const { join } = require('path')
2
-
3
- const getNextSrcDirs = () => ['pages', 'src', 'public', 'styles'].map((dir) => join('.', dir))
4
-
5
- module.exports = getNextSrcDirs
@@ -1,19 +0,0 @@
1
- const { join } = require('path')
2
-
3
- const { existsSync, readJSONSync } = require('fs-extra')
4
-
5
- const getNextDistDir = require('./getNextDistDir')
6
-
7
- const getPagesManifest = async () => {
8
- const nextDistDir = await getNextDistDir()
9
- const manifestPath = join(nextDistDir, 'serverless', 'pages-manifest.json')
10
- if (!existsSync(manifestPath)) return {}
11
- const contents = readJSONSync(manifestPath)
12
- // Next.js mistakenly puts backslashes in certain paths on Windows, replace
13
- Object.entries(contents).forEach(([key, value]) => {
14
- contents[key] = value.replace(/\\/g, '/')
15
- })
16
- return contents
17
- }
18
-
19
- module.exports = getPagesManifest
@@ -1,40 +0,0 @@
1
- const { join } = require('path')
2
-
3
- const { readJSONSync } = require('fs-extra')
4
-
5
- const getNextConfig = require('../../../helpers/getNextConfig')
6
-
7
- const asyncForEach = require('./asyncForEach')
8
- const getDataRouteForRoute = require('./getDataRouteForRoute')
9
- const getNextDistDir = require('./getNextDistDir')
10
-
11
- const transformManifestForI18n = async (manifest) => {
12
- const { routes } = manifest
13
- const newRoutes = {}
14
- await asyncForEach(Object.entries(routes), async ([route, { dataRoute, srcRoute, ...params }]) => {
15
- const isDynamicRoute = Boolean(srcRoute)
16
- if (isDynamicRoute) {
17
- newRoutes[route] = routes[route]
18
- } else {
19
- const [, locale] = route.split('/')
20
- const routeWithoutLocale = `/${route.split('/').slice(2, route.split('/').length).join('/')}`
21
- newRoutes[route] = {
22
- dataRoute: await getDataRouteForRoute(routeWithoutLocale, locale),
23
- srcRoute: routeWithoutLocale,
24
- ...params,
25
- }
26
- }
27
- })
28
-
29
- return { ...manifest, routes: newRoutes }
30
- }
31
-
32
- const getPrerenderManifest = async () => {
33
- const nextConfig = await getNextConfig()
34
- const nextDistDir = await getNextDistDir()
35
- const manifest = readJSONSync(join(nextDistDir, 'prerender-manifest.json'))
36
- if (nextConfig.i18n) return await transformManifestForI18n(manifest)
37
- return manifest
38
- }
39
-
40
- module.exports = getPrerenderManifest
@@ -1,5 +0,0 @@
1
- // Some pages (getStaticProps/withFallback) require a separate standard function for preview mode; this provides the name for that function, to be called in several places
2
-
3
- const getPreviewModeFunctionName = (functionName) => `preview-${functionName}`
4
-
5
- module.exports = getPreviewModeFunctionName
@@ -1,12 +0,0 @@
1
- const { join } = require('path')
2
-
3
- const { readJSONSync } = require('fs-extra')
4
-
5
- const getNextDistDir = require('./getNextDistDir')
6
-
7
- const getRoutesManifest = async () => {
8
- const nextDistDir = await getNextDistDir()
9
- return readJSONSync(join(nextDistDir, 'routes-manifest.json'))
10
- }
11
-
12
- module.exports = getRoutesManifest
@@ -1,37 +0,0 @@
1
- const resolveNextModule = require('../../../helpers/resolveNextModule')
2
-
3
- const removeFileExtension = require('./removeFileExtension')
4
-
5
- // Return an array of redirects sorted in order of specificity, i.e., more generic
6
- // routes precede more specific ones
7
- const getSortedRedirects = (redirects) => {
8
- // The @sls-next getSortedRoutes does not correctly sort routes with file
9
- // endings (e.g., json), so we remove them before sorting and add them back
10
- // after sorting
11
- const routesWithoutExtensions = redirects.map(({ route }) => removeFileExtension(route))
12
-
13
- // Sort the "naked" routes
14
- // eslint-disable-next-line import/no-dynamic-require
15
- const { getSortedRoutes } = require(resolveNextModule(
16
- [
17
- // next <= 11.0.1
18
- 'next/dist/next-server/lib/router/utils/sorted-routes',
19
- // next > 11.0.1
20
- 'next/dist/shared/lib/router/utils/sorted-routes',
21
- ],
22
- process.cwd(),
23
- ))
24
- const sortedRoutes = getSortedRoutes(routesWithoutExtensions)
25
-
26
- // Return original routes in the sorted order
27
- return redirects.sort((a, b) => {
28
- // If routes are different, sort according to Next.js' getSortedRoutes
29
- if (a.route !== b.route) {
30
- return sortedRoutes.indexOf(removeFileExtension(a.route)) - sortedRoutes.indexOf(removeFileExtension(b.route))
31
- }
32
- // Otherwise, put the route with more conditions first
33
- return (b.conditions || []).length - (a.conditions || []).length
34
- })
35
- }
36
-
37
- module.exports = getSortedRedirects
@@ -1,61 +0,0 @@
1
- const { join } = require('path')
2
-
3
- const findCacheDir = require('find-cache-dir')
4
- const { existsSync, readdirSync, readFileSync, removeSync, writeFileSync } = require('fs-extra')
5
-
6
- const { NETLIFY_PUBLISH_PATH, NETLIFY_FUNCTIONS_PATH } = require('../config')
7
-
8
- const TRACKING_FILE_SEPARATOR = '---'
9
- const getDifference = (before, after) => after.filter((filePath) => !before.includes(filePath))
10
-
11
- // Clean configured publish and functions folders and track next-on-netlify files
12
- // for future cleans
13
- const handleFileTracking = ({ functionsPath, publishPath }) => {
14
- const isConfiguredFunctionsDir = functionsPath !== NETLIFY_FUNCTIONS_PATH
15
- const isConfiguredPublishDir = publishPath !== NETLIFY_PUBLISH_PATH
16
-
17
- const cacheDir = findCacheDir({ name: 'next-on-netlify', create: true })
18
- if (!cacheDir) return () => {}
19
- const trackingFilePath = join(cacheDir, '.nonfiletracking')
20
-
21
- if (existsSync(trackingFilePath)) {
22
- const trackingFile = readFileSync(trackingFilePath, 'utf8')
23
- const [trackedFunctions, trackedPublish] = trackingFile.split(TRACKING_FILE_SEPARATOR)
24
- const cleanConfiguredFiles = (trackedFiles, dirPath) => {
25
- trackedFiles
26
- .map((file) => file.trim())
27
- .filter(Boolean)
28
- .forEach((file) => {
29
- const filePath = join(dirPath, file)
30
- removeSync(filePath)
31
- })
32
- }
33
-
34
- if (isConfiguredPublishDir) {
35
- cleanConfiguredFiles(trackedPublish.split('\n'), publishPath)
36
- }
37
- if (isConfiguredFunctionsDir) {
38
- cleanConfiguredFiles(trackedFunctions.split('\n'), functionsPath)
39
- }
40
- }
41
-
42
- const functionsBeforeRun = existsSync(functionsPath) ? readdirSync(functionsPath) : []
43
- const publishBeforeRun = existsSync(publishPath) ? readdirSync(publishPath) : []
44
-
45
- // this callback will run at the end of nextOnNetlify()
46
- const trackNewFiles = () => {
47
- const functionsAfterRun =
48
- isConfiguredFunctionsDir && existsSync(functionsPath) ? readdirSync(functionsPath) : functionsBeforeRun
49
- const publishAfterRun =
50
- isConfiguredPublishDir && existsSync(publishPath) ? readdirSync(publishPath) : publishBeforeRun
51
- const newFunctionsFiles = getDifference(functionsBeforeRun, functionsAfterRun)
52
- const newPublishFiles = getDifference(publishBeforeRun, publishAfterRun)
53
-
54
- const allTrackedFiles = [...newFunctionsFiles, TRACKING_FILE_SEPARATOR, ...newPublishFiles]
55
- writeFileSync(trackingFilePath, allTrackedFiles.join('\n'))
56
- }
57
-
58
- return trackNewFiles
59
- }
60
-
61
- module.exports = handleFileTracking
@@ -1,4 +0,0 @@
1
- // Return true if the route is an API route
2
- const isApiRoute = (route) => route.startsWith('/api/')
3
-
4
- module.exports = isApiRoute
@@ -1,6 +0,0 @@
1
- // Return true if the route uses dynamic routing (e.g., [id] or [...slug])
2
- // (taken from @sls-next/lambda-at-edge)
3
-
4
- const isDynamicRoute = (route) => /\/\[[^/]+?](?=\/|$)/.test(route)
5
-
6
- module.exports = isDynamicRoute
@@ -1,5 +0,0 @@
1
- // Return true if the route is one of the framework pages, such as _app or
2
- // _error
3
- const isFrameworkRoute = (route) => ['/_app', '/_document', '/_error'].includes(route)
4
-
5
- module.exports = isFrameworkRoute
@@ -1,4 +0,0 @@
1
- // Return true if the file path is an HTML file
2
- const isHtmlFile = (filePath) => filePath.endsWith('.html')
3
-
4
- module.exports = isHtmlFile
@@ -1,6 +0,0 @@
1
- // Return true if the redirect is a root level catch-all
2
- // (e.g., /[[...slug]] or /[...slug])
3
- const isRootCatchAllRedirect = (redirect) =>
4
- redirect.startsWith('/*') || (redirect.startsWith('/:') && redirect.includes('/*'))
5
-
6
- module.exports = isRootCatchAllRedirect
@@ -1,23 +0,0 @@
1
- const getI18n = require('./getI18n')
2
- const getPrerenderManifest = require('./getPrerenderManifest')
3
-
4
- // Return true if the route is defined in the prerender manifest
5
- const isRouteInPrerenderManifest = async (route) => {
6
- const i18n = await getI18n()
7
- const { defaultLocale } = i18n
8
- const { routes, dynamicRoutes } = await getPrerenderManifest()
9
-
10
- const isRouteInManifestWithI18n = () => {
11
- let isStaticRoute = false
12
- Object.entries(routes).forEach(([staticRoute, { srcRoute }]) => {
13
- // This is because in i18n we set the nakedRoute to be the srcRoute in the manifest
14
- if (route === srcRoute) isStaticRoute = true
15
- })
16
- return isStaticRoute || route in dynamicRoutes
17
- }
18
-
19
- if (defaultLocale) return isRouteInManifestWithI18n(route)
20
- return route in routes || route in dynamicRoutes
21
- }
22
-
23
- module.exports = isRouteInPrerenderManifest
@@ -1,13 +0,0 @@
1
- const getRoutesManifest = require('./getRoutesManifest')
2
-
3
- // Return true if the route has a data route in the routes manifest
4
- const isRouteWithDataRoute = async (route) => {
5
- const { dataRoutes } = await getRoutesManifest()
6
-
7
- // If no data routes exist, return false
8
- if (dataRoutes == null) return false
9
-
10
- return dataRoutes.find((dataRoute) => dataRoute.page === route)
11
- }
12
-
13
- module.exports = isRouteWithDataRoute
@@ -1,12 +0,0 @@
1
- const getPrerenderManifest = require('./getPrerenderManifest')
2
-
3
- const isRouteWithFallback = async (route) => {
4
- if (!route) return false
5
-
6
- const { dynamicRoutes } = await getPrerenderManifest()
7
-
8
- // Fallback "blocking" routes will have fallback: null in manifest
9
- return dynamicRoutes[route] && dynamicRoutes[route].fallback !== false
10
- }
11
-
12
- module.exports = isRouteWithFallback
@@ -1,44 +0,0 @@
1
- // Helpers for writing info to console.log
2
- const { program } = require('commander')
3
-
4
- // Number of items processed in current build step
5
- let itemsCount = 0
6
-
7
- // Format in bold
8
- const logTitle = (...args) => {
9
- // Finish previous log section
10
- finishLogForBuildStep()
11
-
12
- // Print title
13
- log(`\x1b[1m${args.join(' ')}\x1b[22m`)
14
- }
15
-
16
- // Indent by three spaces
17
- const logItem = (...args) => {
18
- // Display item if within max log lines
19
- if (itemsCount < program.maxLogLines) log(' ', ...args)
20
-
21
- itemsCount += 1
22
- }
23
-
24
- // Just console.log
25
- const log = (...args) => console.log(...args)
26
-
27
- // Finish log section: Write a single line for any suppressed/hidden items
28
- // and reset the item counter
29
- const finishLogForBuildStep = () => {
30
- // Display number of suppressed log lines
31
- if (itemsCount > program.maxLogLines) {
32
- const hiddenLines = itemsCount - program.maxLogLines
33
- log(' ', '+', hiddenLines, 'more', '(run next-on-netlify with --max-log-lines XX to', 'show more or fewer lines)')
34
- }
35
-
36
- // Reset counter
37
- itemsCount = 0
38
- }
39
-
40
- module.exports = {
41
- logTitle,
42
- logItem,
43
- log,
44
- }
@@ -1,4 +0,0 @@
1
- // Remove the file extension form the route
2
- const removeFileExtension = (route) => route.replace(/\.[a-zA-Z]+$/, '')
3
-
4
- module.exports = removeFileExtension
@@ -1,18 +0,0 @@
1
- const os = require('os')
2
-
3
- const fastq = require('fastq')
4
-
5
- const { processPage } = require('../pages/worker')
6
-
7
- // TODO: benchmark a large site to find a good value for this
8
- const PAGE_CONCURRENCY = 4
9
-
10
- const runJobsQueue = (jobs) => {
11
- console.log(`Building ${jobs.length} pages`)
12
-
13
- const queue = fastq.promise(processPage, PAGE_CONCURRENCY)
14
-
15
- return Promise.all(jobs.map((job) => queue.push(job)))
16
- }
17
-
18
- module.exports = runJobsQueue
@@ -1,44 +0,0 @@
1
- const { join } = require('path')
2
-
3
- const { copySync, writeFile, ensureDir, copy } = require('fs-extra')
4
-
5
- const { TEMPLATES_DIR } = require('../config')
6
- const getTemplate = require('../templates/getTemplate')
7
-
8
- const copyDynamicImportChunks = require('./copyDynamicImportChunks')
9
- const getNetlifyFunctionName = require('./getNetlifyFunctionName')
10
- const getNextDistDir = require('./getNextDistDir')
11
- const getPreviewModeFunctionName = require('./getPreviewModeFunctionName')
12
- const { logItem } = require('./logger')
13
-
14
- // Create a Netlify Function for the page with the given file path
15
- const setupNetlifyFunctionForPage = async ({ filePath, functionsPath, isApiPage, isODB, forFallbackPreviewMode }) => {
16
- // Set function name based on file path
17
- const defaultFunctionName = getNetlifyFunctionName(filePath, isApiPage)
18
- const functionName = forFallbackPreviewMode ? getPreviewModeFunctionName(defaultFunctionName) : defaultFunctionName
19
- const functionDirectory = join(functionsPath, functionName)
20
-
21
- await ensureDir(functionDirectory)
22
-
23
- if (isApiPage && functionName.endsWith('-background')) {
24
- logItem(`👁 Setting up API page ${functionName} as a Netlify background function`)
25
- }
26
-
27
- // Write entry point to function directory
28
- const entryPointPath = join(functionDirectory, `${functionName}.js`)
29
- await writeFile(entryPointPath, getTemplate({ filePath, isODB }))
30
-
31
- // Copy function helper
32
- await copy(join(TEMPLATES_DIR, 'getHandlerFunction.js'), join(functionDirectory, 'getHandlerFunction.js'))
33
-
34
- // Copy any dynamic import chunks
35
- await copyDynamicImportChunks(functionDirectory)
36
-
37
- // Copy page to our custom path
38
- const nextPageCopyPath = join(functionDirectory, 'nextPage', filePath)
39
- const nextDistDir = await getNextDistDir()
40
-
41
- copySync(join(nextDistDir, 'serverless', filePath), nextPageCopyPath)
42
- }
43
-
44
- module.exports = setupNetlifyFunctionForPage
@@ -1,18 +0,0 @@
1
- const { join } = require('path')
2
-
3
- const { copySync } = require('fs-extra')
4
-
5
- const getNextDistDir = require('./getNextDistDir')
6
-
7
- // Copy the static asset from pages/inputPath to out_publish/outputPath
8
- const setupStaticFileForPage = async ({ inputPath, outputPath = null, publishPath }) => {
9
- const nextDistDir = await getNextDistDir()
10
-
11
- // Perform copy operation
12
- copySync(join(nextDistDir, 'serverless', 'pages', inputPath), join(publishPath, outputPath || inputPath), {
13
- overwrite: false,
14
- errorOnExist: true,
15
- })
16
- }
17
-
18
- module.exports = setupStaticFileForPage
@@ -1,22 +0,0 @@
1
- const getPagesManifest = require('../../helpers/getPagesManifest')
2
- const isApiRoute = require('../../helpers/isApiRoute')
3
-
4
- const getPages = async () => {
5
- // Get HTML and SSR pages and API endpoints from the NextJS pages manifest
6
- const pagesManifest = await getPagesManifest()
7
-
8
- // Collect pages
9
- const pages = []
10
-
11
- // Parse pages
12
- Object.entries(pagesManifest).forEach(([route, filePath]) => {
13
- // Skip non-API endpoints
14
- if (!isApiRoute(route)) return
15
-
16
- // Add page
17
- pages.push({ route, filePath })
18
- })
19
- return pages
20
- }
21
-
22
- module.exports = getPages
@@ -1,13 +0,0 @@
1
- const getNetlifyFunctionName = require('../../helpers/getNetlifyFunctionName')
2
-
3
- const getPages = require('./pages')
4
-
5
- const getRedirects = async () => {
6
- const pages = await getPages()
7
- return pages.map(({ route, filePath }) => ({
8
- route,
9
- target: `/.netlify/functions/${getNetlifyFunctionName(filePath, true)}`,
10
- }))
11
- }
12
-
13
- module.exports = getRedirects