-
Notifications
You must be signed in to change notification settings - Fork 73
/
parse-cjs.js
80 lines (66 loc) · 1.8 KB
/
parse-cjs.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
/**
* @module Provides language behavior (parser) for importing CommonJS as a
* virtual module source.
*/
/** @import {ParseFn} from './types.js' */
import { analyzeCommonJS } from '@endo/cjs-module-analyzer';
import { wrap, getModulePaths } from './parse-cjs-shared-export-wrapper.js';
const textDecoder = new TextDecoder();
const { freeze } = Object;
/** @type {ParseFn} */
export const parseCjs = (
bytes,
_specifier,
location,
_packageLocation,
{ readPowers } = {},
) => {
const source = textDecoder.decode(bytes);
const {
requires: imports,
exports,
reexports,
} = analyzeCommonJS(source, location);
if (!exports.includes('default')) {
exports.push('default');
}
const { filename, dirname } = getModulePaths(readPowers, location);
/**
* @param {object} moduleEnvironmentRecord
* @param {Compartment} compartment
* @param {Record<string, string>} resolvedImports
*/
const execute = (moduleEnvironmentRecord, compartment, resolvedImports) => {
const functor = compartment.evaluate(
`(function (require, exports, module, __filename, __dirname) { ${source} //*/\n})\n//# sourceURL=${location}`,
);
const { require, moduleExports, module, afterExecute } = wrap({
moduleEnvironmentRecord,
compartment,
resolvedImports,
location,
readPowers,
});
// In CommonJS, the top-level `this` is the `module.exports` object.
functor.call(
moduleExports,
require,
moduleExports,
module,
filename,
dirname,
);
afterExecute();
};
return {
parser: 'cjs',
bytes,
record: freeze({ imports, exports, reexports, execute }),
};
};
/** @type {import('./types.js').ParserImplementation} */
export default {
parse: parseCjs,
heuristicImports: true,
synchronous: true,
};