提交 18af71c0 编写于 作者: J JJ Kasper 提交者: Joe Haddad

Add support for amp to export (#6725)

* Add support for amp to export

* Anchor canonical replace

* Disable profiling test for now

* Centralize amp utils to next-server/server/utils

* re-enable profiling test
上级 e906e4bd
......@@ -115,6 +115,7 @@ type RenderOpts = {
err?: Error | null
nextExport?: boolean
dev?: boolean
ampPath?: string
amphtml?: boolean
hasAmp?: boolean
buildManifest: BuildManifest
......@@ -140,6 +141,7 @@ function renderDocument(
dynamicImportsIds,
err,
dev,
ampPath,
amphtml,
hasAmp,
staticMarkup,
......@@ -151,6 +153,7 @@ function renderDocument(
docProps: any
pathname: string
query: ParsedUrlQuery
ampPath: string,
amphtml: boolean
hasAmp: boolean,
dynamicImportsIds: string[]
......@@ -177,6 +180,7 @@ function renderDocument(
err: err ? serializeError(dev, err) : undefined, // Error if one happened, otherwise don't sent in the resulting HTML
}}
ampEnabled={ampEnabled}
ampPath={ampPath}
amphtml={amphtml}
hasAmp={hasAmp}
staticMarkup={staticMarkup}
......@@ -205,6 +209,7 @@ export async function renderToHTML(
staticMarkup = false,
amphtml = false,
hasAmp = false,
ampPath = '',
App,
Document,
Component,
......@@ -314,6 +319,7 @@ export async function renderToHTML(
props,
docProps,
pathname,
ampPath,
amphtml,
hasAmp,
query,
......
import {join} from 'path'
import { isAmpFile } from './utils'
import {PAGES_MANIFEST, SERVER_DIRECTORY} from 'next-server/constants'
import { normalizePagePath } from './normalize-page-path'
......@@ -53,13 +54,12 @@ export function getPagePath(page: string, distDir: string, opts: PagePathOptions
export function requirePage(page: string, distDir: string, opts: PagePathOptions = {}): any {
const pagePath = getPagePath(page, distDir, opts)
const isAmp = pagePath.indexOf('.amp.') > -1
const isAmp = isAmpFile(pagePath)
let hasAmp = false
if (!isAmp) {
try {
const ampPage = getPagePath(page, distDir, { amphtml: true })
hasAmp = Boolean(ampPage && ampPage.indexOf('.amp') > -1)
hasAmp = isAmpFile(getPagePath(page, distDir, { amphtml: true }))
} catch (_) {}
}
opts.amphtml = opts.amphtml || isAmp
......
......@@ -18,3 +18,21 @@ export function isInternalUrl(url: string): boolean {
export function isBlockedPage(pathname: string): boolean {
return (BLOCKED_PAGES.indexOf(pathname) !== -1)
}
export function cleanAmpPath(pathname: string): string {
return (pathname || '')
.replace(/\.amp$/, '')
.replace(/\index$/, '')
}
export function isAmpPath(pathname: string): boolean {
return (pathname || '').endsWith('.amp')
}
export function isAmpFile(pathname: string): boolean {
if (isAmpPath(pathname)) return true
pathname = pathname || ''
const parts = pathname.split('.')
parts.pop() // remove extension
return isAmpPath(parts.join('.'))
}
......@@ -5,6 +5,7 @@ import mkdirpModule from 'mkdirp'
import { resolve, join } from 'path'
import { existsSync, readFileSync } from 'fs'
import loadConfig from 'next-server/next-config'
import { tryAmp } from 'next-server/dist/server/require'
import { PHASE_EXPORT, SERVER_DIRECTORY, PAGES_MANIFEST, CONFIG_FILE, BUILD_ID_FILE, CLIENT_STATIC_FILES_PATH } from 'next-server/constants'
import createProgress from 'tty-aware-progress'
import { promisify } from 'util'
......@@ -52,6 +53,22 @@ export default async function (dir, options, configuration) {
defaultPathMap[page] = { page }
}
Object.keys(defaultPathMap).forEach(path => {
const isAmp = path.indexOf('.amp') > -1
if (isAmp) {
defaultPathMap[path].query = { amp: 1 }
if (!defaultPathMap[path.split('.amp')[0]]) {
defaultPathMap[path].query.ampOnly = true
}
} else {
const ampPath = tryAmp(defaultPathMap, path)
if (ampPath !== path) {
defaultPathMap[path].query = { hasAmp: true, ampPath }
}
}
})
// Initialize the output directory
const outDir = options.outdir
await recursiveDelete(join(outDir))
......@@ -93,7 +110,8 @@ export default async function (dir, options, configuration) {
distDir,
dev: false,
staticMarkup: false,
hotReloader: null
hotReloader: null,
ampEnabled: nextConfig.experimental.amp
}
const { serverRuntimeConfig, publicRuntimeConfig } = nextConfig
......
import mkdirpModule from 'mkdirp'
import { promisify } from 'util'
import { cleanAmpPath } from 'next/dist/server/lib/utils'
import { extname, join, dirname, sep } from 'path'
import { renderToHTML } from 'next-server/dist/server/render'
import { writeFile } from 'fs'
......@@ -30,6 +31,10 @@ process.on(
const work = async path => {
await sema.acquire()
const { page, query = {} } = exportPathMap[path]
const ampOpts = { amphtml: Boolean(query.amp), hasAmp: query.hasAmp, ampPath: query.ampPath }
delete query.hasAmp
delete query.ampPath
const req = { url: path }
const res = {}
envConfig.setConfig({
......@@ -37,6 +42,11 @@ process.on(
publicRuntimeConfig: renderOpts.runtimeConfig
})
if (query.ampOnly) {
delete query.ampOnly
path = cleanAmpPath(path)
}
let htmlFilename = `${path}${sep}index.html`
const pageExt = extname(page)
const pathExt = extname(path)
......@@ -53,7 +63,7 @@ process.on(
await mkdirp(baseDir)
const components = await loadComponents(distDir, buildId, page)
const html = await renderToHTML(req, res, page, query, { ...components, ...renderOpts })
const html = await renderToHTML(req, res, page, query, { ...components, ...renderOpts, ...ampOpts })
await new Promise((resolve, reject) =>
writeFile(
htmlFilepath,
......
/* eslint-disable */
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { cleanAmpPath } from 'next-server/dist/server/utils'
import { htmlEscapeJsonString } from '../server/htmlescape'
import flush from 'styled-jsx/server'
import {
......@@ -151,6 +152,7 @@ export class Head extends Component {
styles,
amphtml,
hasAmp,
ampPath,
assetPrefix,
__NEXT_DATA__,
} = this.context._documentProps
......@@ -202,7 +204,7 @@ export class Head extends Component {
name="viewport"
content="width=device-width,minimum-scale=1,initial-scale=1"
/>
<link rel="canonical" href={page.split('.amp')[0]} />
<link rel="canonical" href={cleanAmpPath(page)} />
{/* https://www.ampproject.org/docs/fundamentals/optimize_amp#optimize-the-amp-runtime-loading */}
<link
rel="preload"
......@@ -241,7 +243,7 @@ export class Head extends Component {
)}
{!amphtml && (
<>
{ampEnabled && hasAmp && <link rel="amphtml" href={`${page}?amp=1`} />}
{ampEnabled && hasAmp && <link rel="amphtml" href={ampPath ? ampPath : `${page}?amp=1`} />}
{page !== '/_error' && (
<link
rel="preload"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册