-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrollup.base.mjs
132 lines (125 loc) · 3.97 KB
/
rollup.base.mjs
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
import { nodeResolve } from '@rollup/plugin-node-resolve';
import { dts } from 'rollup-plugin-dts';
import commonjs from '@rollup/plugin-commonjs';
import swc from '@rollup/plugin-swc';
import { readFileSync } from 'node:fs';
import { basename, dirname, format, parse, relative, resolve } from 'node:path';
const pkg = JSON.parse(readFileSync('./package.json', 'utf-8'));
const cwd = process.cwd();
const deps = new Set([...Object.keys(pkg.dependencies || {}), ...Object.keys(pkg.peerDependencies || {})]);
export default createConfig('build/index.js', { dts: true });
export function createConfig(input, { banner, external = [], dts } = {}) {
const bundles = [bundleJs(input, { banner, external })];
if (dts) {
if (typeof dts === 'boolean') {
dts = format({ ...parse(input), base: undefined, ext: '.d.ts' });
// console.log('dts:', dts);
}
bundles.push(bundleDts(dts));
}
return bundles;
}
export function bundleDts(input) {
const dir = dirname(input) + '/';
const name = basename(input, '.d.ts');
return {
input,
external: createExternalTest(dir),
output: [
{
file: `dist/${name}.d.ts`,
},
],
plugins: [dts({ respectExternal: true })],
};
}
export function bundleJs(input, { banner, external = [] } = {}) {
const dir = dirname(input) + '/';
const name = basename(input, '.js');
return {
input,
external: createExternalTest(dir, external),
output: [
{
file: `dist/${name}.mjs`,
banner,
format: 'es',
sourcemap: true,
generatedCode: 'es2015',
},
{
file: `dist/${name}.cjs`,
banner,
format: 'cjs',
sourcemap: true,
generatedCode: 'es2015',
},
],
plugins: [
nodeResolve(),
commonjs(),
swc({
swc: {
jsc: {
target: 'es2018',
},
},
}),
],
};
}
function createExternalTest(prefix, external = []) {
return (id, parent) => {
// this function decides if a module should be bundled or not (external)
// a module is not bundled if it points to one of our dependencies
// if it's not a dependency but still resolves outside the build/esm dir, an error is thrown
const path = normalizePath(id, parent);
const depId = npmPackage(id);
if (deps.has(depId)) {
console.log('exclude:', path);
return true;
}
if (path.startsWith(pkg.name)) {
console.log('exclude:', path);
return true;
}
if (!path.startsWith(prefix)) {
// this will throw if we accidentally import something that isn't local and wasn't listed among dependencies
throw new Error(`Attempt to bundle external dependency ${path} for import ${id}. Are we missing a dependency?`);
}
if (external.includes(path.slice(prefix.length))) {
console.log('exclude:', path);
return true;
}
// console.log('include:', path);
return false;
};
}
/**
* Return the path relative to cwd for a give import. Npm package imports will be returned as if they were directly in cwd.
*
* @param id the imported path
* @param parent absolute path of the file containing the import, or undefined if it's the entry point
* @returns path relative to cwd
*/
function normalizePath(id, parent = '') {
const absolute = id.startsWith('.') ? resolve(parent, id) : id;
return relative(cwd, absolute);
}
/**
* Return the npm package name of an import, if applicable.
*
* @param id an import path
* @returns the npm package name if id is determined to point to an npm package, '' otherwise.
*/
function npmPackage(id) {
// relative or absolute ids are not npm packages
if (id.startsWith('.') || id.startsWith('/')) return '';
// we're only ever interested in the first two parts the id (the second is needed if the first part specifies a scope)
const parts = id.split('/', 2);
if (parts[0].startsWith('@')) {
// it's a scoped package, so it will include one backslash
return parts.join('/');
}
return parts[0];
}