-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
rollup.config.js
160 lines (147 loc) · 4.77 KB
/
rollup.config.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
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// @ts-check
import fs from 'node:fs';
import path from 'node:path';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import dynamicImportVars from '@rollup/plugin-dynamic-import-vars';
import { preserveShebangs } from 'rollup-plugin-preserve-shebangs';
import dts from 'unplugin-isolated-decl/rollup';
import esbuild from 'rollup-plugin-esbuild';
import { buildTemplates } from '@sveltejs/create/build';
import MagicString from 'magic-string';
/** @import { Package } from "./packages/cli/commands/add/utils" */
/** @import { Plugin, RollupOptions } from "rollup" */
/** @typedef {Package & { peerDependencies: Record<string, string> }} PackageJson */
/**
* @param {string} project
* @returns {RollupOptions}
*/
function getConfig(project) {
const projectRoot = `./packages/${project}`;
const outDir = `${projectRoot}/dist`;
/** @type {RollupOptions["input"]} */
let inputs;
if (project === 'core') {
inputs = {
index: `${projectRoot}/index.ts`,
css: `${projectRoot}/tooling/css/index.ts`,
html: `${projectRoot}/tooling/html/index.ts`,
js: `${projectRoot}/tooling/js/index.ts`,
parsers: `${projectRoot}/tooling/parsers.ts`
};
} else if (project === 'cli') {
inputs = [
`${projectRoot}/lib/index.ts`,
`${projectRoot}/lib/testing.ts`,
`${projectRoot}/bin.ts`
];
} else {
inputs = [`${projectRoot}/index.ts`];
}
fs.rmSync(outDir, { force: true, recursive: true });
/** @type {PackageJson} */
const pkg = JSON.parse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf8'));
const externalDeps = getExternalDeps(pkg);
// always externalizes `@sveltejs/cli-core` and any deps that are `dependencies` or `peerDependencies`
const external = [...externalDeps];
/** @type {Plugin | undefined} */
let buildCliTemplatesPlugin;
if (project === 'create') {
// This plugin is used to build the templates and place them inside the
// `dist` folder after every rollup build. This is necessary as we're
// clearing the output directory and thus also removes the template files
buildCliTemplatesPlugin = {
name: 'build-cli-templates',
buildStart() {
const templates = getFilePaths('packages', 'create', 'templates');
const shared = getFilePaths('packages', 'create', 'shared');
for (const file of shared.concat(templates)) {
this.addWatchFile(file);
}
},
async writeBundle() {
console.log('building templates');
const start = performance.now();
await buildTemplates(path.resolve('packages', 'cli', 'dist'));
await buildTemplates(path.resolve('packages', 'create', 'dist'));
const end = performance.now();
console.log(`finished building templates: ${Math.round(end - start)}ms`);
}
};
}
/** @type {Plugin | undefined} */
let communityAddonIdsPlugin;
if (project === 'cli') {
// Evaluates the ids of available community addons at build time
communityAddonIdsPlugin = {
name: 'evaluate-community-addon-ids',
transform(code, id) {
if (id.endsWith(`_config${path.sep}community.ts`)) {
const ms = new MagicString(code, { filename: id });
const start = code.indexOf('export const communityAddonIds');
const end = code.indexOf(';', start);
const ids = fs.readdirSync('community-addons').map((p) => path.parse(p).name);
const generated = `export const communityAddonIds = ${JSON.stringify(ids)};`;
ms.overwrite(start, end, generated);
return {
code: ms.toString(),
map: ms.generateMap()
};
}
}
};
}
return {
input: inputs,
output: {
dir: outDir,
format: 'esm',
sourcemap: true
},
external,
plugins: [
preserveShebangs(),
'exports' in pkg &&
dts({ include: project === 'cli' ? [`${projectRoot}/lib/*`] : undefined }),
esbuild(),
nodeResolve({ preferBuiltins: true, rootDir: projectRoot }),
commonjs(),
json(),
dynamicImportVars({
// since we're relying on the usage of standard dynamic imports for community addons, we need to
// prevent this plugin from transforming these cases
exclude: ['packages/cli/commands/add/fetch-packages.ts']
}),
buildCliTemplatesPlugin,
communityAddonIdsPlugin
]
};
}
/** @type {RollupOptions[]} */
export default [
getConfig('clack-core'),
getConfig('clack-prompts'),
getConfig('ast-tooling'),
getConfig('create'),
getConfig('core'),
getConfig('cli')
];
/**
* @param {PackageJson} pkg
* @returns {Set<string>}
*/
function getExternalDeps(pkg) {
return new Set([
...Object.keys(pkg.dependencies ?? {}),
...Object.keys(pkg.peerDependencies ?? {})
]);
}
/**
* @param {string[]} paths
* @returns {string[]}
*/
function getFilePaths(...paths) {
const dir = path.resolve(...paths);
return fs.readdirSync(dir, { withFileTypes: true }).map((f) => path.join(f.parentPath, f.name));
}