1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00

Allow use of filenames in exportPathMap (#2973)

* allow use of filenames in exportPathMap

* add link test and handling for file paths when flattening links for export

* add note about exporting file paths to readme.md
This commit is contained in:
Jesse Ditson 2017-10-05 11:33:10 -07:00 committed by Tim Neutkens
parent 594b214a23
commit a79357f2a4
6 changed files with 42 additions and 5 deletions

View file

@ -101,7 +101,12 @@ export function _rewriteUrlForNextExport (url) {
let [path, qs] = url.split('?') let [path, qs] = url.split('?')
path = path.replace(/\/$/, '') path = path.replace(/\/$/, '')
let newPath = `${path}/` let newPath = path
// Append a trailing slash if this path does not have an extension
if (!/\.[^/]+\/?$/.test(path)) {
newPath = `${path}/`
}
if (qs) { if (qs) {
newPath = `${newPath}?${qs}` newPath = `${newPath}?${qs}`
} }

View file

@ -1064,6 +1064,7 @@ module.exports = {
return { return {
'/': { page: '/' }, '/': { page: '/' },
'/about': { page: '/about' }, '/about': { page: '/about' },
'/readme.md': { page: '/readme' },
'/p/hello-nextjs': { page: '/post', query: { title: 'hello-nextjs' } }, '/p/hello-nextjs': { page: '/post', query: { title: 'hello-nextjs' } },
'/p/learn-nextjs': { page: '/post', query: { title: 'learn-nextjs' } }, '/p/learn-nextjs': { page: '/post', query: { title: 'learn-nextjs' } },
'/p/deploy-nextjs': { page: '/post', query: { title: 'deploy-nextjs' } } '/p/deploy-nextjs': { page: '/post', query: { title: 'deploy-nextjs' } }
@ -1072,6 +1073,8 @@ module.exports = {
} }
``` ```
> Note that if the path ends with a directory, it will be exported as `/dir-name/index.html`, but if it ends with an extension, it will be exported as the specified filename, e.g. `/readme.md` above. If you use a file extension other than `.html`, you may need to set the `Content-Type` header to `text/html` when serving this content.
In that, you specify what are the pages you need to export as static HTML. In that, you specify what are the pages you need to export as static HTML.
Then simply run these commands: Then simply run these commands:

View file

@ -2,7 +2,7 @@ import del from 'del'
import cp from 'recursive-copy' import cp from 'recursive-copy'
import mkdirp from 'mkdirp-then' import mkdirp from 'mkdirp-then'
import walk from 'walk' import walk from 'walk'
import { resolve, join, dirname, sep } from 'path' import { extname, resolve, join, dirname, sep } from 'path'
import { existsSync, readFileSync, writeFileSync } from 'fs' import { existsSync, readFileSync, writeFileSync } from 'fs'
import getConfig from './config' import getConfig from './config'
import { renderToHTML } from './render' import { renderToHTML } from './render'
@ -96,7 +96,14 @@ export default async function (dir, options, configuration) {
const req = { url: path } const req = { url: path }
const res = {} const res = {}
const htmlFilename = path === '/' ? 'index.html' : `${path}${sep}index.html` let htmlFilename = `${path}${sep}index.html`
if (extname(path) !== '') {
// If the path has an extension, use that as the filename instead
htmlFilename = path
} else if (path === '/') {
// If the path is the root, just use index.html
htmlFilename = 'index.html'
}
const baseDir = join(outDir, dirname(htmlFilename)) const baseDir = join(outDir, dirname(htmlFilename))
const htmlFilepath = join(outDir, htmlFilename) const htmlFilepath = join(outDir, htmlFilename)

View file

@ -9,7 +9,8 @@ module.exports = {
'/dynamic-imports': { page: '/dynamic-imports' }, '/dynamic-imports': { page: '/dynamic-imports' },
'/dynamic': { page: '/dynamic', query: { text: 'cool dynamic text' } }, '/dynamic': { page: '/dynamic', query: { text: 'cool dynamic text' } },
'/dynamic/one': { page: '/dynamic', query: { text: 'next export is nice' } }, '/dynamic/one': { page: '/dynamic', query: { text: 'next export is nice' } },
'/dynamic/two': { page: '/dynamic', query: { text: 'zeit is awesome' } } '/dynamic/two': { page: '/dynamic', query: { text: 'zeit is awesome' } },
'/file-name.md': { page: '/dynamic', query: { text: 'this file has an extension' } }
} }
} }
} }

View file

@ -44,6 +44,12 @@ export default () => (
> >
<a id='with-hash'>With Hash</a> <a id='with-hash'>With Hash</a>
</Link> </Link>
<Link
href='/dynamic?text=this+file+has+an+extension'
as='/file-name.md'
>
<a id='path-with-extension'>Path with extension</a>
</Link>
<Link href='/level1'> <Link href='/level1'>
<a id='level1-home-page'>Level1 home page</a> <a id='level1-home-page'>Level1 home page</a>
</Link> </Link>

View file

@ -1,5 +1,6 @@
/* global describe, it, expect */ /* global describe, it, expect */
import { renderViaHTTP } from 'next-test-utils' import { renderViaHTTP } from 'next-test-utils'
import cheerio from 'cheerio'
export default function (context) { export default function (context) {
describe('Render via SSR', () => { describe('Render via SSR', () => {
@ -8,6 +9,15 @@ export default function (context) {
expect(html).toMatch(/This is the home page/) expect(html).toMatch(/This is the home page/)
}) })
it('should render links correctly', async () => {
const html = await renderViaHTTP(context.port, '/')
const $ = cheerio.load(html)
const dynamicLink = $('#dynamic-1').prop('href')
const filePathLink = $('#path-with-extension').prop('href')
expect(dynamicLink).toEqual('/dynamic/one/')
expect(filePathLink).toEqual('/file-name.md')
})
it('should render a page with getInitialProps', async() => { it('should render a page with getInitialProps', async() => {
const html = await renderViaHTTP(context.port, '/dynamic') const html = await renderViaHTTP(context.port, '/dynamic')
expect(html).toMatch(/cool dynamic text/) expect(html).toMatch(/cool dynamic text/)
@ -20,7 +30,12 @@ export default function (context) {
it('should render pages with dynamic imports', async() => { it('should render pages with dynamic imports', async() => {
const html = await renderViaHTTP(context.port, '/dynamic-imports') const html = await renderViaHTTP(context.port, '/dynamic-imports')
expect(html).toMatch(/Welcome to dynamic imports./) expect(html).toMatch(/Welcome to dynamic imports/)
})
it('should render paths with extensions', async() => {
const html = await renderViaHTTP(context.port, '/file-name.md')
expect(html).toMatch(/this file has an extension/)
}) })
it('should give empty object for query if there is no query', async() => { it('should give empty object for query if there is no query', async() => {