Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: locate next.config.js by root publish directory, instead of root of repository #178

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions helpers/defaultFailBuild.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exports.defaultFailBuild = function (message, { error }) {
throw new Error(`${message}\n${error.stack}`)
}
13 changes: 6 additions & 7 deletions helpers/getNextConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,25 @@

const { resolve } = require('path')

const { defaultFailBuild } = require('./defaultFailBuild')
const moize = require('moize')

// Load next.config.js
const getNextConfig = async function (failBuild = defaultFailBuild) {
const getNextConfig = async function (params = {}) {
const { failBuild = defaultFailBuild, publishPath = '.' } = params

// We cannot load `next` at the top-level because we validate whether the
// site is using `next` inside `onPreBuild`.
const { PHASE_PRODUCTION_BUILD } = require('next/constants')
const loadConfig = require('next/dist/next-server/server/config').default

try {
return await loadConfig(PHASE_PRODUCTION_BUILD, resolve('.'))
return await loadConfig(PHASE_PRODUCTION_BUILD, resolve(publishPath))
} catch (error) {
return failBuild('Error loading your next.config.js.', { error })
}
}

const moizedGetNextConfig = moize(getNextConfig, { maxSize: 1e3, isPromise: true })

const defaultFailBuild = function (message, { error }) {
throw new Error(`${message}\n${error.stack}`)
}
const moizedGetNextConfig = moize(getNextConfig, { maxSize: 1e3, isPromise: true, isDeepEqual: true })

module.exports = moizedGetNextConfig
4 changes: 2 additions & 2 deletions helpers/hasCorrectNextConfig.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const getNextConfig = require('./getNextConfig')

// Checks if site has the correct next.config.js
const hasCorrectNextConfig = async ({ nextConfigPath, failBuild }) => {
const hasCorrectNextConfig = async ({ nextConfigPath, failBuild, publishPath }) => {
// In the plugin's case, no config is valid because we'll make it ourselves
if (nextConfigPath === undefined) return true

const { target } = await getNextConfig(failBuild)
const { target } = await getNextConfig({ failBuild, publishPath })

// If the next config exists, log warning if target isnt in acceptableTargets
const acceptableTargets = ['serverless', 'experimental-serverless-trace']
Expand Down
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const build = async (functionsPath, publishPath) => {

copyPublicFiles(publishPath)

await copyNextAssets(publishPath)
await copyNextAssets({ publishPath })

await setupPages({ functionsPath, publishPath })

Expand Down
4 changes: 2 additions & 2 deletions src/lib/helpers/addDefaultLocaleRedirect.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ const getI18n = require('./getI18n')
// to the defaultLocale-prepended route i.e. /static -> /en/static
// Note: there can only one defaultLocale, but we put it in an array to simplify
// logic in redirects.js files via concatenation
const addDefaultLocaleRedirect = async (redirects, route, target, additionalParams) => {
const i18n = await getI18n()
const addDefaultLocaleRedirect = async ({ redirects, route, target, additionalParams, publishPath }) => {
const i18n = await getI18n({ publishPath })
const { defaultLocale } = i18n

// If no i18n, skip
Expand Down
6 changes: 3 additions & 3 deletions src/lib/helpers/addLocaleRedirects.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ const getI18n = require('./getI18n')
const getDataRouteForRoute = require('./getDataRouteForRoute')
const asyncForEach = require('./asyncForEach')

const addLocaleRedirects = async (redirects, route, target) => {
const i18n = await getI18n()
const addLocaleRedirects = async ({ redirects, route, target, publishPath }) => {
const i18n = await getI18n({ publishPath })
await asyncForEach(i18n.locales, async (locale) => {
redirects.push({
route: `/${locale}${route === '/' ? '' : route}`,
target,
})
redirects.push({
route: await getDataRouteForRoute(route, locale),
route: await getDataRouteForRoute({ route, locale, publishPath }),
target,
})
})
Expand Down
4 changes: 2 additions & 2 deletions src/lib/helpers/copyDynamicImportChunks.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ const { logTitle } = require('../helpers/logger')
const getNextDistDir = require('./getNextDistDir')

// Check if there are dynamic import chunks and copy to the necessary function dir
const copyDynamicImportChunks = async (functionPath) => {
const nextDistDir = await getNextDistDir()
const copyDynamicImportChunks = async ({ functionPath, publishPath }) => {
const nextDistDir = await getNextDistDir({ publishPath })
const chunksPath = join(nextDistDir, 'serverless')
const files = readdirSync(chunksPath)
const chunkRegex = new RegExp(/^(\.?[-_$~A-Z0-9a-z]+){1,}\.js$/g)
Expand Down
4 changes: 2 additions & 2 deletions src/lib/helpers/getDataRouteForRoute.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ const getI18nDataRoute = (route, locale, buildId) => {
}

// Return the data route for the given route
const getDataRouteForRoute = async (route, locale) => {
const nextDistDir = await getNextDistDir()
const getDataRouteForRoute = async ({ route, locale, publishPath }) => {
const nextDistDir = await getNextDistDir({ publishPath })

// Get build ID that is used for data routes, e.g. /_next/data/BUILD_ID/...
const fileContents = readFileSync(join(nextDistDir, 'BUILD_ID'))
Expand Down
4 changes: 2 additions & 2 deletions src/lib/helpers/getI18n.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Get the i1i8n details specified in next.config.js, if any
const getNextConfig = require('../../../helpers/getNextConfig')

const getI18n = async () => {
const nextConfig = await getNextConfig()
const getI18n = async ({ publishPath }) => {
const nextConfig = await getNextConfig({ publishPath })

return nextConfig.i18n || { locales: [] }
}
Expand Down
5 changes: 3 additions & 2 deletions src/lib/helpers/getNextDistDir.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Get the NextJS distDir specified in next.config.js
const { join } = require('path')

const getNextConfig = require('../../../helpers/getNextConfig')

const getNextDistDir = async () => {
const nextConfig = await getNextConfig()
const getNextDistDir = async ({ publishPath }) => {
const nextConfig = await getNextConfig({ publishPath })

return join('.', nextConfig.distDir)
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib/helpers/getPagesManifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ const { join } = require('path')
const { existsSync, readJSONSync } = require('fs-extra')
const getNextDistDir = require('./getNextDistDir')

const getPagesManifest = async () => {
const nextDistDir = await getNextDistDir()
const getPagesManifest = async ({ publishPath }) => {
const nextDistDir = await getNextDistDir({ publishPath })
const manifestPath = join(nextDistDir, 'serverless', 'pages-manifest.json')
if (!existsSync(manifestPath)) return {}
const contents = readJSONSync(manifestPath)
Expand Down
12 changes: 6 additions & 6 deletions src/lib/helpers/getPrerenderManifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const getNextDistDir = require('./getNextDistDir')
const getDataRouteForRoute = require('./getDataRouteForRoute')
const asyncForEach = require('./asyncForEach')

const transformManifestForI18n = async (manifest) => {
const transformManifestForI18n = async ({ manifest, publishPath }) => {
const { routes } = manifest
const newRoutes = {}
await asyncForEach(Object.entries(routes), async ([route, { dataRoute, srcRoute, ...params }]) => {
Expand All @@ -16,7 +16,7 @@ const transformManifestForI18n = async (manifest) => {
const locale = route.split('/')[1]
const routeWithoutLocale = `/${route.split('/').slice(2, route.split('/').length).join('/')}`
newRoutes[route] = {
dataRoute: await getDataRouteForRoute(routeWithoutLocale, locale),
dataRoute: await getDataRouteForRoute({ route: routeWithoutLocale, locale, publishPath }),
srcRoute: routeWithoutLocale,
...params,
}
Expand All @@ -26,11 +26,11 @@ const transformManifestForI18n = async (manifest) => {
return { ...manifest, routes: newRoutes }
}

const getPrerenderManifest = async () => {
const nextConfig = await getNextConfig()
const nextDistDir = await getNextDistDir()
const getPrerenderManifest = async ({ publishPath }) => {
const nextConfig = await getNextConfig({ publishPath })
const nextDistDir = await getNextDistDir({ publishPath })
const manifest = readJSONSync(join(nextDistDir, 'prerender-manifest.json'))
if (nextConfig.i18n) return await transformManifestForI18n(manifest)
if (nextConfig.i18n) return await transformManifestForI18n({ manifest, publishPath })
return manifest
}

Expand Down
4 changes: 2 additions & 2 deletions src/lib/helpers/getRoutesManifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ const { join } = require('path')
const { readJSONSync } = require('fs-extra')
const getNextDistDir = require('./getNextDistDir')

const getRoutesManifest = async () => {
const nextDistDir = await getNextDistDir()
const getRoutesManifest = async ({ publishPath }) => {
const nextDistDir = await getNextDistDir({ publishPath })
return readJSONSync(join(nextDistDir, 'routes-manifest.json'))
}

Expand Down
8 changes: 4 additions & 4 deletions src/lib/helpers/isRouteInPrerenderManifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ const getPrerenderManifest = require('./getPrerenderManifest')
const getI18n = require('./getI18n')

// Return true if the route is defined in the prerender manifest
const isRouteInPrerenderManifest = async (route) => {
const i18n = await getI18n()
const isRouteInPrerenderManifest = async ({ route, publishPath }) => {
const i18n = await getI18n({ publishPath })
const { defaultLocale, locales } = i18n
const { routes, dynamicRoutes } = await getPrerenderManifest()
const { routes, dynamicRoutes } = await getPrerenderManifest({ publishPath })

const isRouteInManifestWithI18n = () => {
let isStaticRoute = false
Expand All @@ -16,7 +16,7 @@ const isRouteInPrerenderManifest = async (route) => {
return isStaticRoute || route in dynamicRoutes
}

if (i18n.defaultLocale) return isRouteInManifestWithI18n(route)
if (i18n.defaultLocale) return isRouteInManifestWithI18n()
return route in routes || route in dynamicRoutes
}

Expand Down
4 changes: 2 additions & 2 deletions src/lib/helpers/isRouteWithDataRoute.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const getRoutesManifest = require('./getRoutesManifest')

// Return true if the route has a data route in the routes manifest
const isRouteWithDataRoute = async (route) => {
const { dataRoutes } = await getRoutesManifest()
const isRouteWithDataRoute = async ({ route, publishPath }) => {
const { dataRoutes } = await getRoutesManifest({ publishPath })

// If no data routes exist, return false
if (dataRoutes == null) return false
Expand Down
4 changes: 2 additions & 2 deletions src/lib/helpers/isRouteWithFallback.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const getPrerenderManifest = require('./getPrerenderManifest')

const isRouteWithFallback = async (route) => {
const { dynamicRoutes } = await getPrerenderManifest()
const isRouteWithFallback = async ({ route, publishPath }) => {
const { dynamicRoutes } = await getPrerenderManifest({ publishPath })

// Fallback "blocking" routes will have fallback: null in manifest
return dynamicRoutes[route] && dynamicRoutes[route].fallback !== false
Expand Down
6 changes: 3 additions & 3 deletions src/lib/helpers/setupNetlifyFunctionForPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const copyDynamicImportChunks = require('./copyDynamicImportChunks')
const { logItem } = require('./logger')

// Create a Netlify Function for the page with the given file path
const setupNetlifyFunctionForPage = async ({ filePath, functionsPath, isApiPage }) => {
const setupNetlifyFunctionForPage = async ({ filePath, functionsPath, isApiPage, publishPath }) => {
// Set function name based on file path
const functionName = getNetlifyFunctionName(filePath, isApiPage)
const functionDirectory = join(functionsPath, functionName)
Expand All @@ -33,11 +33,11 @@ const setupNetlifyFunctionForPage = async ({ filePath, functionsPath, isApiPage
})

// Copy any dynamic import chunks
await copyDynamicImportChunks(functionDirectory)
await copyDynamicImportChunks({ functionPath: functionDirectory, publishPath })

// Copy page
const nextPageCopyPath = join(functionDirectory, 'nextPage', 'index.js')
const nextDistDir = await getNextDistDir()
const nextDistDir = await getNextDistDir({ publishPath })
copySync(join(nextDistDir, 'serverless', filePath), nextPageCopyPath, {
overwrite: false,
errorOnExist: true,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/helpers/setupStaticFileForPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const setupStaticFileForPage = async ({ inputPath, outputPath = null, publishPat
// If no outputPath is set, default to the same as inputPath
outputPath = outputPath || inputPath

const nextDistDir = await getNextDistDir()
const nextDistDir = await getNextDistDir({ publishPath })

// Perform copy operation
copySync(join(nextDistDir, 'serverless', 'pages', inputPath), join(publishPath, outputPath), {
Expand Down
4 changes: 2 additions & 2 deletions src/lib/pages/api/pages.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const getPagesManifest = require('../../helpers/getPagesManifest')
const isApiRoute = require('../../helpers/isApiRoute')

const getPages = async () => {
const getPages = async ({ publishPath }) => {
// Get HTML and SSR pages and API endpoints from the NextJS pages manifest
const pagesManifest = await getPagesManifest()
const pagesManifest = await getPagesManifest({ publishPath })

// Collect pages
const pages = []
Expand Down
4 changes: 2 additions & 2 deletions src/lib/pages/api/redirects.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const getNetlifyFunctionName = require('../../helpers/getNetlifyFunctionName')
const getPages = require('./pages')

const getRedirects = async () => {
const pages = await getPages()
const getRedirects = async ({ publishPath }) => {
const pages = await getPages({ publishPath })
return pages.map(({ route, filePath }) => ({
route,
target: `/.netlify/functions/${getNetlifyFunctionName(filePath, true)}`,
Expand Down
6 changes: 3 additions & 3 deletions src/lib/pages/api/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ const asyncForEach = require('../../helpers/asyncForEach')
const getPages = require('./pages')

// Create a Netlify Function for every API endpoint
const setup = async (functionsPath) => {
const setup = async ({ functionsPath, publishPath }) => {
logTitle('💫 Setting up API endpoints as Netlify Functions in', functionsPath)

const pages = await getPages()
const pages = await getPages({ publishPath })

// Create Netlify Function for every page
await asyncForEach(pages, async ({ filePath }) => {
logItem(filePath)
await setupNetlifyFunctionForPage({ filePath, functionsPath, isApiPage: true })
await setupNetlifyFunctionForPage({ filePath, functionsPath, isApiPage: true, publishPath })
})
}

Expand Down
8 changes: 4 additions & 4 deletions src/lib/pages/getInitialProps/pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ const isRouteInPrerenderManifest = require('../../helpers/isRouteInPrerenderMani
const isRouteWithDataRoute = require('../../helpers/isRouteWithDataRoute')
const asyncForEach = require('../../helpers/asyncForEach')

const getPages = async () => {
const getPages = async ({ publishPath }) => {
// Get HTML and SSR pages and API endpoints from the NextJS pages manifest
const pagesManifest = await getPagesManifest()
const pagesManifest = await getPagesManifest({ publishPath })

// Collect pages
const pages = []
Expand All @@ -25,11 +25,11 @@ const getPages = async () => {
if (isApiRoute(route)) return

// Skip page if it is actually used with getStaticProps
if (await isRouteInPrerenderManifest(route)) return
if (await isRouteInPrerenderManifest({ route, publishPath })) return

// Skip page if it has a data route (because then it is a page with
// getServerSideProps)
if (await isRouteWithDataRoute(route)) return
if (await isRouteWithDataRoute({ route, publishPath })) return

// Add page
pages.push({ route, filePath })
Expand Down
6 changes: 3 additions & 3 deletions src/lib/pages/getInitialProps/redirects.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ const getNetlifyFunctionName = require('../../helpers/getNetlifyFunctionName')
const asyncForEach = require('../../helpers/asyncForEach')
const getPages = require('./pages')

const getRedirects = async () => {
const getRedirects = async ({ publishPath }) => {
const redirects = []
const pages = await getPages()
const pages = await getPages({ publishPath })

await asyncForEach(pages, async ({ route, filePath }) => {
const functionName = getNetlifyFunctionName(filePath)
const target = `/.netlify/functions/${functionName}`

await addLocaleRedirects(redirects, route, target)
await addLocaleRedirects({ redirects, route, target, publishPath })

redirects.push({
route,
Expand Down
6 changes: 3 additions & 3 deletions src/lib/pages/getInitialProps/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ const asyncForEach = require('../../helpers/asyncForEach')
const getPages = require('./pages')

// Create a Netlify Function for every page with getInitialProps
const setup = async (functionsPath) => {
const setup = async ({ functionsPath, publishPath }) => {
logTitle('💫 Setting up pages with getInitialProps as Netlify Functions in', functionsPath)

const pages = await getPages()
const pages = await getPages({ publishPath })

// Create Netlify Function for every page
await asyncForEach(pages, async ({ filePath }) => {
logItem(filePath)
await setupNetlifyFunctionForPage({ filePath, functionsPath })
await setupNetlifyFunctionForPage({ filePath, functionsPath, publishPath })
})
}

Expand Down
Loading