Skip to content

Commit

Permalink
Polyfill missing std lib fns for module browsers (#17083)
Browse files Browse the repository at this point in the history
  • Loading branch information
Timer authored Sep 14, 2020
1 parent 7203f50 commit 49a59b1
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 29 deletions.
18 changes: 18 additions & 0 deletions packages/next-polyfill-module/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "@next/polyfill-module",
"version": "9.5.4-canary.16",
"description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)",
"main": "dist/polyfill-module.js",
"license": "MIT",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-polyfill-module"
},
"scripts": {
"prepublish": "microbundle src/index.js -f iife --no-sourcemap --external none",
"build": "microbundle watch src/index.js -f iife --no-sourcemap --external none"
},
"devDependencies": {
"microbundle": "0.11.0"
}
}
94 changes: 94 additions & 0 deletions packages/next-polyfill-module/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/* eslint-disable no-extend-native */

// Contains polyfills for methods missing after browser version(s):
// Edge 16, Firefox 60, Chrome 61, Safari 10.1

/**
* Available in:
* Edge: never
* Firefox: 61
* Chrome: 66
* Safari: 12
*
* https://caniuse.com/mdn-javascript_builtins_string_trimstart
* https://caniuse.com/mdn-javascript_builtins_string_trimend
*/
if (!('trimStart' in String.prototype)) {
String.prototype.trimStart = String.prototype.trimLeft
}
if (!('trimEnd' in String.prototype)) {
String.prototype.trimEnd = String.prototype.trimRight
}

/**
* Available in:
* Edge: never
* Firefox: 63
* Chrome: 70
* Safari: 12.1
*
* https://caniuse.com/mdn-javascript_builtins_symbol_description
*/
if (!('description' in Symbol.prototype)) {
Object.defineProperty(Symbol.prototype, 'description', {
get: function get() {
return /\((.+)\)/.exec(this)[1]
},
})
}

/**
* Available in:
* Edge: never
* Firefox: 62
* Chrome: 69
* Safari: 12
*
* https://caniuse.com/array-flat
*/
// Copied from https://gist.github.com/developit/50364079cf0390a73e745e513fa912d9
// Licensed Apache-2.0
if (!Array.prototype.flat) {
Array.prototype.flat = function flat(d, c) {
return (
(c = this.concat.apply([], this)),
d > 1 && c.some(Array.isArray) ? c.flat(d - 1) : c
)
}
Array.prototype.flatMap = function (c, a) {
return this.map(c, a).flat()
}
}

