1
0
Fork 0
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:
Tim Neutkens 2018-06-04 15:45:39 +02:00 committed by GitHub
parent 18676e0870
commit a7bb9175eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 70 additions and 68 deletions

View file

@ -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'
]

View file

@ -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')
}

View file

@ -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) => {

View file

@ -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()
}

View file

@ -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) {

View file

@ -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)
}

View file

@ -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 = {}

View file

@ -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()
})
})
})

View file

@ -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')
}