@hypernym/bundler 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +21 -0
- package/README.md +100 -0
- package/dist/bin/index.mjs +388 -0
- package/dist/index.mjs +12 -0
- package/dist/types/index.d.ts +76 -0
- package/package.json +82 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Ivo Dolenc, Hypernym Studio
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Bundler
|
|
2
|
+
|
|
3
|
+
ESM & TS module bundler.
|
|
4
|
+
|
|
5
|
+
<sub><a href="https://github.com/hypernym-studio/bundler">Repository</a> | <a href="https://www.npmjs.com/package/@hypernym/bundler">Package</a> | <a href="https://github.com/hypernym-studio/bundler/releases">Releases</a> | <a href="https://github.com/hypernym-studio/bundler/discussions">Discussions</a></sub>
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm i -D @hypernym/bundler
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- Powered by Rollup
|
|
14
|
+
- Allows advanced customization
|
|
15
|
+
- Provides a powerful hooking system
|
|
16
|
+
- Exports fully optimized code
|
|
17
|
+
- Follows modern practice
|
|
18
|
+
- Super easy to use
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
1. Create a `bundler.config.ts` file at the root of your project:
|
|
23
|
+
|
|
24
|
+
> **Note**
|
|
25
|
+
> Configuration also accepts `.js`, `.mjs`, `.ts`, `.mts` formats.
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
// bundler.config.ts
|
|
29
|
+
|
|
30
|
+
import { defineConfig } from '@hypernym/bundler'
|
|
31
|
+
|
|
32
|
+
export default defineConfig({
|
|
33
|
+
// ...
|
|
34
|
+
})
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
2. Specify the bundle's entry points:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
// bundler.config.ts
|
|
41
|
+
|
|
42
|
+
import { defineConfig } from '@hypernym/bundler'
|
|
43
|
+
|
|
44
|
+
export default defineConfig({
|
|
45
|
+
entries: [
|
|
46
|
+
{ input: './src/index.ts' },
|
|
47
|
+
{ types: './src/types/index.ts' },
|
|
48
|
+
{
|
|
49
|
+
input: './src/utils/index.ts',
|
|
50
|
+
plugins: {
|
|
51
|
+
esbuild: { minify: true },
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
// ...
|
|
55
|
+
],
|
|
56
|
+
})
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
3. Build via command:
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
npx hyperbundler
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Options
|
|
66
|
+
|
|
67
|
+
### outDir
|
|
68
|
+
|
|
69
|
+
- Type: `string`
|
|
70
|
+
- Default: `dist`
|
|
71
|
+
|
|
72
|
+
Specifies the output directory for production bundle.
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
// bundler.config.ts
|
|
76
|
+
|
|
77
|
+
export default defineConfig({
|
|
78
|
+
outDir: 'output',
|
|
79
|
+
})
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Custom Config
|
|
83
|
+
|
|
84
|
+
Set a custom config path via the CLI command:
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
npx hyperbundler --config my.config.js
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Community
|
|
91
|
+
|
|
92
|
+
Feel free to use the official [discussions](https://github.com/hypernym-studio/bundler/discussions) for any additional questions.
|
|
93
|
+
|
|
94
|
+
## License
|
|
95
|
+
|
|
96
|
+
Developed in ðŸ‡ðŸ‡· Croatia
|
|
97
|
+
|
|
98
|
+
Released under the [MIT](LICENSE.txt) license.
|
|
99
|
+
|
|
100
|
+
© Hypernym Studio
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import process, { stdout, cwd } from 'node:process';
|
|
3
|
+
import { createArgs } from '@hypernym/args';
|
|
4
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
5
|
+
import { resolve, parse } from 'node:path';
|
|
6
|
+
import { exists } from '@hypernym/utils/node';
|
|
7
|
+
import { dim, magenta, red, cyan, green } from '@hypernym/colors';
|
|
8
|
+
import { build as build$1, transform } from 'esbuild';
|
|
9
|
+
import { createSpinner } from '@hypernym/spinner';
|
|
10
|
+
import { isObject } from '@hypernym/utils';
|
|
11
|
+
import { rollup } from 'rollup';
|
|
12
|
+
import { getLogFilter } from 'rollup/getLogFilter';
|
|
13
|
+
import _replace from '@rollup/plugin-replace';
|
|
14
|
+
import _json from '@rollup/plugin-json';
|
|
15
|
+
import _resolve from '@rollup/plugin-node-resolve';
|
|
16
|
+
import { dts } from 'rollup-plugin-dts';
|
|
17
|
+
import { createFilter } from '@rollup/pluginutils';
|
|
18
|
+
|
|
19
|
+
const externals = [
|
|
20
|
+
/^node:/,
|
|
21
|
+
/^@types/,
|
|
22
|
+
/^@rollup/,
|
|
23
|
+
/^@hypernym/,
|
|
24
|
+
/^rollup/
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
const name = "bundler";
|
|
28
|
+
const version = `0.1.0`;
|
|
29
|
+
|
|
30
|
+
const cl = console.log;
|
|
31
|
+
const log = (...args) => {
|
|
32
|
+
let length = args.length + 2;
|
|
33
|
+
const cols = stdout.columns || 80;
|
|
34
|
+
const time = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
35
|
+
for (const arg of args) {
|
|
36
|
+
length = length + arg.replace(/\u001b\[.*?m/g, "").length;
|
|
37
|
+
}
|
|
38
|
+
const repeatLength = cols <= length + time.length ? 0 : cols - (length + time.length);
|
|
39
|
+
return cl(...args, " ".repeat(repeatLength), dim(time));
|
|
40
|
+
};
|
|
41
|
+
const logger = {
|
|
42
|
+
exit: (message) => {
|
|
43
|
+
cl();
|
|
44
|
+
log(dim(name), dim(version));
|
|
45
|
+
log(magenta(name), message);
|
|
46
|
+
cl();
|
|
47
|
+
return process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
function error(err) {
|
|
52
|
+
log(red(name), "Something went wrong...");
|
|
53
|
+
console.error(err);
|
|
54
|
+
return process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function formatMs(ms) {
|
|
58
|
+
const s = 1e3;
|
|
59
|
+
const m = s * 60;
|
|
60
|
+
const h = m * 60;
|
|
61
|
+
const msAbs = Math.abs(ms);
|
|
62
|
+
if (msAbs >= h)
|
|
63
|
+
return `${(ms / h).toFixed(2)}h`;
|
|
64
|
+
if (msAbs >= m)
|
|
65
|
+
return `${(ms / m).toFixed(2)}m`;
|
|
66
|
+
if (msAbs >= s)
|
|
67
|
+
return `${(ms / s).toFixed(2)}s`;
|
|
68
|
+
return `${ms}ms`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function formatBytes(bytes) {
|
|
72
|
+
const decimals = 2;
|
|
73
|
+
const units = ["B", "KB", "MB", "GB", "TB"];
|
|
74
|
+
if (bytes === 0)
|
|
75
|
+
return `0 B`;
|
|
76
|
+
const k = 1024;
|
|
77
|
+
const dm = decimals;
|
|
78
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
79
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${units[i]}`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function getOutputPath(outDir, input, types = false) {
|
|
83
|
+
const _input = input.startsWith("./") ? input.slice(2) : input;
|
|
84
|
+
let output = _input.replace(_input.split("/")[0], outDir);
|
|
85
|
+
const ts = types ? "d.ts" : "mjs";
|
|
86
|
+
const mts = types ? "d.mts" : "mjs";
|
|
87
|
+
const cts = types ? "d.cts" : "cjs";
|
|
88
|
+
if (output.endsWith(".ts"))
|
|
89
|
+
output = `${output.slice(0, -2)}${ts}`;
|
|
90
|
+
if (output.endsWith(".mts"))
|
|
91
|
+
output = `${output.slice(0, -3)}${mts}`;
|
|
92
|
+
if (output.endsWith(".cts"))
|
|
93
|
+
output = `${output.slice(0, -3)}${cts}`;
|
|
94
|
+
if (outDir.startsWith("./") || outDir.startsWith("../"))
|
|
95
|
+
return output;
|
|
96
|
+
return `./${output}`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function loadConfig(filePath, defaults) {
|
|
100
|
+
const result = await build$1({
|
|
101
|
+
entryPoints: [filePath],
|
|
102
|
+
bundle: true,
|
|
103
|
+
write: false,
|
|
104
|
+
format: "esm",
|
|
105
|
+
target: "esnext",
|
|
106
|
+
packages: "external"
|
|
107
|
+
});
|
|
108
|
+
const code = result.outputFiles[0].text;
|
|
109
|
+
const buffer = Buffer.from(code).toString("base64");
|
|
110
|
+
const content = await import(`data:text/javascript;base64,${buffer}`);
|
|
111
|
+
const config = {
|
|
112
|
+
...defaults,
|
|
113
|
+
...content.default
|
|
114
|
+
};
|
|
115
|
+
return config;
|
|
116
|
+
}
|
|
117
|
+
async function createConfigLoader(cwd, args) {
|
|
118
|
+
const pkgPath = resolve(cwd, "package.json");
|
|
119
|
+
const pkg = await readFile(pkgPath, "utf-8").catch(error);
|
|
120
|
+
const { dependencies } = JSON.parse(pkg);
|
|
121
|
+
const warnMessage = `Missing required configuration. To start bundling, add the ${cyan(
|
|
122
|
+
`'bundler.config.{js,mjs,ts,mts}'`
|
|
123
|
+
)} file to the project's root.`;
|
|
124
|
+
const defaults = {
|
|
125
|
+
externals: [...Object.keys(dependencies || {}), ...externals],
|
|
126
|
+
entries: []
|
|
127
|
+
};
|
|
128
|
+
if (args.config) {
|
|
129
|
+
const path = resolve(cwd, args.config);
|
|
130
|
+
const isConfig = await exists(path);
|
|
131
|
+
if (isConfig)
|
|
132
|
+
return await loadConfig(path, defaults);
|
|
133
|
+
else
|
|
134
|
+
return logger.exit(warnMessage);
|
|
135
|
+
}
|
|
136
|
+
const configName = "bundler.config";
|
|
137
|
+
const configExts = [".ts", ".js", ".mts", ".mjs"];
|
|
138
|
+
for (const ext of configExts) {
|
|
139
|
+
const path = resolve(cwd, `${configName}${ext}`);
|
|
140
|
+
const isConfig = await exists(path);
|
|
141
|
+
if (isConfig)
|
|
142
|
+
return await loadConfig(path, defaults);
|
|
143
|
+
}
|
|
144
|
+
return logger.exit(warnMessage);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function esbuild(options) {
|
|
148
|
+
const isJs = /\.(?:[mc]?js|jsx)$/;
|
|
149
|
+
const filter = createFilter(/\.([cm]?ts|[jt]sx)$/);
|
|
150
|
+
return {
|
|
151
|
+
name: "esbuild",
|
|
152
|
+
resolveId(id, importer, options2) {
|
|
153
|
+
if (isJs.test(id) && importer) {
|
|
154
|
+
return this.resolve(id.replace(/js(x?)$/, "ts$1"), importer, options2);
|
|
155
|
+
}
|
|
156
|
+
return null;
|
|
157
|
+
},
|
|
158
|
+
async transform(code, id) {
|
|
159
|
+
if (!filter(id))
|
|
160
|
+
return null;
|
|
161
|
+
const result = await transform(code, {
|
|
162
|
+
loader: "default",
|
|
163
|
+
...options,
|
|
164
|
+
sourcefile: id.replace(/\.[cm]ts/, ".ts")
|
|
165
|
+
});
|
|
166
|
+
return {
|
|
167
|
+
code: result.code,
|
|
168
|
+
map: result.map || null
|
|
169
|
+
};
|
|
170
|
+
},
|
|
171
|
+
async renderChunk(code, { fileName }) {
|
|
172
|
+
if (!options?.minify)
|
|
173
|
+
return null;
|
|
174
|
+
if (/\.d\.(c|m)?tsx?$/.test(fileName))
|
|
175
|
+
return null;
|
|
176
|
+
const result = await transform(code, {
|
|
177
|
+
...options,
|
|
178
|
+
sourcefile: fileName,
|
|
179
|
+
minify: true
|
|
180
|
+
});
|
|
181
|
+
return {
|
|
182
|
+
code: result.code,
|
|
183
|
+
map: result.map || null
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const replacePlugin = _replace.default ?? _replace;
|
|
190
|
+
const jsonPlugin = _json.default ?? _json;
|
|
191
|
+
const resolvePlugin = _resolve.default ?? _resolve;
|
|
192
|
+
async function build(cwd, options) {
|
|
193
|
+
const { outDir = "dist", hooks } = options;
|
|
194
|
+
let start = 0;
|
|
195
|
+
const buildStats = {
|
|
196
|
+
cwd,
|
|
197
|
+
size: 0,
|
|
198
|
+
buildTime: 0,
|
|
199
|
+
files: []
|
|
200
|
+
};
|
|
201
|
+
if (hooks?.["build:before"])
|
|
202
|
+
await hooks["build:before"](options);
|
|
203
|
+
if (options.entries) {
|
|
204
|
+
start = Date.now();
|
|
205
|
+
for (const entry of options.entries) {
|
|
206
|
+
const entryStart = Date.now();
|
|
207
|
+
const logFilter = getLogFilter(entry.logFilter || []);
|
|
208
|
+
if ("input" in entry) {
|
|
209
|
+
const { input, externals, plugins, banner, footer } = entry;
|
|
210
|
+
const buildLogs = [];
|
|
211
|
+
const _output = getOutputPath(outDir, input);
|
|
212
|
+
let _format = "esm";
|
|
213
|
+
if (_output.endsWith(".cjs"))
|
|
214
|
+
_format = "cjs";
|
|
215
|
+
const output = entry.output || _output;
|
|
216
|
+
const format = entry.format || _format;
|
|
217
|
+
const defaultPlugins = [esbuild(plugins?.esbuild)];
|
|
218
|
+
if (plugins?.json) {
|
|
219
|
+
const jsonOptions = isObject(plugins.json) ? plugins.json : void 0;
|
|
220
|
+
defaultPlugins.push(jsonPlugin(jsonOptions));
|
|
221
|
+
}
|
|
222
|
+
if (plugins?.replace) {
|
|
223
|
+
defaultPlugins.unshift(
|
|
224
|
+
replacePlugin({
|
|
225
|
+
true: true,
|
|
226
|
+
...plugins.replace
|
|
227
|
+
})
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
if (plugins?.resolve) {
|
|
231
|
+
const resolveOptions = isObject(plugins.resolve) ? plugins.resolve : void 0;
|
|
232
|
+
defaultPlugins.unshift(resolvePlugin(resolveOptions));
|
|
233
|
+
}
|
|
234
|
+
const builder = await rollup({
|
|
235
|
+
input: resolve(cwd, input),
|
|
236
|
+
external: externals || options.externals,
|
|
237
|
+
plugins: defaultPlugins,
|
|
238
|
+
onLog: (level, log) => {
|
|
239
|
+
if (logFilter(log))
|
|
240
|
+
buildLogs.push({ level, log });
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
await builder.write({
|
|
244
|
+
file: resolve(cwd, output),
|
|
245
|
+
format,
|
|
246
|
+
banner,
|
|
247
|
+
footer
|
|
248
|
+
});
|
|
249
|
+
const stats = await stat(resolve(cwd, output));
|
|
250
|
+
buildStats.files.push({
|
|
251
|
+
path: output,
|
|
252
|
+
size: stats.size,
|
|
253
|
+
buildTime: Date.now() - entryStart,
|
|
254
|
+
format,
|
|
255
|
+
logs: buildLogs
|
|
256
|
+
});
|
|
257
|
+
buildStats.size = buildStats.size + stats.size;
|
|
258
|
+
}
|
|
259
|
+
if ("types" in entry) {
|
|
260
|
+
const { types, plugins } = entry;
|
|
261
|
+
const buildLogs = [];
|
|
262
|
+
const _output = getOutputPath(outDir, types, true);
|
|
263
|
+
let _format = "esm";
|
|
264
|
+
if (_output.endsWith(".d.cts"))
|
|
265
|
+
_format = "cjs";
|
|
266
|
+
const output = entry.output || _output;
|
|
267
|
+
const format = entry.format || _format;
|
|
268
|
+
const builder = await rollup({
|
|
269
|
+
input: resolve(cwd, types),
|
|
270
|
+
plugins: [dts(plugins?.dts)],
|
|
271
|
+
onLog: (level, log) => {
|
|
272
|
+
if (logFilter(log))
|
|
273
|
+
buildLogs.push({ level, log });
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
await builder.write({
|
|
277
|
+
file: resolve(cwd, output),
|
|
278
|
+
format
|
|
279
|
+
});
|
|
280
|
+
const stats = await stat(resolve(cwd, output));
|
|
281
|
+
buildStats.files.push({
|
|
282
|
+
path: output,
|
|
283
|
+
size: stats.size,
|
|
284
|
+
buildTime: Date.now() - entryStart,
|
|
285
|
+
format,
|
|
286
|
+
logs: buildLogs
|
|
287
|
+
});
|
|
288
|
+
buildStats.size = buildStats.size + stats.size;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
buildStats.buildTime = Date.now() - start;
|
|
292
|
+
}
|
|
293
|
+
if (hooks?.["build:done"])
|
|
294
|
+
await hooks["build:done"](options);
|
|
295
|
+
return buildStats;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
async function createBuilder(cwd, args, options) {
|
|
299
|
+
const spinner = createSpinner();
|
|
300
|
+
cl();
|
|
301
|
+
log(dim(name), dim(version));
|
|
302
|
+
log(cyan(name), `Bundling started...`);
|
|
303
|
+
spinner.start({
|
|
304
|
+
message: `Transforming modules ${green("for production...")}`
|
|
305
|
+
});
|
|
306
|
+
return await build(cwd, options).then((stats) => {
|
|
307
|
+
spinner.stop({
|
|
308
|
+
message: `Modules transformation is ${green("done!")}`,
|
|
309
|
+
template: (mark, message) => {
|
|
310
|
+
const temp = `${mark}${message}`;
|
|
311
|
+
const cols = stdout.columns || 80;
|
|
312
|
+
const time = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
313
|
+
const length = (
|
|
314
|
+
// eslint-disable-next-line no-control-regex
|
|
315
|
+
temp.replace(/\u001b\[.*?m/g, "").length + time.length + 1
|
|
316
|
+
);
|
|
317
|
+
const repeatLength = cols <= length ? 0 : cols - length;
|
|
318
|
+
return temp + " ".repeat(repeatLength) + dim(time);
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
const check = green("\u2714");
|
|
322
|
+
const info = cyan("i");
|
|
323
|
+
const buildTime = green(formatMs(stats.buildTime));
|
|
324
|
+
const buildSize = green(formatBytes(stats.size));
|
|
325
|
+
const modules = green(stats.files.length);
|
|
326
|
+
const longestPath = Math.max(...stats.files.map((v) => v.path.length + 1));
|
|
327
|
+
const longestTime = Math.max(
|
|
328
|
+
...stats.files.map((v) => formatMs(v.buildTime).length)
|
|
329
|
+
);
|
|
330
|
+
const longestSize = Math.max(
|
|
331
|
+
...stats.files.map((v) => formatBytes(v.size).length)
|
|
332
|
+
);
|
|
333
|
+
log(check, `Bundling completed in ${buildTime}`);
|
|
334
|
+
log(check, `${modules} modules transformed. Total size is ${buildSize}`);
|
|
335
|
+
log(info, "Individual stats per module");
|
|
336
|
+
for (const file of stats.files) {
|
|
337
|
+
let format = file.format;
|
|
338
|
+
const base = parse(file.path).base;
|
|
339
|
+
const path = file.path.replace(base, "");
|
|
340
|
+
if (format.includes("system"))
|
|
341
|
+
format = "sys";
|
|
342
|
+
if (format === "commonjs")
|
|
343
|
+
format = "cjs";
|
|
344
|
+
if (format === "module")
|
|
345
|
+
format = "esm";
|
|
346
|
+
if (base.includes(".d."))
|
|
347
|
+
format = "dts";
|
|
348
|
+
if (file.logs) {
|
|
349
|
+
for (const log2 of file.logs) {
|
|
350
|
+
cl(magenta("!"), magenta(log2.log.message));
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
log(
|
|
354
|
+
info,
|
|
355
|
+
dim("\u251C\u2500"),
|
|
356
|
+
dim(path) + cyan(base),
|
|
357
|
+
" ".padEnd(longestPath - (path.length + base.length)),
|
|
358
|
+
dim(format.padStart(5)),
|
|
359
|
+
dim("\u2502"),
|
|
360
|
+
dim(formatMs(file.buildTime).padStart(longestTime)),
|
|
361
|
+
dim("\u2502"),
|
|
362
|
+
dim(formatBytes(file.size).padStart(longestSize))
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
log(
|
|
366
|
+
check,
|
|
367
|
+
`Bundle is now fully generated and ready ${green("for production!")}`
|
|
368
|
+
);
|
|
369
|
+
}).catch((err) => {
|
|
370
|
+
spinner.stop({
|
|
371
|
+
mark: red("\u2716"),
|
|
372
|
+
message: `Modules transformation is ${red("interupted!")}`
|
|
373
|
+
});
|
|
374
|
+
log(red(name), "Something went wrong...");
|
|
375
|
+
console.error(err);
|
|
376
|
+
return process.exit(1);
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
async function main() {
|
|
381
|
+
const cwd$1 = cwd();
|
|
382
|
+
const args = createArgs({
|
|
383
|
+
alias: { config: "c" }
|
|
384
|
+
});
|
|
385
|
+
const config = await createConfigLoader(cwd$1, args);
|
|
386
|
+
await createBuilder(cwd$1, args, config);
|
|
387
|
+
}
|
|
388
|
+
main().catch(error);
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { OutputOptions } from 'rollup';
|
|
2
|
+
import { RollupReplaceOptions } from '@rollup/plugin-replace';
|
|
3
|
+
import { RollupJsonOptions } from '@rollup/plugin-json';
|
|
4
|
+
import { RollupNodeResolveOptions } from '@rollup/plugin-node-resolve';
|
|
5
|
+
import { TransformOptions } from 'esbuild';
|
|
6
|
+
import { Options as Options$1 } from 'rollup-plugin-dts';
|
|
7
|
+
|
|
8
|
+
interface BuildPlugins {
|
|
9
|
+
esbuild?: TransformOptions;
|
|
10
|
+
dts?: Options$1;
|
|
11
|
+
resolve?: RollupNodeResolveOptions | true;
|
|
12
|
+
json?: RollupJsonOptions | true;
|
|
13
|
+
replace?: RollupReplaceOptions;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface Entries {
|
|
17
|
+
output?: string;
|
|
18
|
+
format?: OutputOptions['format'];
|
|
19
|
+
externals?: (string | RegExp)[];
|
|
20
|
+
logFilter?: string[];
|
|
21
|
+
}
|
|
22
|
+
interface EntriesInput extends Entries {
|
|
23
|
+
input: string;
|
|
24
|
+
banner?: OutputOptions['banner'];
|
|
25
|
+
footer?: OutputOptions['footer'];
|
|
26
|
+
plugins?: BuildPlugins;
|
|
27
|
+
}
|
|
28
|
+
interface EntriesTypes extends Entries {
|
|
29
|
+
types: string;
|
|
30
|
+
plugins?: Pick<BuildPlugins, 'dts'>;
|
|
31
|
+
}
|
|
32
|
+
type EntriesOptions = EntriesInput | EntriesTypes;
|
|
33
|
+
|
|
34
|
+
interface BuildHooks {
|
|
35
|
+
/**
|
|
36
|
+
* Called just before bundling started.
|
|
37
|
+
*/
|
|
38
|
+
'build:before'?: (options?: Options) => void | Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Called right after bundling is complete.
|
|
41
|
+
*/
|
|
42
|
+
'build:done'?: (options?: Options) => void | Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
interface Options {
|
|
46
|
+
/**
|
|
47
|
+
* Specifies the bundle's entry points.
|
|
48
|
+
*
|
|
49
|
+
* It allows you to manually set all build entries and adjust options for each one individually.
|
|
50
|
+
*/
|
|
51
|
+
entries: EntriesOptions[];
|
|
52
|
+
/**
|
|
53
|
+
* Specifies the output directory for production bundle.
|
|
54
|
+
*
|
|
55
|
+
* @default 'dist'
|
|
56
|
+
*/
|
|
57
|
+
outDir?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Specifies the module IDs, or regular expressions to match module IDs,
|
|
60
|
+
* that should remain external to the bundle.
|
|
61
|
+
*
|
|
62
|
+
* @default [/^node:/, /^@types/, /^@rollup/, /^@hypernym/, /^rollup/, ...pkg.dependencies]
|
|
63
|
+
*/
|
|
64
|
+
externals?: (string | RegExp)[];
|
|
65
|
+
/**
|
|
66
|
+
* Provides a powerful hooking system to further expand build mode.
|
|
67
|
+
*
|
|
68
|
+
* @default undefined
|
|
69
|
+
*/
|
|
70
|
+
hooks?: BuildHooks;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
declare const externals: RegExp[];
|
|
74
|
+
declare function defineConfig(options: Options): Options;
|
|
75
|
+
|
|
76
|
+
export { defineConfig, externals };
|
package/package.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hypernym/bundler",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"author": "Hypernym Studio",
|
|
5
|
+
"description": "ESM & TS module bundler.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": "hypernym-studio/bundler",
|
|
8
|
+
"homepage": "https://github.com/hypernym-studio/bundler",
|
|
9
|
+
"funding": "https://github.com/sponsors/ivodolenc",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/types/index.d.ts",
|
|
14
|
+
"import": "./dist/index.mjs"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"keywords": [
|
|
21
|
+
"module",
|
|
22
|
+
"modules",
|
|
23
|
+
"bundling",
|
|
24
|
+
"javascript",
|
|
25
|
+
"typescript",
|
|
26
|
+
"bundler",
|
|
27
|
+
"builder",
|
|
28
|
+
"package",
|
|
29
|
+
"bundle",
|
|
30
|
+
"types",
|
|
31
|
+
"build",
|
|
32
|
+
"esm",
|
|
33
|
+
"dts"
|
|
34
|
+
],
|
|
35
|
+
"bin": {
|
|
36
|
+
"hyperbundler": "./dist/bin/index.mjs"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsx src/bin/index.ts",
|
|
40
|
+
"lint": "ESLINT_USE_FLAT_CONFIG=true eslint -c .config/eslint.config.js .",
|
|
41
|
+
"lint:fix": "ESLINT_USE_FLAT_CONFIG=true eslint -c .config/eslint.config.js --fix .",
|
|
42
|
+
"format": "prettier --config .config/prettier.config.js --write .",
|
|
43
|
+
"prepublishOnly": "npm run build"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"@types/node": ">=20.0.0",
|
|
47
|
+
"typescript": ">=5.0.0"
|
|
48
|
+
},
|
|
49
|
+
"peerDependenciesMeta": {
|
|
50
|
+
"@types/node": {
|
|
51
|
+
"optional": true
|
|
52
|
+
},
|
|
53
|
+
"typescript": {
|
|
54
|
+
"optional": true
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@hypernym/args": "^0.2.0",
|
|
59
|
+
"@hypernym/colors": "^1.0.0",
|
|
60
|
+
"@hypernym/spinner": "^0.1.0",
|
|
61
|
+
"@hypernym/utils": "^2.0.2",
|
|
62
|
+
"@rollup/plugin-json": "^6.0.1",
|
|
63
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
64
|
+
"@rollup/plugin-replace": "^5.0.3",
|
|
65
|
+
"esbuild": "^0.19.4",
|
|
66
|
+
"rollup": "^4.0.2",
|
|
67
|
+
"rollup-plugin-dts": "^6.1.0"
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@hypernym/eslint-config": "^2.0.1",
|
|
71
|
+
"@hypernym/prettier-config": "^2.0.1",
|
|
72
|
+
"@hypernym/tsconfig": "^1.1.0",
|
|
73
|
+
"@types/node": "^20.8.4",
|
|
74
|
+
"eslint": "^8.51.0",
|
|
75
|
+
"prettier": "^3.0.3",
|
|
76
|
+
"tsx": "^3.13.0",
|
|
77
|
+
"typescript": "^5.2.2"
|
|
78
|
+
},
|
|
79
|
+
"engines": {
|
|
80
|
+
"node": ">=v18.0.0"
|
|
81
|
+
}
|
|
82
|
+
}
|