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

Polyfill window.fetch by Default #9168

Merged
merged 41 commits into from
Nov 2, 2019
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
f7b7625
Polyfilling fetch and object-assign
janicklas-ralph Oct 17, 2019
b284603
Polyfilling corejs object-assign
janicklas-ralph Oct 18, 2019
b1b2868
Adding object-assign in polyfills.js. IE11 does not support Object.as…
janicklas-ralph Oct 18, 2019
7ca78a2
Fixing failing test
janicklas-ralph Oct 18, 2019
f78f772
Updating object.assign polyfill to fix aliasing
janicklas-ralph Oct 18, 2019
db9f5d4
Merge branch 'canary' of github.com:zeit/next.js into polyfill-fetch
janicklas-ralph Oct 22, 2019
f95ecab
Merge branch 'canary' of github.com:zeit/next.js into polyfill-fetch
janicklas-ralph Oct 25, 2019
3662480
Merge branch 'canary' into polyfill-fetch
timneutkens Oct 25, 2019
6c53959
Updating test case value to match new build stats
janicklas-ralph Oct 28, 2019
1ab61d6
Merge branch 'polyfill-fetch' of github.com:janicklas-ralph/next.js i…
janicklas-ralph Oct 28, 2019
7ca58b6
Increasing the size of default build to 225kb
janicklas-ralph Oct 28, 2019
8e0815d
Resolving upstream conflicts
janicklas-ralph Oct 29, 2019
d9a6414
Fixing defer-script test case to not include polyfill.js
janicklas-ralph Oct 29, 2019
c1e6544
Merge branch 'canary' into polyfill-fetch
Timer Oct 30, 2019
c04d2dd
Revert README.md
Timer Oct 30, 2019
df1a5f4
Merge branch 'canary' of github.com:zeit/next.js into polyfill-fetch
janicklas-ralph Oct 30, 2019
61cbb31
Re-design the polyfill approach based on PR feedback
janicklas-ralph Nov 1, 2019
562126a
Merge branch 'polyfill-fetch' of github.com:janicklas-ralph/next.js i…
janicklas-ralph Nov 1, 2019
26a7586
Rename polyfill chunk
janicklas-ralph Nov 1, 2019
8b73f09
Adding comment and fixing test case
janicklas-ralph Nov 1, 2019
d25f8d4
Rename polyfills chunk
Timer Nov 1, 2019
425ba25
Extract aliases into helper
Timer Nov 1, 2019
b672aca
Remove extra new line
Timer Nov 1, 2019
fd48959
Fix TypeScript typings
Timer Nov 1, 2019
9ca22a7
Adding _internal_fetch alias
janicklas-ralph Nov 1, 2019
db9ac6e
Adjust build manifest plugin
Timer Nov 1, 2019
396cfa6
Build manifest plugin changes - adding a separate entry for polyfills
janicklas-ralph Nov 1, 2019
d847e41
Rename polyfills entry in build-manifest.json
janicklas-ralph Nov 1, 2019
a65639f
Remove old comment
janicklas-ralph Nov 1, 2019
ddaa945
Fix TS
Timer Nov 1, 2019
158ea95
Set key
Timer Nov 1, 2019
9948d4a
Polyfills already added
Timer Nov 1, 2019
5875e56
Filtring polyfill.module.js
janicklas-ralph Nov 1, 2019
67abbb4
Merge branch 'polyfill-fetch' of github.com:janicklas-ralph/next.js i…
janicklas-ralph Nov 1, 2019
1465e49
Fix test
Timer Nov 1, 2019
1d62898
Add __internal_fetch to alias rule
Timer Nov 1, 2019
cc105fc
Adjust name
Timer Nov 1, 2019
f496dfe
bump size
Timer Nov 2, 2019
6476ac4
ignore polyfills
Timer Nov 2, 2019
8da6ec3
sigh
Timer Nov 2, 2019
d18f903
Merge branch 'canary' into polyfill-fetch
Timer Nov 2, 2019
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
1 change: 1 addition & 0 deletions packages/next/build/polyfills/fetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default window.fetch
Timer marked this conversation as resolved.
Show resolved Hide resolved
23 changes: 22 additions & 1 deletion packages/next/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { fileExists } from '../lib/file-exists'
import { resolveRequest } from '../lib/resolve-request'
import {
CLIENT_STATIC_FILES_RUNTIME_MAIN,
CLIENT_STATIC_FILES_RUNTIME_POLYFILLS,
CLIENT_STATIC_FILES_RUNTIME_WEBPACK,
REACT_LOADABLE_MANIFEST,
SERVER_DIRECTORY,
Expand Down Expand Up @@ -54,6 +55,20 @@ const escapePathVariables = (value: any) => {
: value
}

function getOptimizedAliases(isServer: boolean): { [pkg: string]: string } {
if (isServer) {
return {}
}

const stubWindowFetch = path.join(__dirname, 'polyfills', 'fetch.js')
return {
__internal_fetch: require.resolve('whatwg-fetch'),
unfetch$: stubWindowFetch,
'isomorphic-unfetch$': stubWindowFetch,
'whatwg-fetch$': stubWindowFetch,
}
}

export default async function getBaseWebpackConfig(
dir: string,
{
Expand Down Expand Up @@ -148,6 +163,10 @@ export default async function getBaseWebpackConfig(
dev ? `next-dev.js` : 'next.js'
)
),
[CLIENT_STATIC_FILES_RUNTIME_POLYFILLS]: path.join(
NEXT_PROJECT_ROOT_DIST_CLIENT,
'polyfills.js'
),
}
: undefined

Expand Down Expand Up @@ -196,6 +215,7 @@ export default async function getBaseWebpackConfig(
next: NEXT_PROJECT_ROOT,
[PAGES_DIR_ALIAS]: pagesDir,
[DOT_NEXT_ALIAS]: distDir,
...getOptimizedAliases(isServer),
},
mainFields: isServer ? ['main', 'module'] : ['browser', 'module', 'main'],
plugins: [PnpWebpackPlugin],
Expand Down Expand Up @@ -531,7 +551,8 @@ export default async function getBaseWebpackConfig(
if (
!dev &&
(chunk.name === CLIENT_STATIC_FILES_RUNTIME_MAIN ||
chunk.name === CLIENT_STATIC_FILES_RUNTIME_WEBPACK)
chunk.name === CLIENT_STATIC_FILES_RUNTIME_WEBPACK ||
chunk.name === CLIENT_STATIC_FILES_RUNTIME_POLYFILLS)
) {
return chunk.name.replace(/\.js$/, '-[contenthash].js')
}
Expand Down
16 changes: 13 additions & 3 deletions packages/next/build/webpack/plugins/build-manifest-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import devalue from 'devalue'
import { Compiler } from 'webpack'
import { RawSource } from 'webpack-sources'

import {
BUILD_MANIFEST,
CLIENT_STATIC_FILES_PATH,
CLIENT_STATIC_FILES_RUNTIME_MAIN,
CLIENT_STATIC_FILES_RUNTIME_POLYFILLS,
IS_BUNDLED_PAGE_REGEX,
ROUTE_NAME_REGEX,
} from '../../../next-server/lib/constants'
import { Compiler } from 'webpack'
import { RawSource } from 'webpack-sources'

interface AssetMap {
devFiles: string[]
Expand All @@ -27,7 +29,7 @@ const generateClientManifest = (
const appDependencies = new Set(assetMap.pages['/_app'])

Object.entries(assetMap.pages).forEach(([page, dependencies]) => {
if (page === '/_app') return
if (page === '/_app' || page === '/_polyfills') return
// Filter out dependencies in the _app entry, because those will have already
// been loaded by the client prior to a navigation event
const filteredDeps = dependencies.filter(
Expand Down Expand Up @@ -74,6 +76,11 @@ export default class BuildManifestPlugin {
? mainJsChunk.files.filter((file: string) => /\.js$/.test(file))
: []

const polyfillChunk = chunks.find(
c => c.name === CLIENT_STATIC_FILES_RUNTIME_POLYFILLS
)
const polyfillFiles: string[] = polyfillChunk ? polyfillChunk.files : []

for (const filePath of Object.keys(compilation.assets)) {
const path = filePath.replace(/\\/g, '/')
if (/^static\/development\/dll\//.test(path)) {
Expand Down Expand Up @@ -125,6 +132,9 @@ export default class BuildManifestPlugin {
assetMap.pages['/'] = assetMap.pages['/index']
}

// Create a separate entry for polyfills
assetMap.pages['/_polyfills'] = polyfillFiles

// Add the runtime build manifest file (generated later in this file)
// as a dependency for the app. If the flag is false, the file won't be
// downloaded by the client.
Expand Down
1 change: 1 addition & 0 deletions packages/next/client/polyfills.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '__internal_fetch'
2 changes: 2 additions & 0 deletions packages/next/next-server/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export const CLIENT_STATIC_FILES_RUNTIME_MAIN = `${CLIENT_STATIC_FILES_RUNTIME_P
export const CLIENT_STATIC_FILES_RUNTIME_AMP = `${CLIENT_STATIC_FILES_RUNTIME_PATH}/amp.js`
// static/runtime/webpack.js
export const CLIENT_STATIC_FILES_RUNTIME_WEBPACK = `${CLIENT_STATIC_FILES_RUNTIME_PATH}/webpack.js`
// static/runtime/polyfills.js
export const CLIENT_STATIC_FILES_RUNTIME_POLYFILLS = `${CLIENT_STATIC_FILES_RUNTIME_PATH}/polyfills.js`
// matches static/<buildid>/pages/<page>.js
export const IS_BUNDLED_PAGE_REGEX = /^static[/\\][^/\\]+[/\\]pages.*\.js$/
// matches static/<buildid>/pages/:page*.js
Expand Down
1 change: 1 addition & 0 deletions packages/next/next-server/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ export type DocumentProps = DocumentInitialProps & {
hasCssMode: boolean
devFiles: string[]
files: string[]
polyfillFiles: string[]
dynamicImports: ManifestItem[]
assetPrefix?: string
canonicalBase: string
Expand Down
5 changes: 5 additions & 0 deletions packages/next/next-server/server/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ function renderDocument(
staticMarkup,
devFiles,
files,
polyfillFiles,
dynamicImports,
htmlProps,
bodyTags,
Expand All @@ -207,6 +208,7 @@ function renderDocument(
dynamicImports: ManifestItem[]
files: string[]
devFiles: string[]
polyfillFiles: string[]
htmlProps: any
bodyTags: any
headTags: any
Expand Down Expand Up @@ -242,6 +244,7 @@ function renderDocument(
staticMarkup,
devFiles,
files,
polyfillFiles,
dynamicImports,
assetPrefix,
htmlProps,
Expand Down Expand Up @@ -488,6 +491,7 @@ export async function renderToHTML(
...getPageFiles(buildManifest, '/_app'),
]),
]
const polyfillFiles = getPageFiles(buildManifest, '/_polyfills')

const renderElementToString = staticMarkup
? renderToStaticMarkup
Expand Down Expand Up @@ -642,6 +646,7 @@ export async function renderToHTML(
dynamicImports,
files,
devFiles,
polyfillFiles,
})

if (inAmpMode && html) {
Expand Down
3 changes: 2 additions & 1 deletion packages/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@
"webpack": "4.39.0",
"webpack-dev-middleware": "3.7.0",
"webpack-hot-middleware": "2.25.0",
"webpack-sources": "1.4.3"
"webpack-sources": "1.4.3",
"whatwg-fetch": "3.0.0"
},
"peerDependencies": {
"react": "^16.6.0",
Expand Down
20 changes: 20 additions & 0 deletions packages/next/pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,25 @@ export class NextScript extends Component<OriginProps> {
})
}

getPolyfillScripts() {
// polyfills.js has to be rendered as nomodule without async
// It also has to be the first script to load
const { assetPrefix, polyfillFiles } = this.context._documentProps
const { _devOnlyInvalidateCacheQueryString } = this.context

return polyfillFiles
.filter(polyfill => !/\.module\.js$/.test(polyfill))
.map(polyfill => (
<script
key={polyfill}
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
noModule={true}
src={`${assetPrefix}/_next/${polyfill}${_devOnlyInvalidateCacheQueryString}`}
/>
))
}

static getInlineScriptSource(documentProps: DocumentProps) {
const { __NEXT_DATA__ } = documentProps
try {
Expand Down Expand Up @@ -784,6 +803,7 @@ export class NextScript extends Component<OriginProps> {
}}
/>
) : null}
{this.getPolyfillScripts()}
{page !== '/_error' && pageScript}
{appScript}
{staticMarkup ? null : this.getDynamicChunks()}
Expand Down
2 changes: 1 addition & 1 deletion test/integration/build-stats-output/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ const appDir = join(__dirname, '../react-site')
describe('Build Stats Output', () => {
it('Shows correct package count in output', async () => {
const { stdout } = await nextBuild(appDir, undefined, { stdout: true })
expect(stdout).toMatch(/\/something .*?4/)
expect(stdout).toMatch(/\/something .*?2/)
})
})
5 changes: 3 additions & 2 deletions test/integration/defer-scripts/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ describe('Defer Scripts', () => {
let missing = false

for (const script of $('script').toArray()) {
const { defer, type } = script.attribs
const { defer, type, src } = script.attribs
// application/json doesn't need defer
if (type === 'application/json') {
// polyfills cannot be deferred or async'd
if (type === 'application/json' || src.includes('polyfills')) {
continue
}

Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -15264,7 +15264,7 @@ [email protected]:
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f"
integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==

whatwg-fetch@>=0.10.0:
whatwg-fetch@3.0.0, whatwg-fetch@>=0.10.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"
integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==
Expand Down