/**
* Available in:
* Edge: 18
* Firefox: 58
* Chrome: 63
* Safari: 11.1
*
* https://caniuse.com/promise-finally
*/
// Modified from https://gist.github.com/developit/e96097d9b657f2a2f3e588ffde433437
// Licensed Apache-2.0
if (!Promise.prototype.finally) {
Promise.prototype.finally = function (callback) {
if (typeof callback !== 'function') {
return this.then(callback, callback)
}

var P = this.constructor || Promise
return this.then(
function (value) {
return P.resolve(callback()).then(function () {
return value
})
},
function (err) {
return P.resolve(callback()).then(function () {
throw err
})
}
)
}
}
9 changes: 3 additions & 6 deletions packages/next/client/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
/* global location */
import '@next/polyfill-module'
import React from 'react'
import ReactDOM from 'react-dom'
import { HeadManagerContext } from '../next-server/lib/head-manager-context'
import mitt from '../next-server/lib/mitt'
import { RouterContext } from '../next-server/lib/router-context'
import { delBasePath, hasBasePath } from '../next-server/lib/router/router'
import type Router from '../next-server/lib/router/router'
import type {
AppComponent,
AppProps,
PrivateRouteInfo,
} from '../next-server/lib/router/router'
import { delBasePath, hasBasePath } from '../next-server/lib/router/router'
import { isDynamicRoute } from '../next-server/lib/router/utils/is-dynamic'
import * as querystring from '../next-server/lib/router/utils/querystring'
import * as envConfig from '../next-server/lib/runtime-config'
import { getURL, loadGetInitialProps, ST } from '../next-server/lib/utils'
import type { NEXT_DATA } from '../next-server/lib/utils'
import { getURL, loadGetInitialProps, ST } from '../next-server/lib/utils'
import initHeadManager from './head-manager'
import PageLoader, { looseToArray, StyleSheetTuple } from './page-loader'
import measureWebVitals from './performance-relayer'
Expand All @@ -41,10 +42,6 @@ declare global {
type RenderRouteInfo = PrivateRouteInfo & { App: AppComponent }
type RenderErrorProps = Omit<RenderRouteInfo, 'Component' | 'styleSheets'>

if (!('finally' in Promise.prototype)) {
;(Promise.prototype as PromiseConstructor['prototype']).finally = require('next/dist/build/polyfills/finally-polyfill.min')
}

const data: typeof window['__NEXT_DATA__'] = JSON.parse(
document.getElementById('__NEXT_DATA__')!.textContent!
)
Expand Down
2 changes: 1 addition & 1 deletion packages/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"@babel/preset-typescript": "7.10.4",
"@babel/runtime": "7.11.2",
"@babel/types": "7.11.5",
"@next/polyfill-module": "9.5.4-canary.16",
"@next/react-dev-overlay": "9.5.4-canary.16",
"@next/react-refresh-utils": "9.5.4-canary.16",
"ast-types": "0.13.2",
Expand Down Expand Up @@ -179,7 +180,6 @@
"escape-string-regexp": "2.0.0",
"etag": "1.8.1",
"file-loader": "6.0.0",
"finally-polyfill": "0.1.0",
"find-up": "4.1.0",
"fresh": "0.5.2",
"gzip-size": "5.1.1",
Expand Down
14 changes: 1 addition & 13 deletions packages/next/taskfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,14 @@ export async function next__polyfill_nomodule(task, opts) {
.target('dist/build/polyfills')
}

export async function finally_polyfill(task, opts) {
await task
.source(
opts.src || relative(__dirname, require.resolve('finally-polyfill'))
)
.target('dist/build/polyfills')
}

export async function unfetch(task, opts) {
await task
.source(opts.src || relative(__dirname, require.resolve('unfetch')))
.target('dist/build/polyfills')
}

export async function browser_polyfills(task) {

This comment has been minimized.

Copy link
@arcanis

arcanis Sep 23, 2020

Contributor

By any chance, do you know why this file uses the export syntax, even though it's a Node script? It seems to work in most cases, but I don't understand why, and it breaks under a specific config of mine .. is there a magic live transpile somewhere 🤔

This comment has been minimized.

Copy link
@Timer

Timer Sep 23, 2020

Author Member

I think taskr handles it automatically.

This comment has been minimized.

Copy link
@arcanis

arcanis Sep 23, 2020

Contributor

Indeed it does! Fixed the problem, thanks 😃

await task.parallel([
'next__polyfill_nomodule',
'finally_polyfill',
'unfetch',
])
await task.parallel(['next__polyfill_nomodule', 'unfetch'])
}

const externals = {
Expand Down
8 changes: 4 additions & 4 deletions test/integration/build-output/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,17 @@ describe('Build Output', () => {
expect(parseFloat(indexSize) - 265).toBeLessThanOrEqual(0)
expect(indexSize.endsWith('B')).toBe(true)

// should be no bigger than 60.2 kb
expect(parseFloat(indexFirstLoad) - 60.5).toBeLessThanOrEqual(0)
// should be no bigger than 60.8 kb
expect(parseFloat(indexFirstLoad) - 60.8).toBeLessThanOrEqual(0)
expect(indexFirstLoad.endsWith('kB')).toBe(true)

expect(parseFloat(err404Size) - 3.5).toBeLessThanOrEqual(0)
expect(err404Size.endsWith('kB')).toBe(true)

expect(parseFloat(err404FirstLoad) - 63.7).toBeLessThanOrEqual(0)
expect(parseFloat(err404FirstLoad) - 63.8).toBeLessThanOrEqual(0)
expect(err404FirstLoad.endsWith('kB')).toBe(true)

expect(parseFloat(sharedByAll) - 60.2).toBeLessThanOrEqual(0)
expect(parseFloat(sharedByAll) - 60.4).toBeLessThanOrEqual(0)
expect(sharedByAll.endsWith('kB')).toBe(true)

if (_appSize.endsWith('kB')) {
Expand Down
5 changes: 0 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7545,11 +7545,6 @@ finalhandler@~1.1.2:
statuses "~1.5.0"
unpipe "~1.0.0"

finally-polyfill@0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/finally-polyfill/-/finally-polyfill-0.1.0.tgz#2a17b16581d9477db16a703c7b79a898ac0b7d50"
integrity sha512-J1LEcZ5VXe1l3sEO+S//WqL5wcJ/ep7QeKJA6HhNZrcEEFj0eyC8IW3DEZhxySI2bx3r85dwAXz+vYPGuHx5UA==

find-cache-dir@3.3.1, find-cache-dir@^3.0.0, find-cache-dir@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880"
Expand Down

0 comments on commit 49a59b1

Please sign in to comment.