Skip to content

Commit

Permalink
Remove IE polyfills and special casing (#2947)
Browse files Browse the repository at this point in the history
* Remove IE polyfills and special casing

* dashboard: remove `resize-observer-polyfill`

* deps: remove url-parse to use global `URL` instead

* Update documentation for browser support

* Add a migration guide

* Update e2e test platforms

* Remove polyfills from examples and add those missing in CDN bundle

* Use Node.js v16.x on CI because of `AbortController`

* Update bundle builder to produce two builds: `uppy.js` without polyfills, `uppy.legacy.js` with polyfills.

* Upgrade create-react-app deps

* remove null coalescing operator as it's not supported by the build chain

* disable Safari testing (for now)


Co-authored-by: Renée Kooi <[email protected]>
  • Loading branch information
aduh95 and goto-bus-stop authored Jun 28, 2021
1 parent a194865 commit c315329
Show file tree
Hide file tree
Showing 49 changed files with 14,555 additions and 13,104 deletions.
7 changes: 5 additions & 2 deletions .browserslistrc
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
IE 10
[production]
last 2 Safari versions
last 2 Chrome versions
last 2 ChromeAndroid versions
last 2 Firefox versions
last 2 FirefoxAndroid versions
last 2 Edge versions
iOS 11.2
iOS >=13.4

[legacy]
IE 11
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v2-beta
with:
node-version: 14.x
node-version: 16.x
- name: Install npm 7
run: npm install --global npm@7
- name: Install dependencies
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/end-to-end.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v2-beta
with:
node-version: 14.x
node-version: 16.x
- name: Install npm 7
run: npm install --global npm@7
- name: Install dependencies
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ In the current stage we aim to release a new version at least every month.

### next

- **BREAKING CHANGE**: Remove built-in polyfills for Internet Explorer and Safari ≤13.0.

## June 2021

To be released: 2021-06-28
Expand Down
45 changes: 32 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,31 +155,50 @@ The ⓒ mark means that [`@uppy/companion`](https://uppy.io/docs/companion), a s
<img src="https://saucelabs.com/browser-matrix/transloadit-uppy.svg" alt="Sauce Test Status"/>
</a>

We aim to support IE11 and recent versions of Safari, Edge, Chrome, Firefox and Opera.
We aim to support recent versions of Safari, Edge, Chrome, Firefox and Opera.

We still run end-to-end tests with IE10, but we are not actively supporting it or fixing visual / minor issues.
We still provide a bundle which should work on IE11, but we are not running tests on it.

### Polyfills

Uppy heavily uses Promises. If your target environment [does not support Promises](https://caniuse.com/#feat=promises), use a polyfill like `es6-promise` before initializing Uppy.
Here's a list of polyfills you'll need to include to make Uppy work in older browsers, such as IE11:

When using remote providers like Google Drive or Dropbox, the Fetch API is used. If your target environment does not support the [Fetch API](https://caniuse.com/#feat=fetch), use a polyfill like `whatwg-fetch` before initializing Uppy. The Fetch API polyfill must be loaded _after_ the Promises polyfill, because Fetch uses Promises.
- [abortcontroller-polyfill](https://github.com/mo/abortcontroller-polyfill)
- [es6-promise](https://github.com/stefanpenner/es6-promise)
- [math-log2](https://github.com/sindresorhus/math-log2)
- [md-gum-polyfill](https://github.com/mozdevs/mediaDevices-getUserMedia-polyfill)
- [resize-observer-polyfill](https://github.com/que-etc/resize-observer-polyfill)
- [symbol-es6](https://github.com/rousan/symbol-es6)
- [url-polyfill](https://github.com/lifaon74/url-polyfill)
- [whatwg-fetch](https://github.com/github/fetch)

With a module bundler, you can use the required polyfills like so:
If you're using a bundler, you need import them before Uppy:

```shell
npm install es6-promise whatwg-fetch
```
```js
import 'es6-promise/auto'
import 'whatwg-fetch'
import Uppy from '@uppy/core'
import 'es6-promise/auto';
import 'whatwg-fetch';
import 'abortcontroller-polyfill/dist/polyfill-patch-fetch';
// Order matters: AbortController needs fetch which needs Promise.

import mathLog2 from 'math-log2';
import 'md-gum-polyfill';
import ResizeObserver from 'resize-observer-polyfill';
import 'symbol-es6';
import 'url-polyfill';

Math.log2 ??= mathLog2;
window.ResizeObserver ??= ResizeObserver;

export { default } from '@uppy/core';
export * from '@uppy/core';
```
If you're using Uppy from CDN, `es6-promise` and `whatwg-fetch` are already included in the bundle, so no need to include anything additionally:
If you're using Uppy from CDN, those polyfills are already included in the legacy
bundle, so no need to include anything additionally:
```html
<script src="https://releases.transloadit.com/uppy/v1.29.1/uppy.min.js"></script>
<script nomodule src="https://releases.transloadit.com/uppy/v2.0.0/uppy.legacy.min.js"></script>
<script type="module">import"https://releases.transloadit.com/uppy/v2.0.0/uppy.min.js";</script>
```
## FAQ
Expand Down
71 changes: 59 additions & 12 deletions bin/build-bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ const browserify = require('browserify')
const exorcist = require('exorcist')
const glob = require('glob')
const path = require('path')
const { minify } = require('terser')
const { transformFileAsync } = require('@babel/core')

function handleErr (err) {
console.error(chalk.red('✗ Error:'), chalk.red(err.message))
}

// eslint-disable-next-line no-shadow
function buildBundle (srcFile, bundleFile, { minify = false, standalone = '' } = {}) {
const b = browserify(srcFile, { debug: true, standalone })
if (minify) {
Expand All @@ -31,36 +34,80 @@ function buildBundle (srcFile, bundleFile, { minify = false, standalone = '' } =
} else {
console.info(chalk.green(`✓ Built Bundle [${standalone}]:`), chalk.magenta(bundleFile))
}
resolve()
resolve([bundleFile, standalone])
})
})
}
async function minifyBundle ([bundleFile, standalone]) {
const minifiedFilePath = bundleFile.replace(/\.js$/, '.min.js')
const sourceMapPath = `${minifiedFilePath}.map`
const js = await fs.promises.readFile(bundleFile, 'utf-8')
const { code, map } = await minify(js, {
sourceMap: {
content: fs.readFileSync(`${bundleFile}.map`, 'utf-8'),
url:sourceMapPath,
},
toplevel: true,
})
return Promise.all([
fs.promises.writeFile(minifiedFilePath, code),
fs.promises.writeFile(sourceMapPath, map),
])
.then(() => console.info(chalk.green(`✓ Built Minified Bundle [${standalone}]:`), chalk.magenta(minifiedFilePath)))
}
async function transpileDownForIE ([bundleFile, standalone]) {
const minifiedFilePath = bundleFile.replace(/\.js$/, '.min.js')
const sourceMapPath = `${minifiedFilePath}.map`
const { code: js, map: inputMap } = await transformFileAsync(bundleFile, {
compact: false,
highlightCode: false,
inputSourceMap: true,

browserslistEnv: 'legacy',
presets: [['@babel/preset-env', {
modules: false,
loose: true,
targets: { ie:11 },
}]],
})
const { code, map } = await minify(js, {
sourceMap: {
content: inputMap,
url: sourceMapPath,
},
toplevel: true,
})
return Promise.all([
fs.promises.writeFile(bundleFile, js),
fs.promises.writeFile(`${bundleFile}.map`, JSON.stringify(inputMap)),
fs.promises.writeFile(minifiedFilePath, code),
fs.promises.writeFile(sourceMapPath, map),
]).then(() => {
console.info(chalk.green(`✓ Built Bundle [${standalone} (ES5)]:`), chalk.magenta(bundleFile))
console.info(chalk.green(`✓ Built Minified Bundle [${standalone} (ES5)]:`), chalk.magenta(minifiedFilePath))
})
}

mkdirp.sync('./packages/uppy/dist')
mkdirp.sync('./packages/@uppy/robodog/dist')
mkdirp.sync('./packages/@uppy/locales/dist')

const methods = [
buildBundle(
'./packages/uppy/bundle.js',
'./packages/uppy/index.js',
'./packages/uppy/dist/uppy.js',
{ standalone: 'Uppy' }
),
).then(minifyBundle),
buildBundle(
'./packages/uppy/bundle.js',
'./packages/uppy/dist/uppy.min.js',
{ standalone: 'Uppy', minify: true }
),
'./packages/uppy/dist/uppy.legacy.js',
{ standalone: 'Uppy (with polyfills)' }
).then(transpileDownForIE),
buildBundle(
'./packages/@uppy/robodog/bundle.js',
'./packages/@uppy/robodog/dist/robodog.js',
{ standalone: 'Robodog' }
),
buildBundle(
'./packages/@uppy/robodog/bundle.js',
'./packages/@uppy/robodog/dist/robodog.min.js',
{ standalone: 'Robodog', minify: true }
),
).then(minifyBundle),
]

// Build minified versions of all the locales
Expand Down
4 changes: 0 additions & 4 deletions examples/dev/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
// Polyfills, primarily for testing in IE11
require('es6-promise/auto')
require('whatwg-fetch')

const DragDrop = require('./DragDrop.js')
const Dashboard = require('./Dashboard.js')

Expand Down
14 changes: 10 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@
"website"
],
"devDependencies": {
"@babel/cli": "7.10.5",
"@babel/core": "7.11.1",
"@babel/cli": "^7.14.5",
"@babel/core": "^7.14.6",
"@babel/eslint-parser": "7.11.3",
"@babel/eslint-plugin": "7.11.3",
"@babel/plugin-proposal-class-properties": "7.10.4",
"@babel/plugin-transform-object-assign": "7.10.4",
"@babel/plugin-transform-react-jsx": "7.10.4",
"@babel/polyfill": "7.10.4",
"@babel/preset-env": "7.11.0",
"@babel/preset-env": "^7.14.7",
"@babel/register": "7.10.5",
"@goto-bus-stop/envify": "5.0.0",
"@jamen/lorem": "0.2.0",
Expand All @@ -47,6 +47,7 @@
"@wdio/local-runner": "5.18.6",
"@wdio/mocha-framework": "5.18.6",
"@wdio/sauce-service": "5.16.10",
"abortcontroller-polyfill": "^1.7.3",
"adm-zip": "0.4.14",
"aliasify": "2.1.0",
"autoprefixer": "9.7.4",
Expand Down Expand Up @@ -91,6 +92,8 @@
"last-commit-message": "1.0.0",
"lerna": "^3.22.1",
"lint-staged": "9.5.0",
"math-log2": "^2.0.0",
"md-gum-polyfill": "^1.0.0",
"mime-types": "2.1.26",
"minify-stream": "2.0.1",
"minimist": "^1.2.5",
Expand All @@ -113,18 +116,22 @@
"remark-cli": "^8.0.1",
"remark-lint-uppy": "file:private/remark-lint-uppy",
"replacestream": "^4.0.3",
"resize-observer-polyfill": "^1.5.1",
"resolve": "^1.17.0",
"rimraf": "2.7.1",
"sass": "1.29.0",
"size-limit": "4.5.6",
"stringify-object": "3.3.0",
"symbol-es6": "^0.1.2",
"tar": "4.4.13",
"temp-write": "3.4.0",
"terser": "^5.7.0",
"tinyify": "3.0.0",
"tsd": "^0.11.0",
"tsify": "5.0.1",
"tus-node-server": "0.3.2",
"typescript": "~4.1",
"url-polyfill": "^1.1.12",
"verdaccio": "^4.8.0",
"watchify": "3.11.1",
"webdriverio": "5.18.6",
Expand Down Expand Up @@ -158,7 +165,6 @@
"start": "npm-run-all --parallel watch start:companion web:start",
"test:companion": "npm run --prefix ./packages/@uppy/companion test",
"test:endtoend:build-ci": "bash ./bin/endtoend-build-ci",
"test:endtoend:build": "bash ./bin/endtoend-build",
"test:endtoend:local": "npm run test:endtoend:build && wdio test/endtoend/wdio.local.conf.js",
"test:endtoend:providers": "npm run test:endtoend:build && . ./test/endtoend/providers/env.sh && wdio test/endtoend/wdio.local.conf.js --spec test/endtoend/providers/provider.*.test.js",
"test:endtoend:prepare-ci": "npm-run-all --parallel --race test:endtoend:registry test:endtoend:build-ci",
Expand Down
3 changes: 1 addition & 2 deletions packages/@uppy/aws-s3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@
"@uppy/utils": "file:../utils",
"@uppy/xhr-upload": "file:../xhr-upload",
"cuid": "^2.1.1",
"qs-stringify": "^1.1.0",
"url-parse": "^1.4.7"
"qs-stringify": "^1.1.0"
},
"devDependencies": {
"whatwg-fetch": "3.6.2"
Expand Down
6 changes: 1 addition & 5 deletions packages/@uppy/aws-s3/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
* the XHRUpload code, but at least it's not horrifically broken :)
*/

// If global `URL` constructor is available, use it
const URL_ = typeof URL === 'function' ? URL : require('url-parse')
const { BasePlugin } = require('@uppy/core')
const Translator = require('@uppy/utils/lib/Translator')
const RateLimitedQueue = require('@uppy/utils/lib/RateLimitedQueue')
Expand All @@ -38,9 +36,7 @@ const MiniXHRUpload = require('./MiniXHRUpload')
const isXml = require('./isXml')

function resolveUrl (origin, link) {
return origin
? new URL_(link, origin).toString()
: new URL_(link).toString()
return new URL(link, origin || undefined).toString()
}

/**
Expand Down
3 changes: 1 addition & 2 deletions packages/@uppy/companion-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"dependencies": {
"@uppy/utils": "file:../utils",
"namespace-emitter": "^2.0.1",
"qs-stringify": "^1.1.0",
"url-parse": "^1.4.7"
"qs-stringify": "^1.1.0"
}
}
1 change: 0 additions & 1 deletion packages/@uppy/companion-client/src/Provider.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict'

const qsStringify = require('qs-stringify')
const URL = require('url-parse')
const RequestClient = require('./RequestClient')
const tokenStorage = require('./tokenStorage')

Expand Down
6 changes: 1 addition & 5 deletions packages/@uppy/core/src/loggers.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ const justErrorsLogger = {
// Print logs to console with namespace + timestamp,
// set by logger: Uppy.debugLogger or debug: true
const debugLogger = {
debug: (...args) => {
// IE 10 doesn’t support console.debug
const debug = console.debug || console.log
debug.call(console, `[Uppy] [${getTimeStamp()}]`, ...args)
},
debug: (...args) => console.debug(`[Uppy] [${getTimeStamp()}]`, ...args),
warn: (...args) => console.warn(`[Uppy] [${getTimeStamp()}]`, ...args),
error: (...args) => console.error(`[Uppy] [${getTimeStamp()}]`, ...args),
}
Expand Down
6 changes: 5 additions & 1 deletion packages/@uppy/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@
"lodash.debounce": "^4.0.8",
"lodash.throttle": "^4.1.1",
"memoize-one": "^5.0.4",
"preact": "^10.5.13",
"preact": "^10.5.13"
},
"devDependencies": {
"@uppy/google-drive": "*",
"@uppy/status-bar": "*",
"resize-observer-polyfill": "^1.5.0"
},
"peerDependencies": {
Expand Down
1 change: 0 additions & 1 deletion packages/@uppy/dashboard/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const getDroppedFiles = require('@uppy/utils/lib/getDroppedFiles')
const getTextDirection = require('@uppy/utils/lib/getTextDirection')
const trapFocus = require('./utils/trapFocus')
const cuid = require('cuid')
const ResizeObserver = require('resize-observer-polyfill').default || require('resize-observer-polyfill')
const createSuperFocus = require('./utils/createSuperFocus')
const memoize = require('memoize-one').default || require('memoize-one')
const FOCUSABLE_ELEMENTS = require('@uppy/utils/lib/FOCUSABLE_ELEMENTS')
Expand Down
8 changes: 8 additions & 0 deletions packages/@uppy/dashboard/src/index.test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
/* global globalThis */
const Core = require('@uppy/core')
const StatusBarPlugin = require('@uppy/status-bar')
const GoogleDrivePlugin = require('@uppy/google-drive')
const DashboardPlugin = require('./index')

describe('Dashboard', () => {
beforeAll(() => {
globalThis.ResizeObserver = require('resize-observer-polyfill').default || require('resize-observer-polyfill')
})
afterAll(() => {
delete globalThis.ResizeObserver
})

it('can safely be added together with the StatusBar without id conflicts', () => {
const core = new Core()
core.use(StatusBarPlugin)
Expand Down
1 change: 0 additions & 1 deletion packages/@uppy/image-editor/src/Editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,6 @@ module.exports = class Editor extends Component {
render () {
const { currentImage, i18n, opts } = this.props
const { actions } = opts
// eslint-disable-next-line compat/compat
const imageURL = URL.createObjectURL(currentImage.data)

return (
Expand Down
Loading

0 comments on commit c315329

Please sign in to comment.