-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathesm.js
More file actions
110 lines (97 loc) · 3.41 KB
/
esm.js
File metadata and controls
110 lines (97 loc) · 3.41 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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
var acorn = require('acorn');
var assignParent = require('estree-assign-parent');
var scan = require('scope-analyzer');
var through = require('through2');
module.exports = function esm () {
return through.obj(function (row, enc, cb) {
if (!row.esm) {
cb(null, row);
return;
}
var ast = acorn.parse(row.source, { sourceType: 'module' });
assignParent(ast);
scan.analyze(ast);
var scope = scan.scope(ast);
var esmDefaultName = '_esmDefault'
var patches = [];
ast.body.forEach(function (node) {
if (node.type === 'ExportDefaultDeclaration') {
if (node.declaration.id) {
esmDefaultName = node.declaration.id.name
}
patches.push({
start: node.start,
end: node.declaration.start,
string: node.declaration.id ? '' : 'var _esmDefault = '
});
}
if (node.type === 'ExportNamedDeclaration') {
if (node.declaration) {
// Only erase the `export` bit before `export var`
patches.push({ start: node.start, end: node.declaration.start, string: '' })
} else {
// Erase the entire declaration
patches.push({ start: node.start, end: node.end, string: '' })
}
}
if (node.type === 'ImportDeclaration') {
patches.push({ start: node.start, end: node.end, string: '' });
}
});
var setup = ''
if (row.esm) {
if (row.esm.exports.length > 0) {
// Define getters for exports to support live bindings, and to prevent writes to them from outside this module
setup += '_esmExport({'
row.esm.exports.forEach(function (record, i) {
if (i > 0) setup += ','
if (record.name === 'default' && !record.as && !record.export) {
setup += 'default:function(){return ' + esmDefaultName + '}'
} else {
setup += JSON.stringify(record.as) + ':function(){return ' + record.export + '}'
}
});
setup += '});'
}
var needInterop = false;
var baseImports = {};
row.esm.imports.forEach(function (record, i) {
var binding = scope.getBinding(record.as);
if (!record.esm) {
if (record.import !== 'default') {
throw new Error('The requested module does not provide an export named \'' + record.import + '\'')
}
setup += 'var ' + record.as + ' = ' + '_esmRequire(' + JSON.stringify(record.from) + ');';
return;
}
var base = baseImports[record.from];
if (!base) {
base = baseImports[record.from] = '_esmImport' + i;
setup += 'var ' + base + ' = _esmRequire(' + JSON.stringify(record.from) + ');';
}
binding.references.forEach(function (ref, i) {
if (ref === binding.definition) return
patches.push({
start: ref.start,
end: ref.end,
string: base + '.' + record.import
});
});
});
}
row.source = patch(row.source, patches)
row.source = setup + '\n' + row.source
cb(null, row);
});
};
function patch (str, patches) {
patches = patches.slice().sort(function (a, b) { return a.start - b.start })
var offset = 0
patches.forEach(function (r) {
var start = r.start + offset
var end = r.end + offset
str = str.slice(0, start) + r.string + str.slice(end)
offset += r.start - r.end + r.string.length
})
return str
}