-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild-umd.mjs
More file actions
84 lines (77 loc) · 3.06 KB
/
Copy pathbuild-umd.mjs
File metadata and controls
84 lines (77 loc) · 3.06 KB
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
/**
* build-umd.mjs
*
* 共 thokit.js(ESM 源碼)構建做 UMD 單文件,予 HTML 內會使直接用
* `<script src="thokit.umd.js"></script>` 載入,了後 `new ThoKit()`。
*
* 做法:
* 1. 用 Babel API(@babel/core)轉譯。先用一个自訂 plugin 共源碼尾部个手工
* 「條件導出」塊(`if (typeof module !== 'undefined' && module.exports) {...}
* else if (typeof window !== 'undefined') {...}`)提掉 —— 即个手工塊佇 UMD
* wrapper 內會佮 wrapper 个 exports 處理衝突(CJS 分支會共 `module.exports`
* 重設做新物件,致到 wrapper 寫入 `exports.ThoKit` 个值脫鉤)。
* `export { ThoKit }` 保留,交予 @babel/plugin-transform-modules-umd 處理。
* 2. Babel UMD wrapper 个瀏覽器分支原本是 `global.ThoKit = mod.exports`(namespace,
* 即 `{ ThoKit, __esModule: true }`),按呢 HTML 內愛 `new ThoKit.ThoKit()`。
* 3. 為著予 HTML 內直接 `new ThoKit()`,共 wrapper 最後一行改做
* `global.ThoKit = mod.exports.ThoKit`(對 namespace 內提取 class 本身)。
*/
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { transformSync } from '@babel/core';
const __dirname = dirname(fileURLToPath(import.meta.url));
const root = resolve(__dirname);
const src = resolve(root, 'thokit.js');
const outDir = resolve(root, 'dist');
const outFile = resolve(outDir, 'thokit.umd.js');
const code = readFileSync(src, 'utf-8');
// 自訂 Babel plugin:提掉源碼尾部个手工「條件導出」塊。
// 即个 if 敘述有一个特徵:測試是 `typeof module !== 'undefined' && module.exports`。
const stripManualExportBlock = ({ types: t }) => ({
name: 'strip-manual-export-block',
visitor: {
IfStatement(path) {
const { test } = path.node;
// 匹配 `typeof module !== 'undefined' && module.exports`
const isTypeofModuleCheck =
t.isLogicalExpression(test, { operator: '&&' }) &&
t.isBinaryExpression(test.left, { operator: '!==' }) &&
t.isUnaryExpression(test.left.left, { operator: 'typeof' }) &&
t.isIdentifier(test.left.left.argument, { name: 'module' });
if (isTypeofModuleCheck) {
path.remove();
}
},
},
});
const result = transformSync(code, {
configFile: false,
babelrc: false,
filename: 'thokit.js',
presets: [
[
'@babel/preset-env',
{
targets: {
browsers: ['> 0.5%', 'last 2 versions', 'not dead'],
},
modules: false,
},
],
],
plugins: [
stripManualExportBlock,
['@babel/plugin-transform-modules-umd', { moduleId: 'ThoKit' }],
],
});
let output = result.code;
// 共 UMD wrapper 瀏覽器分支个 namespace 暴露改做 class 提取,
// 予 HTML <script> 載入了後 `window.ThoKit` 直接是 class(會使 `new ThoKit()`)。
output = output.replace(
/global\.ThoKit = mod\.exports;/,
'global.ThoKit = mod.exports.ThoKit;'
);
mkdirSync(outDir, { recursive: true });
writeFileSync(outFile, output, 'utf-8');
console.log(`UMD build written to ${outFile}`);