提交 211c84e1 编写于 作者: H htbvo 提交者: Tim Neutkens

allow NextScript to optionally defer javascript (#8980)

* allow NextScript to optionally defer javascript

* move defer options to experimental feature

* combine defer flags into a single option

* Update deferScripts to work with serverless target

* Add test for defer and async property

* Read the async property

* Check versions of chrome and chromedriver

* Update to chromedriver 76

* Fix test
上级 94e81c02
......@@ -36,6 +36,11 @@ commands:
- run:
name: Installing Dependencies
command: yarn install --frozen-lockfile --check-files
- run:
name: Install correct Chrome Driver version
command: yarn add chromedriver@76 -W
- run: google-chrome --version
- run: chromedriver --version
yarn_lint:
steps:
- run:
......
......@@ -724,6 +724,9 @@ export default async function getBaseWebpackConfig(
'process.env.__NEXT_EXPORT_TRAILING_SLASH': JSON.stringify(
config.exportTrailingSlash
),
'process.env.__NEXT_DEFER_SCRIPTS': JSON.stringify(
config.experimental.deferScripts
),
'process.env.__NEXT_MODERN_BUILD': JSON.stringify(
config.experimental.modern && !dev
),
......
......@@ -47,6 +47,7 @@ const defaultConfig: { [key: string]: any } = {
profiling: false,
publicDirectory: false,
sprFlushToDisk: true,
deferScripts: false,
},
future: {
excludeDefaultMomentLocales: false,
......
......@@ -521,7 +521,8 @@ export class NextScript extends Component<OriginProps> {
return (
<script
async
defer={process.env.__NEXT_DEFER_SCRIPTS as any}
async={!process.env.__NEXT_DEFER_SCRIPTS as any}
key={bundle.file}
src={`${assetPrefix}/_next/${encodeURI(
bundle.file
......@@ -561,7 +562,8 @@ export class NextScript extends Component<OriginProps> {
file
)}${_devOnlyInvalidateCacheQueryString}`}
nonce={this.props.nonce}
async
defer={process.env.__NEXT_DEFER_SCRIPTS as any}
async={!process.env.__NEXT_DEFER_SCRIPTS as any}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
{...modernProps}
/>
......@@ -594,6 +596,7 @@ export class NextScript extends Component<OriginProps> {
devFiles,
__NEXT_DATA__,
} = this.context._documentProps
const deferScripts: any = process.env.__NEXT_DEFER_SCRIPTS
const { _devOnlyInvalidateCacheQueryString } = this.context
if (inAmpMode) {
......@@ -648,7 +651,8 @@ export class NextScript extends Component<OriginProps> {
const pageScript = [
<script
async
defer={deferScripts}
async={!deferScripts}
data-next-page={page}
key={page}
src={
......@@ -662,7 +666,8 @@ export class NextScript extends Component<OriginProps> {
/>,
process.env.__NEXT_MODERN_BUILD && (
<script
async
defer={deferScripts}
async={!deferScripts}
data-next-page={page}
key={`${page}-modern`}
src={
......@@ -681,7 +686,8 @@ export class NextScript extends Component<OriginProps> {
const appScript = [
<script
async
defer={deferScripts}
async={!deferScripts}
data-next-page="/_app"
src={
assetPrefix +
......@@ -695,7 +701,8 @@ export class NextScript extends Component<OriginProps> {
/>,
process.env.__NEXT_MODERN_BUILD && (
<script
async
defer={deferScripts}
async={!deferScripts}
data-next-page="/_app"
src={
assetPrefix +
......
module.exports = {
onDemandEntries: {
// Make sure entries are not getting disposed.
maxInactiveAge: 1000 * 60 * 60
},
experimental: {
deferScripts: true
}
}
export default () => <h1>Hello World</h1>
/* eslint-env jest */
/* global jasmine */
import { join } from 'path'
import {
nextServer,
runNextCommand,
startApp,
stopApp,
renderViaHTTP
} from 'next-test-utils'
import cheerio from 'cheerio'
const appDir = join(__dirname, '../')
let appPort
let server
let app
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5
const context = {}
describe('Defer Scripts', () => {
beforeAll(async () => {
await runNextCommand(['build', appDir])
app = nextServer({
dir: join(__dirname, '../'),
dev: false,
quiet: true
})
server = await startApp(app)
context.appPort = appPort = server.address().port
})
afterAll(() => stopApp(server))
it('should have defer on all script tags', async () => {
const html = await renderViaHTTP(appPort, '/')
const $ = cheerio.load(html)
let missing = false
for (const script of $('script').toArray()) {
const { defer, type } = script.attribs
// application/json doesn't need defer
if (type === 'application/json') {
continue
}
if (defer !== '') {
missing = true
}
}
expect(missing).toBe(false)
})
})
......@@ -663,6 +663,24 @@ describe('Production Usage', () => {
}
})
it('should have async on all script tags', async () => {
const html = await renderViaHTTP(appPort, '/')
const $ = cheerio.load(html)
let missing = false
for (const script of $('script').toArray()) {
// application/json doesn't need defer
if (script.attribs.type === 'application/json') {
continue
}
if (script.attribs.async !== '') {
missing = true
}
}
expect(missing).toBe(false)
})
dynamicImportTests(context, (p, q) => renderViaHTTP(context.appPort, p, q))
processEnv(context)
......
......@@ -4174,10 +4174,10 @@ chrome-trace-event@^1.0.2:
dependencies:
tslib "^1.9.0"
chromedriver@75.1.0:
version "75.1.0"
resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-75.1.0.tgz#edfef5d7a9b16b6f8a12ddb58cbac76ae52732fd"
integrity sha512-N2P0fg6FS4c+tTG0R7cCOD5qiVo+E6uAz6xVjmbZesYv1xs1iGdcCUo0IqOY+ppD/4OOObG+XWV1CFWXT6UIgA==
chromedriver@76.0.1:
version "76.0.1"
resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-76.0.1.tgz#65283299c3b34b1212eef272c32bd826c6bdebd3"
integrity sha512-+8BCemJLKPF2w/UpzA1uNgLWQrg1IgIO4ZYcsAjYYgqD8zUcvQ+RfwA/0TR1Zwv9Mkd8fdzTe21eZ2FyZ83DAg==
dependencies:
del "^4.1.1"
extract-zip "^1.6.7"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册