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:
parent
594b214a23
commit
a79357f2a4
|
@ -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}`
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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' } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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() => {
|
||||||
|
|
Loading…
Reference in a new issue