diff --git a/README.md b/README.md index ad49a85..54868e7 100644 --- a/README.md +++ b/README.md @@ -169,22 +169,26 @@ export default { ## Content Security Policy -The legacy plugin requires inline scripts for [Safari 10.1 `nomodule` fix](https://gist.github.com/samthor/64b114e4a4f539915a95b91ffd340acc), SystemJS initialization, and dynamic import fallback. If you have a strict CSP policy requirement, you will need to [add the corresponding hashes to your `script-src` list](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#unsafe_inline_script): +The legacy plugin requires inline scripts for [Safari 10.1 `nomodule` fix](https://gist.github.com/samthor/64b114e4a4f539915a95b91ffd340acc), SystemJS initialization, and dynamic import fallback. If you have a strict CSP policy requirement, you will need to [add the corresponding hashes to your `script-src` list](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#unsafe_inline_script). + +The hash values (without the `sha256-` prefix) can be retrieved via: + +```js +import { cspHashes } from 'vite-plugin-legacy-swc' +``` + +The current values are: - `sha256-MS6/3FCg4WjP9gwgaBGwLpRCY6fZBgwmhVCdrPrNf3E=` - `sha256-tQjf8gvb2ROOMapIxFvFAYBeUJ0v1HCbOcSmDNXGtDo=` -- `sha256-4y/gEB2/KIwZFTfNqwXJq4olzvmQ0S214m9jwKgNXoc=` +- `sha256-VA8O2hAdooB288EpSTrGLl7z3QikbWU9wwoebO/QaYk=` - `sha256-+5XkZFazzJo8n0iOP4ti/cLCMUudTf//Mzkb7xNPXIc=` -These values (without the `sha256-` prefix) can also be retrieved via - -```js -import { cspHashes } from 'vite-plugin-legacy-swc' -``` +Note that these values could change between minor versions. Thus, we recommend generating the CSP header from the exported `cspHashes` variable. If you copy the values manually, then you should pin the minor version using `~`. When using the `regenerator-runtime` polyfill, it will attempt to use the `globalThis` object to register itself. If `globalThis` is not available (it is [fairly new](https://caniuse.com/?search=globalThis) and not widely supported, including IE 11), it attempts to perform dynamic `Function(...)` call which violates the CSP. To avoid dynamic `eval` in the absence of `globalThis` consider adding `core-js/proposals/global-this` to `additionalLegacyPolyfills` to define it. diff --git a/src/snippets.ts b/src/snippets.ts index d4643ab..032fdaa 100644 --- a/src/snippets.ts +++ b/src/snippets.ts @@ -7,9 +7,8 @@ export const legacyEntryId = 'vite-legacy-entry' export const systemJSInlineCode = `System.import(document.getElementById('${legacyEntryId}').getAttribute('data-src'))` const detectModernBrowserVarName = '__vite_is_modern_browser' -export const detectModernBrowserDetector - = 'import.meta.url;import("_").catch(()=>1);async function* g(){};' -export const detectModernBrowserCode = `${detectModernBrowserDetector}if(location.protocol!="file:"){window.${detectModernBrowserVarName}=true}` +export const detectModernBrowserDetector = `import.meta.url;import("_").catch(()=>1);(async function*(){})().next()` +export const detectModernBrowserCode = `${detectModernBrowserDetector};if(location.protocol!="file:"){window.${detectModernBrowserVarName}=true}` export const dynamicFallbackInlineCode = `!function(){if(window.${detectModernBrowserVarName})return;console.warn("vite: loading legacy chunks, syntax error above and the same error below should be ignored");var e=document.getElementById("${legacyPolyfillId}"),n=document.createElement("script");n.src=e.src,n.onload=function(){${systemJSInlineCode}},document.body.appendChild(n)}();` export const modernChunkLegacyGuard = `export function __vite_legacy_guard(){${detectModernBrowserDetector}};` diff --git a/tests/snippets.spec.ts b/tests/snippets.spec.ts index b249492..8fc46b1 100644 --- a/tests/snippets.spec.ts +++ b/tests/snippets.spec.ts @@ -1,15 +1,21 @@ import type { ecmaVersion } from 'acorn' import { parse } from 'acorn' -import { expect, test } from 'vitest' -import { detectModernBrowserDetector } from '../src/snippets' +import { describe, expect, test } from 'vitest' +import { + detectModernBrowserCode, + detectModernBrowserDetector, + dynamicFallbackInlineCode, + safari10NoModuleFix, + systemJSInlineCode, +} from '../src/snippets' const shouldFailVersions: ecmaVersion[] = [] for (let v = 2015; v <= 2019; v++) { shouldFailVersions.push(v as ecmaVersion) } -const shouldPassVersions: acorn.ecmaVersion[] = [] -for (let v = 2020; v <= 2022; v++) { +const shouldPassVersions: ecmaVersion[] = [] +for (let v = 2020; v <= 2024; v++) { shouldPassVersions.push(v as ecmaVersion) } @@ -34,3 +40,23 @@ for (const version of shouldPassVersions) { }).not.toThrow() }) } + +describe('snippets are valid', () => { + const codes = { + safari10NoModuleFix, + systemJSInlineCode, + detectModernBrowserCode, + dynamicFallbackInlineCode, + } + + for (const [name, value] of Object.entries(codes)) { + test(`${name} is valid JS`, () => { + expect(() => { + parse(value, { + ecmaVersion: 'latest', + sourceType: 'module', + }) + }).not.toThrow() + }) + } +})