-
-
Notifications
You must be signed in to change notification settings - Fork 12
/
index.ts
90 lines (80 loc) · 2.85 KB
/
index.ts
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
86
87
88
89
90
import fs from 'fs';
import path from 'path';
import chalk from 'chalk';
import { createHash } from 'crypto';
import type { Plugin, ResolvedConfig } from 'vite';
import { rswCompile, rswWatch } from './compiler';
import { RswPluginOptions, WasmFileInfo } from './types';
import { debugConfig, checkENV, getCrateName, loadWasm, genLibs, rswOverlay, rswHot } from './utils';
const wasmMap = new Map<string, WasmFileInfo>();
export function ViteRsw(userOptions: RswPluginOptions): Plugin {
let config: ResolvedConfig;
const crateRoot = path.resolve(process.cwd(), userOptions.root || '');
const crateList = userOptions.crates.map(i => getCrateName(i));
const isLib = userOptions?.isLib || false;
const libRoot = userOptions?.libRoot || 'libs';
debugConfig(userOptions);
checkENV();
return {
name: 'vite-plugin-rsw',
enforce: 'pre',
configResolved(_config) {
config = _config;
},
configureServer(serve) {
rswCompile({
config: userOptions,
root: crateRoot,
});
rswWatch(userOptions, crateRoot, serve);
},
transform(code, id) {
if (new RegExp(`(${crateList.join('|')})` + '\\/pkg/.*.js').test(id)) {
const re = id.indexOf('@') > 0 ? '([@\\/].*)' : '';
const _path = id.match(new RegExp(`.*(.*${re}([\\/].*){3}).js$`)) as string[];
const fileId = _path?.[1].replace(/^\//, '') + '_bg.wasm';
// build wasm file
if (!wasmMap.has(fileId) && config?.mode !== 'development') {
const source = fs.readFileSync(path.resolve(crateRoot, fileId));
const hash = createHash('md5').update(String(source)).digest('hex').substring(0, 8);
const _name = config?.build?.assetsDir + '/' + path.basename(fileId).replace('.wasm', `.${hash}.wasm`);
wasmMap.set(fileId, {
fileName: _name,
source,
});
// fix: fetch or URL
code = loadWasm(code, path.basename(fileId), _name);
return code;
}
// wasm file path and rsw hot
return code.replace('import.meta.url.replace(/\\.js$/, \'_bg.wasm\');', `fetch('/${fileId}')`) + rswHot;
}
return code;
},
transformIndexHtml(html) {
// compiler error overlay
if (config?.mode === 'development') {
return html.replace('</html>', `<script>${rswOverlay}</script></html>`);
}
return html;
},
generateBundle() {
if (isLib) {
console.log('\n\n');
console.log(chalk.bgBlue(`[rsw::lib] ${libRoot}`));
crateList.forEach(i => {
genLibs(`${crateRoot}/${i}/pkg`, `${libRoot}/${i}`);
})
console.log();
}
wasmMap.forEach((i: WasmFileInfo) => {
this.emitFile({
fileName: i.fileName,
type: 'asset',
source: (i.source as Uint8Array),
});
})
}
};
}
export default ViteRsw;