/
wmr.config.js
85 lines (80 loc) · 2.62 KB
/
wmr.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import babel from '@babel/standalone';
/** @param {import("../../..").Options} options */
export default function ({ mode, prod, env, ...options }) {
console.log('CONFIG: ', { mode, prod, env });
if (mode !== 'build') return;
options.plugins.push({
name: 'legacy',
async generateBundle(opts, bundle) {
const downleveled = new Map();
for (const fileName in bundle) {
const chunk = bundle[fileName];
if (chunk.type !== 'chunk') continue;
const legacy = downlevel(chunk.code, fileName);
if (!legacy) continue;
const legacyFileName = chunk.fileName.replace(/\.js/, '.legacy.js');
this.emitFile({
type: 'asset',
fileName: legacyFileName,
source: legacy
});
downleveled.set(fileName, legacyFileName);
}
// Update all the HTML files with <script type=module> to add legacy loading via Shimport+Polyfills
for (const fileName in bundle) {
const asset = bundle[fileName];
if (asset.type !== 'asset' || typeof asset.source !== 'string' || !asset.fileName.match(/\.html$/)) continue;
if (!/<script(?:\s[^>]*)?\s+type=(['"])module\1/.test(asset.source)) continue;
// this is gross obviously
const POLYFILL = 'https://unpkg.com/@babel/polyfill@7.12.1/browser.js'; // https://unpkg.com/regenerator-runtime
const SHIMPORT = 'https://unpkg.com/shimport@2.0.4/index.js';
const script = `<script nomodule src="${POLYFILL}"></script><script nomodule src="${SHIMPORT}"></script><script nomodule>[].forEach.call(document.querySelectorAll('script[type=module]'),function(n){__shimport__.load(n.src.replace(/\\.js$/,'.legacy.js'))})</script>`;
if (/<\/body>/.test(asset.source)) {
asset.source = asset.source.replace(/<\/body>/, `${script}</body>`);
} else {
asset.source += script;
}
}
}
});
}
function downlevel(code, fileName) {
const result = babel.transform(code, {
compact: true,
minified: true,
configFile: false,
babelrc: false,
filename: fileName,
presets: [
[
'env',
{
targets: 'defaults',
loose: true,
bugfixes: true,
corejs: false,
useBuiltIns: false,
modules: false
}
]
],
plugins: [
{
visitor: {
ImportDeclaration(path) {
path.node.source.value = path.node.source.value.replace(/\.js$/, '.legacy.js');
},
Import(path) {
const p = path.parentPath;
if (!p.isCallExpression()) return;
const arg = p.get('arguments.0');
// the things I do to make TypeScript happy...
if (Array.isArray(arg) || !arg.isStringLiteral()) return;
arg.node.value = arg.node.value.replace(/\.js$/, '.legacy.js');
}
}
}
]
});
return result.code;
}