Skip to content

Commit 49471b8

Browse files
committed
Start to add code
1 parent e9a31d9 commit 49471b8

File tree

7 files changed

+1093
-0
lines changed

7 files changed

+1093
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.DS_Store
2+
node_modules
3+
dist

rollup.config.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import fs from 'fs';
2+
import replace from '@rollup/plugin-replace';
3+
import path from 'path';
4+
5+
const version = JSON.parse(fs.readFileSync('package.json')).version;
6+
7+
export default [
8+
config(true, false),
9+
config(false, false),
10+
config(false, true),
11+
];
12+
13+
function config (isWasm, isDebug) {
14+
const name = 'es-module-shims'
15+
16+
return {
17+
input: `src/${name}.js`,
18+
output: {
19+
file: `dist/${name}${isWasm ? '.wasm' : ''}${isDebug ? '.debug' : ''}.js`,
20+
format: 'iife',
21+
strict: false,
22+
sourcemap: false,
23+
banner: `/* ES Module Shims ${isWasm ? 'Wasm ' : ''}${isDebug ? 'DEBUG BUILD ' : ''}${version} */`
24+
},
25+
plugins: [
26+
{
27+
resolveId (id) {
28+
if (isWasm && id === '../node_modules/es-module-lexer/dist/lexer.asm.js')
29+
return path.resolve('node_modules/es-module-lexer/dist/lexer.js');
30+
}
31+
},
32+
replace({
33+
'self.ESMS_DEBUG': isDebug.toString(),
34+
preventAssignment: true
35+
}),
36+
]
37+
};
38+
}

src/dynamic-import.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { createBlob, baseUrl, nonce, hasDocument } from './env.js';
2+
3+
export let dynamicImport = !hasDocument && (0, eval)('u=>import(u)');
4+
5+
export let supportsDynamicImport;
6+
7+
export const dynamicImportCheck = hasDocument && new Promise(resolve => {
8+
const s = Object.assign(document.createElement('script'), {
9+
src: createBlob('self._d=u=>import(u)'),
10+
ep: true
11+
});
12+
s.setAttribute('nonce', nonce);
13+
s.addEventListener('load', () => {
14+
if (!(supportsDynamicImport = !!(dynamicImport = self._d))) {
15+
let err;
16+
window.addEventListener('error', _err => err = _err);
17+
dynamicImport = (url, opts) => new Promise((resolve, reject) => {
18+
const s = Object.assign(document.createElement('script'), {
19+
type: 'module',
20+
src: createBlob(`import*as m from'${url}';self._esmsi=m`)
21+
});
22+
err = undefined;
23+
s.ep = true;
24+
if (nonce)
25+
s.setAttribute('nonce', nonce);
26+
// Safari is unique in supporting module script error events
27+
s.addEventListener('error', cb);
28+
s.addEventListener('load', cb);
29+
function cb (_err) {
30+
document.head.removeChild(s);
31+
if (self._esmsi) {
32+
resolve(self._esmsi, baseUrl);
33+
self._esmsi = undefined;
34+
}
35+
else {
36+
reject(!(_err instanceof Event) && _err || err && err.error || new Error(`Error loading ${opts && opts.errUrl || url} (${s.src}).`));
37+
err = undefined;
38+
}
39+
}
40+
document.head.appendChild(s);
41+
});
42+
}
43+
document.head.removeChild(s);
44+
delete self._d;
45+
resolve();
46+
});
47+
document.head.appendChild(s);
48+
});

src/env.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
export const hasWindow = typeof window !== 'undefined';
2+
export const hasDocument = typeof document !== 'undefined';
3+
4+
export const noop = () => {};
5+
6+
const optionsScript = hasDocument ? document.querySelector('script[type=esms-options]') : undefined;
7+
8+
export const esmsInitOptions = optionsScript ? JSON.parse(optionsScript.innerHTML) : {};
9+
Object.assign(esmsInitOptions, self.esmsInitOptions || {});
10+
11+
export let shimMode = hasDocument ? !!esmsInitOptions.shimMode : true;
12+
13+
export const importHook = globalHook(shimMode && esmsInitOptions.onimport);
14+
export const resolveHook = globalHook(shimMode && esmsInitOptions.resolve);
15+
export let fetchHook = esmsInitOptions.fetch ? globalHook(esmsInitOptions.fetch) : fetch;
16+
export const metaHook = esmsInitOptions.meta ? globalHook(shimMode && esmsInitOptions.meta) : noop;
17+
18+
export const mapOverrides = esmsInitOptions.mapOverrides;
19+
20+
export let nonce = esmsInitOptions.nonce;
21+
if (!nonce && hasDocument) {
22+
const nonceElement = document.querySelector('script[nonce]');
23+
if (nonceElement)
24+
nonce = nonceElement.nonce || nonceElement.getAttribute('nonce');
25+
}
26+
27+
export const onerror = globalHook(esmsInitOptions.onerror || noop);
28+
export const onpolyfill = esmsInitOptions.onpolyfill ? globalHook(esmsInitOptions.onpolyfill) : () => {
29+
console.log('%c^^ Module TypeError above is polyfilled and can be ignored ^^', 'font-weight:900;color:#391');
30+
};
31+
32+
export const { revokeBlobURLs, noLoadEventRetriggers, enforceIntegrity } = esmsInitOptions;
33+
34+
function globalHook (name) {
35+
return typeof name === 'string' ? self[name] : name;
36+
}
37+
38+
const enable = Array.isArray(esmsInitOptions.polyfillEnable) ? esmsInitOptions.polyfillEnable : [];
39+
export const cssModulesEnabled = enable.includes('css-modules');
40+
export const jsonModulesEnabled = enable.includes('json-modules');
41+
42+
export const edge = !navigator.userAgentData && !!navigator.userAgent.match(/Edge\/\d+\.\d+/);
43+
44+
export const baseUrl = hasDocument
45+
? document.baseURI
46+
: `${location.protocol}//${location.host}${location.pathname.includes('/')
47+
? location.pathname.slice(0, location.pathname.lastIndexOf('/') + 1)
48+
: location.pathname}`;
49+
50+
export const createBlob = (source, type = 'text/javascript') => URL.createObjectURL(new Blob([source], { type }));
51+
export let { skip } = esmsInitOptions;
52+
if (Array.isArray(skip)) {
53+
const l = skip.map(s => new URL(s, baseUrl).href);
54+
skip = s => l.some(i => i[i.length - 1] === '/' && s.startsWith(i) || s === i);
55+
}
56+
else if (typeof skip === 'string') {
57+
const r = new RegExp(skip);
58+
skip = s => r.test(s);
59+
}
60+
61+
const eoop = err => setTimeout(() => { throw err });
62+
63+
export const throwError = err => { (self.reportError || hasWindow && window.safari && console.error || eoop)(err), void onerror(err) };
64+
65+
export function fromParent (parent) {
66+
return parent ? ` imported from ${parent}` : '';
67+
}
68+
69+
export let importMapSrcOrLazy = false;
70+
71+
export function setImportMapSrcOrLazy () {
72+
importMapSrcOrLazy = true;
73+
}
74+
75+
// shim mode is determined on initialization, no late shim mode
76+
if (!shimMode) {
77+
if (document.querySelectorAll('script[type=module-shim],script[type=importmap-shim],link[rel=modulepreload-shim]').length) {
78+
shimMode = true;
79+
}
80+
else {
81+
let seenScript = false;
82+
for (const script of document.querySelectorAll('script[type=module],script[type=importmap]')) {
83+
if (!seenScript) {
84+
if (script.type === 'module' && !script.ep)
85+
seenScript = true;
86+
}
87+
else if (script.type === 'importmap' && seenScript) {
88+
importMapSrcOrLazy = true;
89+
break;
90+
}
91+
}
92+
}
93+
}

0 commit comments

Comments
 (0)