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

Add configuration to specify the name of the pages directory. #936

Closed
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
11 changes: 7 additions & 4 deletions bin/next-build
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { resolve, join } from 'path'
import { existsSync } from 'fs'
import parseArgs from 'minimist'
import getConfig from '../server/config'
import build from '../server/build'
import { printAndExit } from '../lib/utils'

Expand Down Expand Up @@ -29,18 +30,20 @@ if (argv.help) {
}

const dir = resolve(argv._[0] || '.')
const config = getConfig(dir)
const pagesDirectory = config.pagesDirectory

// Check if pages dir exists and warn if not
if (!existsSync(dir)) {
printAndExit(`> No such directory exists as the project root: ${dir}`)
}

if (!existsSync(join(dir, 'pages'))) {
if (existsSync(join(dir, '..', 'pages'))) {
printAndExit('> No `pages` directory found. Did you mean to run `next` in the parent (`../`) directory?')
if (!existsSync(join(dir, pagesDirectory))) {
if (existsSync(join(dir, '..', pagesDirectory))) {
printAndExit(`> No \`${pagesDirectory}\` directory found. Did you mean to run \`next\` in the parent (\`../\`) directory?`)
}

printAndExit('> Couldn\'t find a `pages` directory. Please create one under the project root')
printAndExit(`> Couldn't find a \`${pagesDirectory}\` directory. Please create one under the project root`)
}

build(dir)
Expand Down
11 changes: 7 additions & 4 deletions bin/next-dev
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { resolve, join } from 'path'
import parseArgs from 'minimist'
import { existsSync, readFileSync } from 'fs'
import Server from '../server'
import getConfig from '../server/config'
import { printAndExit } from '../lib/utils'
import pkgUp from 'pkg-up'

Expand Down Expand Up @@ -40,18 +41,20 @@ if (argv.help) {
}

const dir = resolve(argv._[0] || '.')
const config = getConfig(dir)
const pagesDirectory = config.pagesDirectory

// Check if pages dir exists and warn if not
if (!existsSync(dir)) {
printAndExit(`> No such directory exists as the project root: ${dir}`)
}

if (!existsSync(join(dir, 'pages'))) {
if (existsSync(join(dir, '..', 'pages'))) {
printAndExit('> No `pages` directory found. Did you mean to run `next` in the parent (`../`) directory?')
if (!existsSync(join(dir, pagesDirectory))) {
if (existsSync(join(dir, '..', pagesDirectory))) {
printAndExit(`> No \`${pagesDirectory}\` directory found. Did you mean to run \`next\` in the parent (\`../\`) directory?`)
}

printAndExit('> Couldn\'t find a `pages` directory. Please create one under the project root')
printAndExit(`> Couldn't find a \`${pagesDirectory}\` directory. Please create one under the project root`)
}

const srv = new Server({ dir, dev: true })
Expand Down
13 changes: 8 additions & 5 deletions bin/next-init
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { resolve, join, basename } from 'path'
import parseArgs from 'minimist'
import { exists, writeFile, mkdir } from 'mz/fs'
import mkdirp from 'mkdirp-then'
import getConfig from '../server/config'

const argv = parseArgs(process.argv.slice(2), {
alias: {
Expand All @@ -29,9 +30,11 @@ if (argv.help) {
}

const dir = resolve(argv._[0] || '.')
const config = getConfig(dir)
const pagesDirectory = config.pagesDirectory

if (basename(dir) === 'pages') {
console.warn('Your root directory is named "pages". This looks suspicious. You probably want to go one directory up.')
if (basename(dir) === pagesDirectory) {
console.warn(`Your root directory is named "${pagesDirectory}". This looks suspicious. You probably want to go one directory up.`)
process.exit(1)
}

Expand All @@ -49,9 +52,9 @@ exists(dir)
await mkdir(join(dir, 'static'))
}

if (!await exists(join(dir, 'pages'))) {
await mkdir(join(dir, 'pages'))
await writeFile(join(dir, 'pages', 'index.js'), basePage)
if (!await exists(join(dir, pagesDirectory))) {
await mkdir(join(dir, pagesDirectory))
await writeFile(join(dir, pagesDirectory, 'index.js'), basePage)
}
})
.catch((err) => {
Expand Down
4 changes: 2 additions & 2 deletions lib/router/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,8 @@ export default class Router extends EventEmitter {
}

doFetchRoute (route) {
const { buildId } = window.__NEXT_DATA__
const url = `/_next/${encodeURIComponent(buildId)}/pages${route}`
const { buildId, pagesDirectory } = window.__NEXT_DATA__
const url = `/_next/${encodeURIComponent(buildId)}/${pagesDirectory}${route}`

return fetch(url, {
method: 'GET',
Expand Down
5 changes: 4 additions & 1 deletion server/build/loaders/hot-self-accept-loader.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { resolve, relative } from 'path'
import getConfig from '../../config'

module.exports = function (content, sourceMap) {
this.cacheable()
Expand Down Expand Up @@ -34,7 +35,9 @@ module.exports = function (content, sourceMap) {
const nextPagesDir = resolve(__dirname, '..', '..', '..', 'pages')

function getRoute (loaderContext) {
const pagesDir = resolve(loaderContext.options.context, 'pages')
const config = getConfig(loaderContext.options.context)
const pagesDirectory = config.pagesDirectory
const pagesDir = resolve(loaderContext.options.context, pagesDirectory)
const { resourcePath } = loaderContext
const dir = [pagesDir, nextPagesDir]
.find((d) => resourcePath.indexOf(d) === 0)
Expand Down
11 changes: 10 additions & 1 deletion server/build/plugins/json-pages-plugin.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import getConfig from '../../config'

export default class JsonPagesPlugin {
constructor (dir) {
this.config = getConfig(dir)
}

apply (compiler) {
compiler.plugin('after-compile', (compilation, callback) => {
const regex = new RegExp(`^bundles/${this.config.pagesDirectory}.*.js$`)
const pages = Object
.keys(compilation.assets)
.filter((filename) => /^bundles[/\\]pages.*\.js$/.test(filename))
.filter((filename) => {
return filename.match(regex)
})

pages.forEach((pageName) => {
const page = compilation.assets[pageName]
Expand Down
9 changes: 5 additions & 4 deletions server/build/plugins/watch-pages-plugin.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { resolve, join } from 'path'
import { join } from 'path'
import getConfig from '../../config'

export default class WatchPagesPlugin {
constructor (dir) {
this.dir = resolve(dir, 'pages')
this.config = getConfig(dir)
}

apply (compiler) {
compiler.plugin('compilation', (compilation) => {
compilation.plugin('optimize-assets', (assets, callback) => {
// transpile pages/_document.js and descendants,
// but don't need the bundle file
delete assets[join('bundles', 'pages', '_document.js')]
delete assets[join('bundles', this.config.pagesDirectory, '_document.js')]
callback()
})
})
Expand All @@ -19,7 +20,7 @@ export default class WatchPagesPlugin {
// watch the pages directory
compilation.contextDependencies = [
...compilation.contextDependencies,
this.dir
this.config.pagesDirectory
]
callback()
})
Expand Down
16 changes: 8 additions & 8 deletions server/build/webpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ const defaultPages = [
]
const nextPagesDir = join(__dirname, '..', '..', 'pages')
const nextNodeModulesDir = join(__dirname, '..', '..', '..', 'node_modules')
const interpolateNames = new Map(defaultPages.map((p) => {
return [join(nextPagesDir, p), `dist/pages/${p}`]
}))

const relativeResolve = rootModuleRelativePath(require)

Expand All @@ -34,6 +31,9 @@ export default async function createCompiler (dir, { dev = false, quiet = false,
] : []
const mainJS = dev
? require.resolve('../../client/next-dev') : require.resolve('../../client/next')
const interpolateNames = new Map(defaultPages.map((p) => {
return [join(nextPagesDir, p), `dist/${config.pagesDirectory}/${p}`]
}))

let minChunks

Expand All @@ -45,8 +45,8 @@ export default async function createCompiler (dir, { dev = false, quiet = false,
]
}

const pages = await glob('pages/**/*.js', { cwd: dir })
const devPages = pages.filter((p) => p === 'pages/_document.js' || p === 'pages/_error.js')
const pages = await glob(`${config.pagesDirectory}/**/*.js`, { cwd: dir })
const devPages = pages.filter((p) => p === `${config.pagesDirectory}/_document.js` || p === `${config.pagesDirectory}/_error.js`)

// In the dev environment, on-demand-entry-handler will take care of
// managing pages.
Expand All @@ -61,7 +61,7 @@ export default async function createCompiler (dir, { dev = false, quiet = false,
}

for (const p of defaultPages) {
const entryName = join('bundles', 'pages', p)
const entryName = join('bundles', config.pagesDirectory, p)
if (!entries[entryName]) {
entries[entryName] = [...defaultEntries, join(nextPagesDir, p) + '?entry']
}
Expand Down Expand Up @@ -104,7 +104,7 @@ export default async function createCompiler (dir, { dev = false, quiet = false,
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(dev ? 'development' : 'production')
}),
new JsonPagesPlugin(),
new JsonPagesPlugin(dir),
new CaseSensitivePathPlugin()
]

Expand Down Expand Up @@ -158,7 +158,7 @@ export default async function createCompiler (dir, { dev = false, quiet = false,
test: /\.js(\?[^?]*)?$/,
loader: 'hot-self-accept-loader',
include: [
join(dir, 'pages'),
join(dir, config.pagesDirectory),
nextPagesDir
]
}, {
Expand Down
3 changes: 2 additions & 1 deletion server/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ const cache = new Map()

const defaultConfig = {
webpack: null,
poweredByHeader: true
poweredByHeader: true,
pagesDirectory: 'pages'
}

export default function getConfig (dir) {
Expand Down
2 changes: 1 addition & 1 deletion server/hot-reloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export default class HotReloader {
// and to update error content
const failed = failedChunkNames

const rootDir = join('bundles', 'pages')
const rootDir = join('bundles', this.config.pagesDirectory)

for (const n of new Set([...added, ...removed, ...failed, ...succeeded])) {
const route = toRoute(relative(rootDir, n))
Expand Down
4 changes: 2 additions & 2 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export default class Server {
await this.serveStatic(req, res, p)
},

'/_next/:buildId/pages/:path*': async (req, res, params) => {
[`/_next/:buildId/${this.config.pagesDirectory}/:path*`]: async (req, res, params) => {
if (!this.handleBuildId(params.buildId, res)) {
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify({ buildIdMismatch: true }))
Expand Down Expand Up @@ -300,7 +300,7 @@ export default class Server {
const errors = this.hotReloader.getCompilationErrors()
if (!errors.size) return

const id = join(this.dir, '.next', 'bundles', 'pages', page)
const id = join(this.dir, '.next', 'bundles', this.config.pagesDirectory, page)
const p = resolveFromList(id, errors.keys())
if (p) return errors.get(p)[0]
}
Expand Down
4 changes: 3 additions & 1 deletion server/on-demand-entry-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { EventEmitter } from 'events'
import { join } from 'path'
import { parse } from 'url'
import resolvePath from './resolve'
import getConfig from './config'
import touch from 'touch'

const ADDED = Symbol('added')
Expand All @@ -18,6 +19,7 @@ export default function onDemandEntryHandler (devMiddleware, compiler, {
const lastAccessPages = ['']
const doneCallbacks = new EventEmitter()
const invalidator = new Invalidator(devMiddleware)
const config = getConfig(dir)
let touchedAPage = false

compiler.plugin('make', function (compilation, done) {
Expand Down Expand Up @@ -67,7 +69,7 @@ export default function onDemandEntryHandler (devMiddleware, compiler, {
async ensurePage (page) {
page = normalizePage(page)

const pagePath = join(dir, 'pages', page)
const pagePath = join(dir, config.pagesDirectory, page)
const pathname = await resolvePath(pagePath)
const name = join('bundles', pathname.substring(dir.length))

Expand Down
21 changes: 15 additions & 6 deletions server/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { join } from 'path'
import { createElement } from 'react'
import { renderToString, renderToStaticMarkup } from 'react-dom/server'
import send from 'send'
import getConfig from './config'
import requireModule from './require'
import resolvePath from './resolve'
import readPage from './read-page'
Expand Down Expand Up @@ -38,13 +39,16 @@ async function doRender (req, res, pathname, query, {
dev = false,
staticMarkup = false
} = {}) {
const config = getConfig(dir)
const pagesDirectory = config.pagesDirectory

page = page || pathname

await ensurePage(page, { dir, hotReloader })

let [Component, Document] = await Promise.all([
requireModule(join(dir, '.next', 'dist', 'pages', page)),
requireModule(join(dir, '.next', 'dist', 'pages', '_document'))
requireModule(join(dir, '.next', 'dist', pagesDirectory, page)),
requireModule(join(dir, '.next', 'dist', pagesDirectory, '_document'))
])
Component = Component.default || Component
Document = Document.default || Document
Expand All @@ -56,8 +60,8 @@ async function doRender (req, res, pathname, query, {
errorComponent
] = await Promise.all([
loadGetInitialProps(Component, ctx),
readPage(join(dir, '.next', 'bundles', 'pages', page)),
readPage(join(dir, '.next', 'bundles', 'pages', '_error'))
readPage(join(dir, '.next', 'bundles', pagesDirectory, page)),
readPage(join(dir, '.next', 'bundles', pagesDirectory, '_error'))
])

// the response might be finshed on the getinitialprops call
Expand Down Expand Up @@ -96,6 +100,7 @@ async function doRender (req, res, pathname, query, {
query,
buildId,
buildStats,
pagesDirectory,
err: (err && dev) ? errorToJSON(err) : null
},
dev,
Expand All @@ -108,12 +113,16 @@ async function doRender (req, res, pathname, query, {

export async function renderJSON (req, res, page, { dir = process.cwd(), hotReloader } = {}) {
await ensurePage(page, { dir, hotReloader })
const pagePath = await resolvePath(join(dir, '.next', 'bundles', 'pages', page))
const config = getConfig(dir)
const pagesDirectory = config.pagesDirectory
const pagePath = await resolvePath(join(dir, '.next', 'bundles', pagesDirectory, page))
return serveStatic(req, res, pagePath)
}

export async function renderErrorJSON (err, req, res, { dir = process.cwd(), dev = false } = {}) {
const component = await readPage(join(dir, '.next', 'bundles', 'pages', '_error'))
const config = getConfig(dir)
const pagesDirectory = config.pagesDirectory
const component = await readPage(join(dir, '.next', 'bundles', pagesDirectory, '_error'))

sendJSON(res, {
component,
Expand Down
9 changes: 9 additions & 0 deletions test/integration/custom-page-directory/foo/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react'

export default class FooHomePage extends React.Component {
render () {
return <div>
<h1>Just a page in /foo</h1>
</div>
}
}
3 changes: 3 additions & 0 deletions test/integration/custom-page-directory/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
pagesDirectory: 'foo'
}
Loading