mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Clean up references to this.dir and this.dist everywhere (#4535)
This was spread around the server. Now it's set in one place and passed around.
This commit is contained in:
parent
18676e0870
commit
a7bb9175eb
|
@ -6,3 +6,9 @@ export const PAGES_MANIFEST = 'pages-manifest.json'
|
|||
export const BUILD_MANIFEST = 'build-manifest.json'
|
||||
export const SERVER_DIRECTORY = 'server'
|
||||
export const CONFIG_FILE = 'next.config.js'
|
||||
export const BUILD_ID_FILE = 'BUILD_ID'
|
||||
export const BLOCKED_PAGES = [
|
||||
'/_document',
|
||||
'/_app',
|
||||
'/_error'
|
||||
]
|
||||
|
|
|
@ -3,7 +3,7 @@ import promisify from '../lib/promisify'
|
|||
import fs from 'fs'
|
||||
import webpack from 'webpack'
|
||||
import loadConfig from '../config'
|
||||
import { PHASE_PRODUCTION_BUILD } from '../../lib/constants'
|
||||
import { PHASE_PRODUCTION_BUILD, BUILD_ID_FILE } from '../../lib/constants'
|
||||
import getBaseWebpackConfig from './webpack'
|
||||
|
||||
const access = promisify(fs.access)
|
||||
|
@ -12,6 +12,7 @@ const writeFile = promisify(fs.writeFile)
|
|||
export default async function build (dir, conf = null) {
|
||||
const config = loadConfig(PHASE_PRODUCTION_BUILD, dir, conf)
|
||||
const buildId = await config.generateBuildId() // defaults to a uuid
|
||||
const distDir = join(dir, config.distDir)
|
||||
|
||||
try {
|
||||
await access(dir, (fs.constants || fs).W_OK)
|
||||
|
@ -28,7 +29,7 @@ export default async function build (dir, conf = null) {
|
|||
|
||||
await runCompiler(configs)
|
||||
|
||||
await writeBuildId(dir, buildId, config)
|
||||
await writeBuildId(distDir, buildId)
|
||||
} catch (err) {
|
||||
console.error(`> Failed to build`)
|
||||
throw err
|
||||
|
@ -55,7 +56,7 @@ function runCompiler (compiler) {
|
|||
})
|
||||
}
|
||||
|
||||
async function writeBuildId (dir, buildId, config) {
|
||||
const buildIdPath = join(dir, config.distDir, 'BUILD_ID')
|
||||
async function writeBuildId (distDir, buildId) {
|
||||
const buildIdPath = join(distDir, BUILD_ID_FILE)
|
||||
await writeFile(buildIdPath, buildId, 'utf8')
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import walk from 'walk'
|
|||
import { extname, resolve, join, dirname, sep } from 'path'
|
||||
import { existsSync, readFileSync, writeFileSync } from 'fs'
|
||||
import loadConfig from './config'
|
||||
import {PHASE_EXPORT, SERVER_DIRECTORY, PAGES_MANIFEST, CONFIG_FILE} from '../lib/constants'
|
||||
import {PHASE_EXPORT, SERVER_DIRECTORY, PAGES_MANIFEST, CONFIG_FILE, BUILD_ID_FILE} from '../lib/constants'
|
||||
import { renderToHTML } from './render'
|
||||
import { getAvailableChunks } from './utils'
|
||||
import { setAssetPrefix } from '../lib/asset'
|
||||
|
@ -14,16 +14,16 @@ import * as envConfig from '../lib/runtime-config'
|
|||
export default async function (dir, options, configuration) {
|
||||
dir = resolve(dir)
|
||||
const nextConfig = configuration || loadConfig(PHASE_EXPORT, dir)
|
||||
const nextDir = join(dir, nextConfig.distDir)
|
||||
const distDir = join(dir, nextConfig.distDir)
|
||||
|
||||
log(`> using build directory: ${nextDir}`)
|
||||
log(`> using build directory: ${distDir}`)
|
||||
|
||||
if (!existsSync(nextDir)) {
|
||||
throw new Error(`Build directory ${nextDir} does not exist. Make sure you run "next build" before running "next start" or "next export".`)
|
||||
if (!existsSync(distDir)) {
|
||||
throw new Error(`Build directory ${distDir} does not exist. Make sure you run "next build" before running "next start" or "next export".`)
|
||||
}
|
||||
|
||||
const buildId = readFileSync(join(nextDir, 'BUILD_ID'), 'utf8')
|
||||
const pagesManifest = require(join(nextDir, SERVER_DIRECTORY, PAGES_MANIFEST))
|
||||
const buildId = readFileSync(join(distDir, BUILD_ID_FILE), 'utf8')
|
||||
const pagesManifest = require(join(distDir, SERVER_DIRECTORY, PAGES_MANIFEST))
|
||||
|
||||
const pages = Object.keys(pagesManifest)
|
||||
const defaultPathMap = {}
|
||||
|
@ -52,26 +52,26 @@ export default async function (dir, options, configuration) {
|
|||
}
|
||||
|
||||
// Copy .next/static directory
|
||||
if (existsSync(join(nextDir, 'static'))) {
|
||||
if (existsSync(join(distDir, 'static'))) {
|
||||
log(' copying "static build" directory')
|
||||
await cp(
|
||||
join(nextDir, 'static'),
|
||||
join(distDir, 'static'),
|
||||
join(outDir, '_next', 'static')
|
||||
)
|
||||
}
|
||||
|
||||
// Copy dynamic import chunks
|
||||
if (existsSync(join(nextDir, 'chunks'))) {
|
||||
if (existsSync(join(distDir, 'chunks'))) {
|
||||
log(' copying dynamic import chunks')
|
||||
|
||||
await mkdirp(join(outDir, '_next', 'webpack'))
|
||||
await cp(
|
||||
join(nextDir, 'chunks'),
|
||||
join(distDir, 'chunks'),
|
||||
join(outDir, '_next', 'webpack', 'chunks')
|
||||
)
|
||||
}
|
||||
|
||||
await copyPages(nextDir, outDir, buildId)
|
||||
await copyPages(distDir, outDir, buildId)
|
||||
|
||||
// Get the exportPathMap from the config file
|
||||
if (typeof nextConfig.exportPathMap !== 'function') {
|
||||
|
@ -84,14 +84,14 @@ export default async function (dir, options, configuration) {
|
|||
// Start the rendering process
|
||||
const renderOpts = {
|
||||
dir,
|
||||
dist: nextConfig.distDir,
|
||||
buildId,
|
||||
nextExport: true,
|
||||
assetPrefix: nextConfig.assetPrefix.replace(/\/$/, ''),
|
||||
distDir,
|
||||
dev: false,
|
||||
staticMarkup: false,
|
||||
hotReloader: null,
|
||||
availableChunks: getAvailableChunks(dir, nextConfig.distDir)
|
||||
availableChunks: getAvailableChunks(distDir)
|
||||
}
|
||||
|
||||
const {serverRuntimeConfig, publicRuntimeConfig} = nextConfig
|
||||
|
@ -152,10 +152,10 @@ export default async function (dir, options, configuration) {
|
|||
}
|
||||
}
|
||||
|
||||
function copyPages (nextDir, outDir, buildId) {
|
||||
function copyPages (distDir, outDir, buildId) {
|
||||
// TODO: do some proper error handling
|
||||
return new Promise((resolve, reject) => {
|
||||
const nextBundlesDir = join(nextDir, 'bundles', 'pages')
|
||||
const nextBundlesDir = join(distDir, 'bundles', 'pages')
|
||||
const walker = walk.walk(nextBundlesDir, { followLinks: false })
|
||||
|
||||
walker.on('file', (root, stat, next) => {
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
import Router from './router'
|
||||
import { getAvailableChunks, isInternalUrl } from './utils'
|
||||
import loadConfig from './config'
|
||||
import {PHASE_PRODUCTION_SERVER, PHASE_DEVELOPMENT_SERVER} from '../lib/constants'
|
||||
import {PHASE_PRODUCTION_SERVER, PHASE_DEVELOPMENT_SERVER, BLOCKED_PAGES, BUILD_ID_FILE} from '../lib/constants'
|
||||
import * as asset from '../lib/asset'
|
||||
import * as envConfig from '../lib/runtime-config'
|
||||
import { isResSent } from '../lib/utils'
|
||||
|
@ -26,12 +26,6 @@ import pkg from '../../package'
|
|||
|
||||
const access = promisify(fs.access)
|
||||
|
||||
const blockedPages = {
|
||||
'/_document': true,
|
||||
'/_app': true,
|
||||
'/_error': true
|
||||
}
|
||||
|
||||
export default class Server {
|
||||
constructor ({ dir = '.', dev = false, staticMarkup = false, quiet = false, conf = null } = {}) {
|
||||
this.dir = resolve(dir)
|
||||
|
@ -41,7 +35,7 @@ export default class Server {
|
|||
this.http = null
|
||||
const phase = dev ? PHASE_DEVELOPMENT_SERVER : PHASE_PRODUCTION_SERVER
|
||||
this.nextConfig = loadConfig(phase, this.dir, conf)
|
||||
this.dist = this.nextConfig.distDir
|
||||
this.distDir = join(dir, this.nextConfig.distDir)
|
||||
|
||||
this.hotReloader = dev ? this.getHotReloader(this.dir, { quiet, config: this.nextConfig }) : null
|
||||
|
||||
|
@ -49,19 +43,18 @@ export default class Server {
|
|||
// publicRuntimeConfig gets it's default in client/index.js
|
||||
const {serverRuntimeConfig = {}, publicRuntimeConfig, assetPrefix, generateEtags} = this.nextConfig
|
||||
|
||||
if (!dev && !fs.existsSync(resolve(dir, this.dist, 'BUILD_ID'))) {
|
||||
console.error(`> Could not find a valid build in the '${this.dist}' directory! Try building your app with 'next build' before starting the server.`)
|
||||
if (!dev && !fs.existsSync(resolve(this.distDir, BUILD_ID_FILE))) {
|
||||
console.error(`> Could not find a valid build in the '${this.distDir}' directory! Try building your app with 'next build' before starting the server.`)
|
||||
process.exit(1)
|
||||
}
|
||||
this.buildId = !dev ? this.readBuildId() : '-'
|
||||
this.renderOpts = {
|
||||
dev,
|
||||
staticMarkup,
|
||||
dir: this.dir,
|
||||
dist: this.dist,
|
||||
distDir: this.distDir,
|
||||
hotReloader: this.hotReloader,
|
||||
buildId: this.buildId,
|
||||
availableChunks: dev ? {} : getAvailableChunks(this.dir, this.dist),
|
||||
availableChunks: dev ? {} : getAvailableChunks(this.distDir),
|
||||
generateEtags
|
||||
}
|
||||
|
||||
|
@ -159,13 +152,13 @@ export default class Server {
|
|||
if (!this.dev) {
|
||||
res.setHeader('Cache-Control', 'public, max-age=31536000, immutable')
|
||||
}
|
||||
const p = join(this.dir, this.dist, 'chunks', params.name)
|
||||
const p = join(this.distDir, 'chunks', params.name)
|
||||
await this.serveStatic(req, res, p)
|
||||
},
|
||||
|
||||
// This is to support, webpack dynamic import support with HMR
|
||||
'/_next/webpack/:id': async (req, res, params) => {
|
||||
const p = join(this.dir, this.dist, 'chunks', params.id)
|
||||
const p = join(this.distDir, 'chunks', params.id)
|
||||
await this.serveStatic(req, res, p)
|
||||
},
|
||||
|
||||
|
@ -181,7 +174,7 @@ export default class Server {
|
|||
}
|
||||
}
|
||||
|
||||
const path = join(this.dir, this.dist, 'bundles', 'pages', `${page}.js.map`)
|
||||
const path = join(this.distDir, 'bundles', 'pages', `${page}.js.map`)
|
||||
await serveStatic(req, res, path)
|
||||
},
|
||||
|
||||
|
@ -207,7 +200,7 @@ export default class Server {
|
|||
}
|
||||
}
|
||||
|
||||
const p = join(this.dir, this.dist, 'bundles', 'pages', `${page}.js`)
|
||||
const p = join(this.distDir, 'bundles', 'pages', `${page}.js`)
|
||||
|
||||
// [production] If the page is not exists, we need to send a proper Next.js style 404
|
||||
// Otherwise, it'll affect the multi-zones feature.
|
||||
|
@ -230,7 +223,7 @@ export default class Server {
|
|||
res.setHeader('Cache-Control', 'public, max-age=31536000, immutable')
|
||||
}
|
||||
}
|
||||
const p = join(this.dir, this.dist, 'static', ...(params.path || []))
|
||||
const p = join(this.distDir, 'static', ...(params.path || []))
|
||||
await this.serveStatic(req, res, p)
|
||||
},
|
||||
|
||||
|
@ -315,7 +308,7 @@ export default class Server {
|
|||
return this.handleRequest(req, res, parsedUrl)
|
||||
}
|
||||
|
||||
if (blockedPages[pathname]) {
|
||||
if (BLOCKED_PAGES.indexOf(pathname) !== -1) {
|
||||
return await this.render404(req, res, parsedUrl)
|
||||
}
|
||||
|
||||
|
@ -408,7 +401,7 @@ export default class Server {
|
|||
isServeableUrl (path) {
|
||||
const resolved = resolve(path)
|
||||
if (
|
||||
resolved.indexOf(join(this.dir, this.dist) + sep) !== 0 &&
|
||||
resolved.indexOf(join(this.distDir) + sep) !== 0 &&
|
||||
resolved.indexOf(join(this.dir, 'static') + sep) !== 0
|
||||
) {
|
||||
// Seems like the user is trying to traverse the filesystem.
|
||||
|
@ -419,7 +412,7 @@ export default class Server {
|
|||
}
|
||||
|
||||
readBuildId () {
|
||||
const buildIdPath = join(this.dir, this.dist, 'BUILD_ID')
|
||||
const buildIdPath = join(this.distDir, BUILD_ID_FILE)
|
||||
const buildId = fs.readFileSync(buildIdPath, 'utf8')
|
||||
return buildId.trim()
|
||||
}
|
||||
|
|
|
@ -42,8 +42,8 @@ async function doRender (req, res, pathname, query, {
|
|||
assetPrefix,
|
||||
runtimeConfig,
|
||||
availableChunks,
|
||||
dist,
|
||||
dir = process.cwd(),
|
||||
distDir,
|
||||
dir,
|
||||
dev = false,
|
||||
staticMarkup = false,
|
||||
nextExport = false
|
||||
|
@ -56,11 +56,11 @@ async function doRender (req, res, pathname, query, {
|
|||
await ensurePage(page, { dir, hotReloader })
|
||||
}
|
||||
|
||||
const documentPath = join(dir, dist, SERVER_DIRECTORY, 'bundles', 'pages', '_document')
|
||||
const appPath = join(dir, dist, SERVER_DIRECTORY, 'bundles', 'pages', '_app')
|
||||
const buildManifest = require(join(dir, dist, BUILD_MANIFEST))
|
||||
const documentPath = join(distDir, SERVER_DIRECTORY, 'bundles', 'pages', '_document')
|
||||
const appPath = join(distDir, SERVER_DIRECTORY, 'bundles', 'pages', '_app')
|
||||
const buildManifest = require(join(distDir, BUILD_MANIFEST))
|
||||
let [Component, Document, App] = await Promise.all([
|
||||
requirePage(page, {dir, dist}),
|
||||
requirePage(page, {distDir}),
|
||||
require(documentPath),
|
||||
require(appPath)
|
||||
])
|
||||
|
@ -105,7 +105,7 @@ async function doRender (req, res, pathname, query, {
|
|||
} finally {
|
||||
head = Head.rewind() || defaultHead()
|
||||
}
|
||||
const chunks = loadChunks({ dev, dir, dist, availableChunks })
|
||||
const chunks = loadChunks({ dev, distDir, availableChunks })
|
||||
|
||||
return { html, head, errorHtml, chunks, buildManifest }
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ async function ensurePage (page, { dir, hotReloader }) {
|
|||
await hotReloader.ensurePage(page)
|
||||
}
|
||||
|
||||
function loadChunks ({ dev, dir, dist, availableChunks }) {
|
||||
function loadChunks ({ dev, distDir, availableChunks }) {
|
||||
const flushedChunks = flushChunks()
|
||||
const response = {
|
||||
names: [],
|
||||
|
@ -238,7 +238,7 @@ function loadChunks ({ dev, dir, dist, availableChunks }) {
|
|||
}
|
||||
|
||||
if (dev) {
|
||||
availableChunks = getAvailableChunks(dir, dist)
|
||||
availableChunks = getAvailableChunks(distDir)
|
||||
}
|
||||
|
||||
for (var chunk of flushedChunks) {
|
||||
|
|
|
@ -27,8 +27,8 @@ export function normalizePagePath (page) {
|
|||
return page
|
||||
}
|
||||
|
||||
export function getPagePath (page, {dir, dist}) {
|
||||
const serverBuildPath = join(dir, dist, SERVER_DIRECTORY)
|
||||
export function getPagePath (page, {distDir}) {
|
||||
const serverBuildPath = join(distDir, SERVER_DIRECTORY)
|
||||
const pagesManifest = require(join(serverBuildPath, PAGES_MANIFEST))
|
||||
|
||||
try {
|
||||
|
@ -45,7 +45,7 @@ export function getPagePath (page, {dir, dist}) {
|
|||
return join(serverBuildPath, pagesManifest[page])
|
||||
}
|
||||
|
||||
export default async function requirePage (page, {dir, dist}) {
|
||||
const pagePath = getPagePath(page, {dir, dist})
|
||||
export default async function requirePage (page, {distDir}) {
|
||||
const pagePath = getPagePath(page, {distDir})
|
||||
return require(pagePath)
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ import { readdirSync, existsSync } from 'fs'
|
|||
export const IS_BUNDLED_PAGE = /^bundles[/\\]pages.*\.js$/
|
||||
export const MATCH_ROUTE_NAME = /^bundles[/\\]pages[/\\](.*)\.js$/
|
||||
|
||||
export function getAvailableChunks (dir, dist) {
|
||||
const chunksDir = join(dir, dist, 'chunks')
|
||||
export function getAvailableChunks (distDir) {
|
||||
const chunksDir = join(distDir, 'chunks')
|
||||
if (!existsSync(chunksDir)) return {}
|
||||
|
||||
const chunksMap = {}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import { join } from 'path'
|
||||
import { existsSync } from 'fs'
|
||||
import {BUILD_ID_FILE} from 'next/constants'
|
||||
import {
|
||||
nextServer,
|
||||
nextBuild,
|
||||
|
@ -39,10 +40,10 @@ describe('Production Usage', () => {
|
|||
|
||||
describe('File locations', () => {
|
||||
it('should build the app within the given `dist` directory', () => {
|
||||
expect(existsSync(join(__dirname, '/../dist/BUILD_ID'))).toBeTruthy()
|
||||
expect(existsSync(join(__dirname, `/../dist/${BUILD_ID_FILE}`))).toBeTruthy()
|
||||
})
|
||||
it('should not build the app within the default `.next` directory', () => {
|
||||
expect(existsSync(join(__dirname, '/../.next/BUILD_ID'))).toBeFalsy()
|
||||
expect(existsSync(join(__dirname, `/../.next/${BUILD_ID_FILE}`))).toBeFalsy()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -5,7 +5,8 @@ import {SERVER_DIRECTORY} from 'next/constants'
|
|||
import requirePage, {getPagePath, normalizePagePath, pageNotFoundError} from '../../dist/server/require'
|
||||
|
||||
const sep = '/'
|
||||
const pathToBundles = join(__dirname, '_resolvedata', SERVER_DIRECTORY, 'bundles', 'pages')
|
||||
const distDir = join(__dirname, '_resolvedata')
|
||||
const pathToBundles = join(distDir, SERVER_DIRECTORY, 'bundles', 'pages')
|
||||
|
||||
describe('pageNotFoundError', () => {
|
||||
it('Should throw error with ENOENT code', () => {
|
||||
|
@ -41,39 +42,39 @@ describe('normalizePagePath', () => {
|
|||
|
||||
describe('getPagePath', () => {
|
||||
it('Should append /index to the / page', () => {
|
||||
const pagePath = getPagePath('/', {dir: __dirname, dist: '_resolvedata'})
|
||||
const pagePath = getPagePath('/', {distDir})
|
||||
expect(pagePath).toBe(join(pathToBundles, `${sep}index.js`))
|
||||
})
|
||||
|
||||
it('Should prepend / when a page does not have it', () => {
|
||||
const pagePath = getPagePath('_error', {dir: __dirname, dist: '_resolvedata'})
|
||||
const pagePath = getPagePath('_error', {distDir})
|
||||
expect(pagePath).toBe(join(pathToBundles, `${sep}_error.js`))
|
||||
})
|
||||
|
||||
it('Should throw with paths containing ../', () => {
|
||||
expect(() => getPagePath('/../../package.json', {dir: __dirname, dist: '_resolvedata'})).toThrow()
|
||||
expect(() => getPagePath('/../../package.json', {distDir})).toThrow()
|
||||
})
|
||||
})
|
||||
|
||||
describe('requirePage', () => {
|
||||
it('Should require /index.js when using /', async () => {
|
||||
const page = await requirePage('/', {dir: __dirname, dist: '_resolvedata'})
|
||||
const page = await requirePage('/', {distDir})
|
||||
expect(page.test).toBe('hello')
|
||||
})
|
||||
|
||||
it('Should require /index.js when using /index', async () => {
|
||||
const page = await requirePage('/index', {dir: __dirname, dist: '_resolvedata'})
|
||||
const page = await requirePage('/index', {distDir})
|
||||
expect(page.test).toBe('hello')
|
||||
})
|
||||
|
||||
it('Should require /world.js when using /world', async () => {
|
||||
const page = await requirePage('/world', {dir: __dirname, dist: '_resolvedata'})
|
||||
const page = await requirePage('/world', {distDir})
|
||||
expect(page.test).toBe('world')
|
||||
})
|
||||
|
||||
it('Should throw when using /../../test.js', async () => {
|
||||
try {
|
||||
await requirePage('/../../test', {dir: __dirname, dist: '_resolvedata'})
|
||||
await requirePage('/../../test', {distDir})
|
||||
} catch (err) {
|
||||
expect(err.code).toBe('ENOENT')
|
||||
}
|
||||
|
@ -81,7 +82,7 @@ describe('requirePage', () => {
|
|||
|
||||
it('Should throw when using non existent pages like /non-existent.js', async () => {
|
||||
try {
|
||||
await requirePage('/non-existent', {dir: __dirname, dist: '_resolvedata'})
|
||||
await requirePage('/non-existent', {distDir})
|
||||
} catch (err) {
|
||||
expect(err.code).toBe('ENOENT')
|
||||
}
|
||||
|
@ -89,7 +90,7 @@ describe('requirePage', () => {
|
|||
|
||||
it('Should bubble up errors in the child component', async () => {
|
||||
try {
|
||||
await requirePage('/non-existent-child', {dir: __dirname, dist: '_resolvedata'})
|
||||
await requirePage('/non-existent-child', {distDir})
|
||||
} catch (err) {
|
||||
expect(err.code).toBe('MODULE_NOT_FOUND')
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue