/
generate-esm.ts
78 lines (69 loc) · 1.95 KB
/
generate-esm.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
import { makeLegalIdentifier } from '@rollup/pluginutils';
type ImportSpecifiers = Record<string /* exportName */, string /* importAs */>;
export type Imports = Map<string /* filePath */, ImportSpecifiers>;
export type Exports = Record<string, {
code: string;
resolved: string;
exportAs: Set<string>;
}>;
const importStatement = (
specifiers: string,
source: string,
) => `import${specifiers ? `{${specifiers}}from` : ''}${JSON.stringify(source)};`;
const importsToCode = (
imports: Imports,
) => (
Array.from(imports)
.map(
([file, importedAs]) => importStatement(
Object.entries(importedAs).map(
([exportName, importAs]) => `${JSON.stringify(exportName)} as ${importAs}`,
).join(','),
`${file}?.module.css`,
),
)
.join('')
);
const exportsToCode = (
exports: Exports,
) => {
const variables = new Set<string>();
const exportedVariables = Object.entries(exports).flatMap(
([exportName, { exportAs, code: value }]) => {
const jsVariable = makeLegalIdentifier(exportName);
variables.add(`const ${jsVariable} = \`${value}\`;`);
return Array.from(exportAs).map((exportAsName) => {
const exportNameSafe = makeLegalIdentifier(exportAsName);
if (exportAsName !== exportNameSafe) {
exportAsName = JSON.stringify(exportAsName);
}
return [jsVariable, exportAsName] as const;
});
},
);
const namedExports = `export {${
exportedVariables
.map(
([jsVariable, exportName]) => (
jsVariable === exportName
? jsVariable
: `${jsVariable} as ${exportName}`
),
)
.join(',')
}};`;
const defaultExports = `export default{${
exportedVariables.map(
([jsVariable, exportName]) => (
jsVariable === exportName
? jsVariable
: `${exportName}: ${jsVariable}`
),
).join(',')
}}`;
return `${Array.from(variables).join('')}${namedExports}${defaultExports}`;
};
export const generateEsm = (
imports: Imports,
exports: Exports,
) => importsToCode(imports) + exportsToCode(exports);