-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(plugin-legacy): @vitejs/plugin-legacy
- Loading branch information
Showing
18 changed files
with
1,434 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
test('should work', async () => { | ||
expect(await page.textContent('#app')).toMatch('Hello') | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export function fn() { | ||
const m = new Map() | ||
m.set('foo', 'Hello') | ||
document.querySelector('#app').textContent = m.get('foo') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<h1 id="app"></h1> | ||
<script type="module" src="./main.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
async function run() { | ||
const { fn } = await import('./async.js') | ||
fn() | ||
} | ||
|
||
run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"name": "test-legacy", | ||
"private": true, | ||
"version": "0.0.0", | ||
"scripts": { | ||
"dev": "vite", | ||
"build": "vite build --debug legacy", | ||
"debug": "node --inspect-brk ../../vite/bin/vite" | ||
}, | ||
"devDependencies": { | ||
"@vitejs/plugin-legacy": "^1.0.0" | ||
}, | ||
"dependencies": {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
const fs = require('fs') | ||
const path = require('path') | ||
const legacy = require('@vitejs/plugin-legacy').default | ||
|
||
module.exports = { | ||
plugins: [ | ||
legacy({ | ||
targets: 'IE 11' | ||
}) | ||
], | ||
|
||
build: { | ||
// make tests faster | ||
minify: false | ||
}, | ||
|
||
// special test only hook | ||
// for tests, remove `<script type="module">` tags and remove `nomodule` | ||
// attrs so that we run the legacy bundle instead. | ||
__test__() { | ||
const indexPath = path.resolve(__dirname, './dist/index.html') | ||
let index = fs.readFileSync(indexPath, 'utf-8') | ||
index = index | ||
.replace(/<script type="module".*?<\/script>/g, '') | ||
.replace(/<script nomodule/g, '<script') | ||
fs.writeFileSync(indexPath, index) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
# @vitejs/plugin-legacy | ||
|
||
Vite's default browser support baseline is [Native ESM](https://caniuse.com/es6-module). This plugin provides support for legacy browsers that do not support native ESM. | ||
|
||
By default, this plugin will: | ||
|
||
- Generate a corresponding legacy chunk for every chunk in the final bundle, transformed with [@babel/preset-env](https://babeljs.io/docs/en/babel-preset-env) and emitted as [SystemJS modules](https://github.com/systemjs/systemjs) (code splitting is still supported!). | ||
|
||
- Generate a polyfill chunk including SystemJS runtime, and any necessary polyfills determined by specified browser targets and **acutal usage** in the bundle. | ||
|
||
- Inject `<script nomdule>` tags into generated HTML to conditionally load the polyfills and legacy bundle only in browsers without native ESM support. | ||
|
||
## Usage | ||
|
||
```js | ||
// vite.config.js | ||
import legacy from '@vitejs/plugin-legacy' | ||
|
||
export default { | ||
plugins: [ | ||
legacy({ | ||
targets: [ | ||
'defaults', | ||
'not IE 11 | ||
] | ||
}) | ||
] | ||
} | ||
``` | ||
## Options | ||
### `targets` | ||
- **Type:** `string | string[] | { [key: string]: string }` | ||
- **Default:** `'defaults'` | ||
If explicitly set, it's passed on to [`@babel/preset-env`](https://babeljs.io/docs/en/babel-preset-env#targets). | ||
|
||
The query is also [Browserslist compatible](https://github.com/browserslist/browserslist). The default value, `'defaults'`, is what is recommended by Browserslist. See [Browserslist Best Practices](https://github.com/browserslist/browserslist#best-practices) for more details. | ||
|
||
### `polyfills` | ||
|
||
- **Type:** `boolean | string[]` | ||
- **Default:** `true` | ||
|
||
By default, a polyfills chunks is generated based on the target browser ranges and actual usage in the final bundle (detected via `@babel/preset-env`'s `useBuiltIns: 'usage'`). | ||
Set to a list of strings to explicitly control which polyfills to include. See [Polyfill Specifiers](#polyfill-specifiers) for details. | ||
Set to `false` to avoid generating polyfills and handle it yourself (will still generate legacy chunks with syntax transformations). | ||
### `ignoreBrowserslistConfig` | ||
- **Type:** `boolean` | ||
- **Default:** `false` | ||
`@babel/preset-env` automatically detects [`browserslist` config sources](https://github.com/browserslist/browserslist#browserslist-): | ||
- `browserslist` field in `package.json` | ||
- `.browserslistrc` file in cwd. | ||
Set to `false` to ignore these sources. | ||
### `modernPolyfills` | ||
- **Type:** `boolean | string[]` | ||
- **Default:** `false` | ||
Defaults to `false`. Enabling this option will generate a separate polyfills chunk for the modern build (targeting browsers with [native ESM support](https://caniuse.com/es6-module)). | ||
Set to a list of strings to explicitly control which polyfills to include. See [Polyfill Specifiers](#polyfill-specifiers) for details. | ||
Note it is **not recommended** to use the `true` value (which uses auto detection) because `core-js@3` is very aggressive in polyfill inclusions due to all the bleeding edge features it supports. Even when targeting native ESM support, it injects 15kb of polyfills! | ||
If you don't have hard reliance on bleeding edge runtime features, it is not that hard to avoid having to use polyfills in the modern build altogether. Alternatively, consider using an on-demand service like [Polyfill.io](https://polyfill.io/v3/) to only inject necessary polyfills based on actual browser useragents (most modern brwosers will need nothing!). | ||
|
||
### `renderLegacyChunks` | ||
|
||
- **Type:** `boolean` | ||
- **Default:** `true` | ||
|
||
Set to `false` to disable legacy chunks. This is only useful if you are using `modernPolyfills`, which essentially allows you to use this plugin for injecting polyfills to the modern build only: | ||
|
||
```js | ||
import legacy from '@vitejs/plugin-legacy' | ||
export default { | ||
plugins: [ | ||
legacy({ | ||
modernPolyfills: [ | ||
/* ... */ | ||
], | ||
renderLegacyChunks: false | ||
}) | ||
] | ||
} | ||
``` | ||
|
||
## Polyfill Sepcifiers | ||
|
||
Polyfill specifier strings for `polyfills` and `modernPolyfills` can be either of the following: | ||
|
||
- Any [`core-js` 3 sub import paths](https://unpkg.com/browse/[email protected]/) - e.g. `es/map` will import `core-js/es/map` | ||
|
||
- Any [individual `core-js` 3 modules](https://unpkg.com/browse/[email protected]/modules/) - e.g. `es.array.iterator` will import `core-js/modules/es.array.iterator.js` | ||
|
||
**Example** | ||
|
||
```js | ||
import legacy from '@vitejs/plugin-legacy' | ||
export default { | ||
plugins: [ | ||
legacy({ | ||
polyfills: [ | ||
'es.promise.finally', | ||
'es/map', | ||
'es/set' | ||
], | ||
modernPolyfills: [ | ||
'es.promise.finally' | ||
] | ||
}) | ||
] | ||
} | ||
``` | ||
|
||
## References | ||
|
||
- [Vue CLI modern mode](https://cli.vuejs.org/guide/browser-compatibility.html#modern-mode) | ||
- [Using Native JavaScript Modules in Production Today](https://philipwalton.com/articles/using-native-javascript-modules-in-production-today/) | ||
- [rollup-native-modules-boilerplate](https://github.com/philipwalton/rollup-native-modules-boilerplate) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { Plugin } from 'vite' | ||
|
||
export interface Options { | ||
/** | ||
* default: 'defaults' | ||
*/ | ||
targets?: string | string[] | { [key: string]: string } | ||
/** | ||
* default: false | ||
*/ | ||
ignoreBrowserslistConfig?: boolean | ||
/** | ||
* default: true | ||
*/ | ||
polyfills?: boolean | string[] | ||
/** | ||
* default: false | ||
*/ | ||
modernPolyfills?: boolean | string[] | ||
/** | ||
* default: true | ||
*/ | ||
renderLegacyChunks?: boolean | ||
} | ||
|
||
declare function createPlugin(options?: Options): Plugin | ||
|
||
export default createPlugin |
Oops, something went wrong.