Skip to content

Commit 02d1c87

Browse files
committed
refactor(compartment-mapper): refactor bundler to produce less output
1 parent 037be50 commit 02d1c87

File tree

6 files changed

+262
-101
lines changed

6 files changed

+262
-101
lines changed

packages/compartment-mapper/scripts/bundle-live-test.js

+6
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,11 @@ const readPowers = makeReadPowers({ fs, url });
1515
const bundle = await makeBundle(readPowers.read, fixture);
1616
fs.writeFileSync(url.fileURLToPath(target), bundle);
1717

18+
console.log(`
19+
#######################
20+
size: ${bundle.length}
21+
`);
22+
23+
// eslint-disable-next-line no-undef
1824
global.print = console.log;
1925
import(target);

packages/compartment-mapper/src/bundle-cjs.js

+9-21
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,7 @@
1-
/** quotes strings */
2-
const q = JSON.stringify;
3-
4-
const exportsCellRecord = exportsList =>
5-
''.concat(
6-
...exportsList.map(
7-
exportName => `\
8-
${exportName}: cell(${q(exportName)}),
9-
`,
10-
),
11-
);
12-
1+
// vvv runtime to inline in the bundle vvv
2+
/* eslint-disable no-undef */
133
// This function is serialized and references variables from its destination scope.
14-
const runtime = function wrapCjsFunctor(num) {
15-
/* eslint-disable no-undef */
4+
function wrapCjsFunctor(num) {
165
return ({ imports = {} }) => {
176
const cModule = Object.freeze(
187
Object.defineProperty({}, 'exports', cells[num].default),
@@ -24,8 +13,11 @@ const runtime = function wrapCjsFunctor(num) {
2413
.filter(k => k !== 'default' && k !== '*')
2514
.map(k => cells[num][k].set(cModule.exports[k]));
2615
};
27-
/* eslint-enable no-undef */
28-
}.toString();
16+
}
17+
/* eslint-enable no-undef */
18+
const runtime = `\
19+
${wrapCjsFunctor}`;
20+
// ^^^ runtime to inline in the bundle ^^^
2921

3022
export default {
3123
runtime,
@@ -41,11 +33,7 @@ export default {
4133
// === functors[${index}] ===
4234
${cjsFunctor},
4335
`,
44-
getCells: () => `\
45-
{
46-
${exportsCellRecord(exportsList)}\
47-
},
48-
`,
36+
getCells: () => exportsList,
4937
getReexportsWiring: () => '',
5038
getFunctorCall: () => `\
5139
wrapCjsFunctor(${index})({imports: ${importsMap}});

packages/compartment-mapper/src/bundle-json.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ export default {
66
// === functors[${index}] ===
77
${sourceText},
88
`,
9-
getCells: () => `\
10-
{ default: cell('default') },
11-
`,
9+
getCells: () => ['default'],
1210
getReexportsWiring: () => '',
1311
getFunctorCall: () => `\
1412
cells[${index}].default.set(functors[${index}]);

packages/compartment-mapper/src/bundle-mjs.js

+56-50
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
11
/** quotes strings */
22
const q = JSON.stringify;
33

4-
const exportsCellRecord = exportMap =>
5-
''.concat(
6-
...Object.keys(exportMap).map(
7-
exportName => `\
8-
${exportName}: cell(${q(exportName)}),
9-
`,
10-
),
11-
);
12-
134
const importsCellSetter = (exportMap, index) =>
145
''.concat(
156
...Object.entries(exportMap).map(
@@ -19,31 +10,56 @@ const importsCellSetter = (exportMap, index) =>
1910
),
2011
);
2112

22-
const adaptReexport = reexportMap => {
13+
const importImplementation = indexedImports => {
14+
const knownEntries = Object.entries(indexedImports);
15+
if (knownEntries.length === 0) {
16+
return `imports() {},`;
17+
}
18+
return `\
19+
imports(entries) {
20+
const map = new Map(entries);
21+
observeImports(map, [
22+
${''.concat(
23+
...knownEntries.map(
24+
([importName, importIndex]) => `\
25+
[${q(importName)}, ${importIndex}],
26+
`,
27+
),
28+
)}\
29+
]);},`;
30+
};
31+
32+
const getReexportKeys = reexportMap => {
2333
if (!reexportMap) {
2434
return {};
2535
}
26-
const ret = Object.fromEntries(
27-
Object.values(reexportMap)
28-
.flat()
29-
.map(([local, exported]) => [exported, [local]]),
30-
);
31-
return ret;
36+
return Object.values(reexportMap)
37+
.flat()
38+
.map(([local, _exported]) => local);
3239
};
3340

34-
export const runtime = `\
35-
function observeImports(map, importName, importIndex) {
36-
for (const [name, observers] of map.get(importName)) {
37-
const cell = cells[importIndex][name];
38-
if (cell === undefined) {
39-
throw new ReferenceError(\`Cannot import name \${name}\`);
40-
}
41-
for (const observer of observers) {
42-
cell.observe(observer);
41+
// vvv runtime to inline in the bundle vvv
42+
/* eslint-disable no-undef */
43+
function observeImports(map, pairs) {
44+
for (const [importName, importIndex] of pairs) {
45+
for (const [name, observers] of map.get(importName)) {
46+
const cell = cells[importIndex][name];
47+
if (cell === undefined) {
48+
throw new ReferenceError(`Cannot import name ${name}`);
49+
}
50+
for (const observer of observers) {
51+
cell.observe(observer);
52+
}
4353
}
4454
}
4555
}
46-
`;
56+
57+
/* eslint-enable no-undef */
58+
59+
const runtime = `\
60+
${observeImports}
61+
${observeImports}`;
62+
// ^^^ runtime to inline in the bundle ^^^
4763

4864
export default {
4965
runtime,
@@ -55,6 +71,7 @@ export default {
5571
__fixedExportMap__ = {},
5672
__liveExportMap__ = {},
5773
__reexportMap__ = {},
74+
__needsImportMeta__ = false,
5875
reexports,
5976
},
6077
}) {
@@ -63,19 +80,17 @@ export default {
6380
// === functors[${index}] ===
6481
${__syncModuleProgram__},
6582
`,
66-
getCells: () => `\
67-
{
68-
${exportsCellRecord(__fixedExportMap__)}${exportsCellRecord(
69-
__liveExportMap__,
70-
)}${exportsCellRecord(adaptReexport(__reexportMap__))}\
71-
},
72-
`,
83+
getCells: () => [
84+
...Object.keys(__fixedExportMap__),
85+
...Object.keys(__liveExportMap__),
86+
...getReexportKeys(__reexportMap__),
87+
],
88+
reexportedCells: reexports.map(importSpecifier => [
89+
index,
90+
indexedImports[importSpecifier],
91+
]),
7392
getReexportsWiring: () => {
74-
const mappings = reexports.map(
75-
importSpecifier => `\
76-
Object.defineProperties(cells[${index}], Object.getOwnPropertyDescriptors(cells[${indexedImports[importSpecifier]}]));
77-
`,
78-
);
93+
const mappings = [];
7994
// Create references for export name as newname
8095
const namedReexportsToProcess = Object.entries(__reexportMap__);
8196
if (namedReexportsToProcess.length > 0) {
@@ -96,23 +111,14 @@ ${exportsCellRecord(__fixedExportMap__)}${exportsCellRecord(
96111
},
97112
getFunctorCall: () => `\
98113
functors[${index}]({
99-
imports(entries) {
100-
const map = new Map(entries);
101-
${''.concat(
102-
...Object.entries(indexedImports).map(
103-
([importName, importIndex]) => `\
104-
observeImports(map, ${q(importName)}, ${importIndex});
105-
`,
106-
),
107-
)}\
108-
},
114+
${importImplementation(indexedImports)}
109115
liveVar: {
110116
${importsCellSetter(__liveExportMap__, index)}\
111117
},
112118
onceVar: {
113119
${importsCellSetter(__fixedExportMap__, index)}\
114-
},
115-
importMeta: {},
120+
},\
121+
${__needsImportMeta__ ? '\n importMeta: {},' : ''}
116122
});
117123
`,
118124
};

packages/compartment-mapper/src/bundle.js

+58-27
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,10 @@ const sortedModules = (
7979
);
8080
}
8181
if (record) {
82-
const { imports = [], reexports = [] } =
83-
/** @type {PrecompiledStaticModuleInterface} */ (record);
82+
const {
83+
imports = [],
84+
reexports = [],
85+
} = /** @type {PrecompiledStaticModuleInterface} */ (record);
8486
const resolvedImports = Object.create(null);
8587
for (const importSpecifier of [...imports, ...reexports]) {
8688
const resolvedSpecifier = resolve(importSpecifier, moduleSpecifier);
@@ -149,6 +151,49 @@ function getBundlerKitForModule(module) {
149151
return getBundlerKit(module);
150152
}
151153

154+
// vvv runtime to inline in the bundle vvv
155+
/* eslint-disable no-undef */
156+
function cell(name, value = undefined) {
157+
const observers = [];
158+
return Object.freeze({
159+
get: Object.freeze(() => {
160+
return value;
161+
}),
162+
set: Object.freeze(newValue => {
163+
value = newValue;
164+
for (const observe of observers) {
165+
observe(value);
166+
}
167+
}),
168+
observe: Object.freeze(observe => {
169+
observers.push(observe);
170+
observe(value);
171+
}),
172+
enumerable: true,
173+
});
174+
}
175+
function makeCells(orderedCells, reexports) {
176+
const cells = orderedCells.map(cs =>
177+
cs.reduce((kv, c) => {
178+
kv[c] = cell(c);
179+
return kv;
180+
}, {}),
181+
);
182+
for (const [to, from] of reexports) {
183+
Object.defineProperties(
184+
cells[to],
185+
Object.getOwnPropertyDescriptors(cells[from]),
186+
);
187+
}
188+
return cells;
189+
}
190+
/* eslint-enable no-undef */
191+
const runtime = `\
192+
${cell}
193+
${makeCells}`;
194+
195+
// ^^^ runtime to inline in the bundle ^^^
196+
152197
/**
153198
* @param {ReadFn} read
154199
* @param {string} moduleLocation
@@ -251,29 +296,17 @@ export const makeBundle = async (read, moduleLocation, options) => {
251296
${''.concat(...modules.map(m => m.bundlerKit.getFunctor()))}\
252297
]; // functors end
253298
254-
const cell = (name, value = undefined) => {
255-
const observers = [];
256-
return Object.freeze({
257-
get: Object.freeze(() => {
258-
return value;
259-
}),
260-
set: Object.freeze((newValue) => {
261-
value = newValue;
262-
for (const observe of observers) {
263-
observe(value);
264-
}
265-
}),
266-
observe: Object.freeze((observe) => {
267-
observers.push(observe);
268-
observe(value);
269-
}),
270-
enumerable: true,
271-
});
272-
};
273-
274-
const cells = [
275-
${''.concat(...modules.map(m => m.bundlerKit.getCells()))}\
276-
];
299+
//runtime
300+
${''.concat(
301+
runtime,
302+
...Array.from(parsersInUse).map(parser => getRuntime(parser)),
303+
)}
304+
// runtime end
305+
const cells = makeCells(
306+
${JSON.stringify([...modules.map(m => m.bundlerKit.getCells())], null, 2)},
307+
/* export * from */
308+
${JSON.stringify(modules.flatMap(m => m.bundlerKit.reexportedCells || []))}
309+
);
277310
278311
${''.concat(...modules.map(m => m.bundlerKit.getReexportsWiring()))}\
279312
@@ -283,8 +316,6 @@ ${''.concat(...modules.map(m => m.bundlerKit.getReexportsWiring()))}\
283316
cells[index]['*'] = cell('*', namespaces[index]);
284317
}
285318
286-
${''.concat(...Array.from(parsersInUse).map(parser => getRuntime(parser)))}
287-
288319
${''.concat(...modules.map(m => m.bundlerKit.getFunctorCall()))}\
289320
290321
return cells[cells.length - 1]['*'].get();

0 commit comments

Comments
 (0)