susee 2.2.4 → 2.3.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/README.md +42 -8
- package/dist/cli/index.mjs +181 -66
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.cjs +60 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.mts +3 -2
- package/dist/index.mjs +61 -32
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -7
package/README.md
CHANGED
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
[![NPM][nodei_img]][nodei_url]
|
|
11
11
|
|
|
12
12
|
[![npm version][npm_v_img]][npm_v_url] [![license][license_img]](LICENSE) [](https://www.bestpractices.dev/projects/13115) [](https://www.bestpractices.dev/projects/13115)
|
|
13
|
-
|
|
13
|
+
> [!IMPORTANT]
|
|
14
|
+
> Use **susee v2.3.0 or above**. The core bundler was ported to Rust in v2.3.0, fixing multiple bugs present in earlier versions. Older versions are no longer recommended.
|
|
14
15
|
## Overview
|
|
15
16
|
|
|
16
17
|
`susee` is a **TypeScript-first bundler** powered by `oxc`, specialized for library packages. Unlike general-purpose bundlers, `susee` focuses on consolidating a package's local TypeScript dependency tree into consolidated source units and compiling them into dual-format artifacts (ESM and CommonJS).
|
|
@@ -91,6 +92,8 @@ Susee reads your config, bundles each entry point, compiles to ESM and/or Common
|
|
|
91
92
|
```
|
|
92
93
|
susee build Build using susee.config.{ts,js,mjs}
|
|
93
94
|
susee init Generate susee.config.{ts,js,mjs}
|
|
95
|
+
susee check Run lint checks on a dependency tree without bundling
|
|
96
|
+
susee bundle <entry> [options] Bundle a single entry file to disk without compiling
|
|
94
97
|
susee --version / -v Print version
|
|
95
98
|
susee --help / -h Show help
|
|
96
99
|
susee build <entry> [options] Build from a single entry file
|
|
@@ -102,12 +105,16 @@ susee build <entry> [options] Build from a single entry file
|
|
|
102
105
|
|------|------|---------|-------------|
|
|
103
106
|
| `--entry <path>` | string | — | Entry file (optional if given positionally) |
|
|
104
107
|
| `--outdir <path>` | string | `dist` | Output directory |
|
|
105
|
-
| `--format` | `cjs\|commonjs\|esm` | `esm` | Output module format |
|
|
108
|
+
| `--format` | `cjs\|commonjs\|esm\|both` | `esm` | Output module format (`both` = CJS + ESM) |
|
|
106
109
|
| `--tsconfig <path>` | string | `undefined` | Custom tsconfig path |
|
|
107
110
|
| `--allow-update[=true\|false]` | boolean | `false` | Allow `package.json` updates |
|
|
108
111
|
| `--minify[=true\|false]` | boolean | `false` | Minify output JS |
|
|
109
112
|
| `--check[=true\|false]` | boolean | `false` | Run bundler lint checks |
|
|
110
113
|
|
|
114
|
+
### Bundle Flags
|
|
115
|
+
|
|
116
|
+
The `susee bundle` command writes the bundled source (before TypeScript compilation) to disk. It supports `--entry`, `--outdir`, and `--check[=true|false]`.
|
|
117
|
+
|
|
111
118
|
Flags accept both `--flag=value` and `--flag value` syntax.
|
|
112
119
|
|
|
113
120
|
### Examples
|
|
@@ -115,12 +122,18 @@ Flags accept both `--flag=value` and `--flag value` syntax.
|
|
|
115
122
|
```sh
|
|
116
123
|
npx susee build src/index.ts --outdir dist
|
|
117
124
|
npx susee build src/index.ts --format commonjs
|
|
125
|
+
npx susee build src/index.ts --format both # emit CJS + ESM
|
|
118
126
|
npx susee build --entry src/index.ts --format esm --tsconfig tsconfig.build.json
|
|
119
127
|
npx susee build src/index.ts --minify
|
|
128
|
+
npx susee build src/index.ts --check # run lint checks during build
|
|
129
|
+
npx susee bundle src/index.ts --outdir bundled # write bundled source only
|
|
130
|
+
npx susee check # lint the dependency tree from config
|
|
120
131
|
```
|
|
121
132
|
|
|
122
133
|
## Programmatic API
|
|
123
134
|
|
|
135
|
+
### `build()`
|
|
136
|
+
|
|
124
137
|
```ts
|
|
125
138
|
import { build, type SuSeeConfig } from "susee";
|
|
126
139
|
|
|
@@ -137,6 +150,26 @@ await build(config);
|
|
|
137
150
|
|
|
138
151
|
`build()` resolves options from the argument first, then from a root config file. If neither is available it logs an error and exits with code 1.
|
|
139
152
|
|
|
153
|
+
### `suseeBundle()`
|
|
154
|
+
|
|
155
|
+
Bundle a single entry point into a consolidated source string without compiling or writing to disk:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
import { suseeBundle, type CheckOptions } from "susee";
|
|
159
|
+
|
|
160
|
+
const code: string = suseeBundle("src/index.ts");
|
|
161
|
+
|
|
162
|
+
// with lint checks enabled
|
|
163
|
+
const checks: CheckOptions = {
|
|
164
|
+
checkAnonymous: true,
|
|
165
|
+
checkDefaultExports: true,
|
|
166
|
+
checkNpmInstalled: true,
|
|
167
|
+
};
|
|
168
|
+
const checked = suseeBundle("src/index.ts", checks);
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
`suseeBundle()` runs the oxc-powered bundler over the entry's local dependency tree and returns the bundled source. When `CheckOptions` are provided the bundler runs diagnostics (anonymous declarations, default exports, npm-installed deps) before returning.
|
|
172
|
+
|
|
140
173
|
## How It Works
|
|
141
174
|
|
|
142
175
|
```mermaid
|
|
@@ -172,13 +205,14 @@ The pipeline bundles each entry point's local dependency tree into a single sour
|
|
|
172
205
|
|
|
173
206
|
```
|
|
174
207
|
src/
|
|
175
|
-
├── index.ts # Public API — re-exports build
|
|
208
|
+
├── index.ts # Public API — re-exports build, suseeBundle, SuSeeConfig, CheckOptions
|
|
176
209
|
├── build.ts # Build orchestrator — resolves config, runs Compiler
|
|
177
|
-
├── bundler.ts # Wrapper around @suseejs/susee_bundler (oxc)
|
|
210
|
+
├── bundler.ts # Wrapper around @suseejs/susee_bundler (oxc) + CLI bundle writer
|
|
178
211
|
├── cli/
|
|
179
|
-
│ ├── index.ts # CLI entrypoint & command dispatch
|
|
180
|
-
│ ├── parse_args.ts # Parses CLI flags into SuSeeConfig
|
|
212
|
+
│ ├── index.ts # CLI entrypoint & command dispatch (build/init/check/bundle)
|
|
213
|
+
│ ├── parse_args.ts # Parses CLI flags into SuSeeConfig / bundle opts
|
|
181
214
|
│ ├── init.ts # `susee init` — scaffolds config file
|
|
215
|
+
│ ├── lint.ts # `susee check` — runs suseeLint over the dependency tree
|
|
182
216
|
│ └── print_help.ts # `susee --help` output
|
|
183
217
|
├── compiler/
|
|
184
218
|
│ ├── index.ts # Compiler class — bundles + emits CJS/ESM + types
|
|
@@ -256,8 +290,8 @@ npm run fmt # oxfmt
|
|
|
256
290
|
|
|
257
291
|
<!-- Need to update version -->
|
|
258
292
|
|
|
259
|
-
[sb_img]: https://badge.socket.dev/npm/package/susee/
|
|
260
|
-
[sb_url]: https://badge.socket.dev/npm/package/susee/
|
|
293
|
+
[sb_img]: https://badge.socket.dev/npm/package/susee/2.2.4
|
|
294
|
+
[sb_url]: https://badge.socket.dev/npm/package/susee/2.2.4
|
|
261
295
|
|
|
262
296
|
<!-- -->
|
|
263
297
|
|
package/dist/cli/index.mjs
CHANGED
|
@@ -2,9 +2,8 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import process from 'node:process';
|
|
4
4
|
import readline from 'node:readline/promises';
|
|
5
|
-
import tcolor from '@suseejs/color';
|
|
6
5
|
import ts6 from '@suseejs/ts6';
|
|
7
|
-
import { LogTimer, logError, logInfo, suseeBundler } from '@suseejs/susee_bundler';
|
|
6
|
+
import { LogTimer, logError, logInfo, logWarning, suseeBundler, suseeLint } from '@suseejs/susee_bundler';
|
|
8
7
|
import { minify } from 'oxc-minify';
|
|
9
8
|
//src/cli/init.ts
|
|
10
9
|
const tsFileText = `
|
|
@@ -181,7 +180,7 @@ function checkEntries(entries) {
|
|
|
181
180
|
for (const obj of entries) {
|
|
182
181
|
if (!fs.existsSync(path.resolve(process.cwd(), obj.entry))) {
|
|
183
182
|
const info = 'Entry file error';
|
|
184
|
-
const cause = `Entry file ${obj.entry}
|
|
183
|
+
const cause = `Entry file ${obj.entry} does not exist.`;
|
|
185
184
|
logError(info, cause, true);
|
|
186
185
|
}
|
|
187
186
|
}
|
|
@@ -238,6 +237,52 @@ async function finalSuseeConfig() {
|
|
|
238
237
|
return generateBuildOptions(config);
|
|
239
238
|
}
|
|
240
239
|
}
|
|
240
|
+
async function generateFinalBuildOptions(options) {
|
|
241
|
+
let buildOptions = {};
|
|
242
|
+
const _buildOptions = await finalSuseeConfig();
|
|
243
|
+
if (!options && !_buildOptions) {
|
|
244
|
+
const info = 'Required build options or susee config file at root.You can use `npx susee init` to create susee config file at root';
|
|
245
|
+
const cause = 'No build options or susee config file at root.';
|
|
246
|
+
logError(info, cause, true);
|
|
247
|
+
}
|
|
248
|
+
if (options) {
|
|
249
|
+
buildOptions = generateBuildOptions(options);
|
|
250
|
+
}
|
|
251
|
+
else if (_buildOptions) {
|
|
252
|
+
buildOptions = _buildOptions;
|
|
253
|
+
}
|
|
254
|
+
return buildOptions;
|
|
255
|
+
}
|
|
256
|
+
function bundler(point) {
|
|
257
|
+
const root = process.cwd();
|
|
258
|
+
const bundled = suseeBundler(point.entry, root, point.checks);
|
|
259
|
+
if (bundled.moduleType === 2) {
|
|
260
|
+
logWarning('Your project contains CJS files that were auto-converted. Consider migrating to ESM for better tree-shaking.');
|
|
261
|
+
}
|
|
262
|
+
return bundled.bundledCode;
|
|
263
|
+
}
|
|
264
|
+
function suseeBundle(entry, checkOptions) {
|
|
265
|
+
const root = process.cwd();
|
|
266
|
+
const opts = checkOptions ? checkOptions : {
|
|
267
|
+
checkAnonymous: false,
|
|
268
|
+
checkDefaultExports: false,
|
|
269
|
+
checkNpmInstalled: false
|
|
270
|
+
};
|
|
271
|
+
const bundled = suseeBundler(entry, root, opts);
|
|
272
|
+
if (bundled.moduleType === 2) {
|
|
273
|
+
logWarning('Your project contains CJS files that were auto-converted. Consider migrating to ESM for better tree-shaking.');
|
|
274
|
+
}
|
|
275
|
+
return bundled.bundledCode;
|
|
276
|
+
}
|
|
277
|
+
async function suseeCliBundle(opts) {
|
|
278
|
+
const fileName = path.basename(opts.entry);
|
|
279
|
+
const outDir = opts.outDir ? path.resolve(process.cwd(), opts.outDir) : process.cwd();
|
|
280
|
+
const outFilePath = path.join(outDir, fileName);
|
|
281
|
+
const code = suseeBundle(opts.entry, opts.check);
|
|
282
|
+
if (!fs.existsSync(outDir))
|
|
283
|
+
await fs.promises.mkdir(outDir, { recursive: true });
|
|
284
|
+
await fs.promises.writeFile(outFilePath, code);
|
|
285
|
+
}
|
|
241
286
|
function fail(message) {
|
|
242
287
|
const info = message;
|
|
243
288
|
const cause = '';
|
|
@@ -266,24 +311,38 @@ function parseBooleanFlag(flag, value) {
|
|
|
266
311
|
return false;
|
|
267
312
|
fail(`Type of ${flag} must be boolean.`);
|
|
268
313
|
}
|
|
314
|
+
function parseBundleBool(value) {
|
|
315
|
+
if (value === 'true')
|
|
316
|
+
return true;
|
|
317
|
+
if (value === 'false')
|
|
318
|
+
return false;
|
|
319
|
+
fail(`${value} must be "true" or "false".`);
|
|
320
|
+
}
|
|
269
321
|
function parseArgs(argv) {
|
|
270
|
-
const
|
|
322
|
+
const buildOpts = {};
|
|
323
|
+
const bundleOpts = {};
|
|
271
324
|
for (let index = 0; index < argv.length; index += 1) {
|
|
272
325
|
const argument = argv[index];
|
|
273
|
-
if (
|
|
274
|
-
|
|
326
|
+
if (!argument.startsWith('--') && isFile(argument)) {
|
|
327
|
+
if (buildOpts.entry && isFile(buildOpts.entry))
|
|
328
|
+
fail('Entry point already exists.');
|
|
329
|
+
buildOpts.entry = argument;
|
|
330
|
+
bundleOpts.entry = argument;
|
|
275
331
|
continue;
|
|
276
332
|
}
|
|
277
|
-
const
|
|
333
|
+
const eqIndex = argument.indexOf('=');
|
|
334
|
+
const flag = eqIndex === -1 ? argument : argument.slice(0, eqIndex);
|
|
335
|
+
const inlineValue = eqIndex === -1 ? undefined : argument.slice(eqIndex + 1);
|
|
278
336
|
const nextValue = argv[index + 1];
|
|
279
337
|
const value = inlineValue ?? nextValue;
|
|
280
338
|
switch (flag) {
|
|
281
339
|
case '--entry':
|
|
282
340
|
if (!value || value.startsWith('--'))
|
|
283
341
|
fail('Entry point required.');
|
|
284
|
-
if (
|
|
342
|
+
if (buildOpts.entry && isFile(buildOpts.entry))
|
|
285
343
|
fail('Entry point already exists.');
|
|
286
|
-
|
|
344
|
+
buildOpts.entry = value;
|
|
345
|
+
bundleOpts.entry = value;
|
|
287
346
|
if (inlineValue === undefined) {
|
|
288
347
|
index += 1;
|
|
289
348
|
}
|
|
@@ -291,16 +350,17 @@ function parseArgs(argv) {
|
|
|
291
350
|
case '--outdir':
|
|
292
351
|
if (!value || value.startsWith('--'))
|
|
293
352
|
fail('Output directory required.');
|
|
294
|
-
|
|
353
|
+
buildOpts.outDir = value;
|
|
354
|
+
bundleOpts.outDir = value;
|
|
295
355
|
if (inlineValue === undefined) {
|
|
296
356
|
index += 1;
|
|
297
357
|
}
|
|
298
358
|
break;
|
|
299
359
|
case '--format':
|
|
300
|
-
if (value !== 'cjs' && value !== 'commonjs' && value !== 'esm') {
|
|
360
|
+
if (value !== 'cjs' && value !== 'commonjs' && value !== 'esm' && value !== 'both') {
|
|
301
361
|
fail('Format must be cjs, commonjs, esm, both.');
|
|
302
362
|
}
|
|
303
|
-
|
|
363
|
+
buildOpts.format = value === 'cjs' || value === 'commonjs' ? ['commonjs'] : value === 'esm' ? ['esm'] : value === 'both' ? ['commonjs', 'esm'] : undefined;
|
|
304
364
|
if (inlineValue === undefined) {
|
|
305
365
|
index += 1;
|
|
306
366
|
}
|
|
@@ -308,82 +368,106 @@ function parseArgs(argv) {
|
|
|
308
368
|
case '--tsconfig':
|
|
309
369
|
if (!value || value.startsWith('--'))
|
|
310
370
|
fail('Tsconfig path required.');
|
|
311
|
-
|
|
371
|
+
buildOpts.tsconfig = value;
|
|
312
372
|
if (inlineValue === undefined) {
|
|
313
373
|
index += 1;
|
|
314
374
|
}
|
|
315
375
|
break;
|
|
316
376
|
case '--allow-update':
|
|
317
377
|
if (inlineValue !== undefined) {
|
|
318
|
-
|
|
378
|
+
buildOpts.allowUpdate = parseBooleanFlag('allow update', inlineValue);
|
|
319
379
|
}
|
|
320
380
|
else if (nextValue === 'true' || nextValue === 'false') {
|
|
321
|
-
|
|
381
|
+
buildOpts.allowUpdate = parseBooleanFlag('allow update', nextValue);
|
|
322
382
|
index += 1;
|
|
323
383
|
}
|
|
324
384
|
else {
|
|
325
|
-
|
|
385
|
+
buildOpts.allowUpdate = true;
|
|
326
386
|
}
|
|
327
387
|
break;
|
|
328
388
|
case '--check':
|
|
329
389
|
if (inlineValue !== undefined) {
|
|
330
|
-
|
|
390
|
+
buildOpts.check = parseBooleanFlag('check', inlineValue);
|
|
391
|
+
bundleOpts.check = parseBundleBool(inlineValue);
|
|
331
392
|
}
|
|
332
393
|
else if (nextValue === 'true' || nextValue === 'false') {
|
|
333
|
-
|
|
394
|
+
buildOpts.check = parseBooleanFlag('check', nextValue);
|
|
395
|
+
bundleOpts.check = parseBundleBool(nextValue);
|
|
334
396
|
index += 1;
|
|
335
397
|
}
|
|
336
398
|
else {
|
|
337
|
-
|
|
399
|
+
buildOpts.check = true;
|
|
400
|
+
bundleOpts.check = true;
|
|
338
401
|
}
|
|
339
402
|
break;
|
|
340
403
|
case '--minify':
|
|
341
404
|
if (inlineValue !== undefined) {
|
|
342
|
-
|
|
405
|
+
buildOpts.minify = parseBooleanFlag('minify', inlineValue);
|
|
343
406
|
}
|
|
344
407
|
else if (nextValue === 'true' || nextValue === 'false') {
|
|
345
|
-
|
|
408
|
+
buildOpts.minify = parseBooleanFlag('minify', nextValue);
|
|
346
409
|
index += 1;
|
|
347
410
|
}
|
|
348
411
|
else {
|
|
349
|
-
|
|
412
|
+
buildOpts.minify = true;
|
|
350
413
|
}
|
|
351
414
|
break;
|
|
352
415
|
}
|
|
353
416
|
}
|
|
354
|
-
return
|
|
417
|
+
return {
|
|
418
|
+
buildOpts,
|
|
419
|
+
bundleOpts
|
|
420
|
+
};
|
|
355
421
|
}
|
|
356
422
|
function cliConfig(argv) {
|
|
357
|
-
const
|
|
358
|
-
if (isEmptyObject(
|
|
423
|
+
const opts = parseArgs(argv).buildOpts;
|
|
424
|
+
if (isEmptyObject(opts))
|
|
359
425
|
return undefined;
|
|
360
426
|
const point = {
|
|
361
|
-
entry:
|
|
427
|
+
entry: opts.entry ?? '',
|
|
362
428
|
exportPath: '.',
|
|
363
|
-
format:
|
|
364
|
-
tsconfigFilePath:
|
|
365
|
-
minify:
|
|
429
|
+
format: opts.format ?? ['esm'],
|
|
430
|
+
tsconfigFilePath: opts.tsconfig ?? undefined,
|
|
431
|
+
minify: opts.minify ?? false,
|
|
366
432
|
checks: {
|
|
367
|
-
checkAnonymous:
|
|
368
|
-
checkDefaultExports:
|
|
369
|
-
checkNpmInstalled:
|
|
433
|
+
checkAnonymous: opts.check ? true : false,
|
|
434
|
+
checkDefaultExports: opts.check ? true : false,
|
|
435
|
+
checkNpmInstalled: opts.check ? true : false
|
|
370
436
|
}
|
|
371
437
|
};
|
|
372
438
|
if (point.entry === '')
|
|
373
439
|
return undefined;
|
|
374
440
|
const config = {
|
|
375
441
|
entryPoints: [point],
|
|
376
|
-
outDir:
|
|
377
|
-
allowUpdatePackageJson:
|
|
442
|
+
outDir: opts.outDir ?? 'dist',
|
|
443
|
+
allowUpdatePackageJson: opts.allowUpdate ?? false
|
|
378
444
|
};
|
|
379
445
|
return config;
|
|
380
446
|
}
|
|
447
|
+
function cliBundleOpts(argv) {
|
|
448
|
+
const opts = parseArgs(argv).bundleOpts;
|
|
449
|
+
if (isEmptyObject(opts))
|
|
450
|
+
return undefined;
|
|
451
|
+
if (!opts.entry)
|
|
452
|
+
return undefined;
|
|
453
|
+
const options = {
|
|
454
|
+
entry: opts.entry,
|
|
455
|
+
outDir: opts.outDir,
|
|
456
|
+
check: opts.check ? {
|
|
457
|
+
checkAnonymous: true,
|
|
458
|
+
checkDefaultExports: true,
|
|
459
|
+
checkNpmInstalled: true
|
|
460
|
+
} : undefined
|
|
461
|
+
};
|
|
462
|
+
return options;
|
|
463
|
+
}
|
|
381
464
|
//src/cli/print_help.ts
|
|
382
465
|
function printHelp() {
|
|
383
466
|
console.log(`Susee CLI.
|
|
384
467
|
Usage:
|
|
385
468
|
susee build Build using susee.config.{ts,js,mjs}
|
|
386
469
|
susee init Generate susee.config.{ts,js,mjs}
|
|
470
|
+
susee check Run lint checks on a dependency tree without bundling.
|
|
387
471
|
susee --help Show this message
|
|
388
472
|
susee build <entry> [options] Build from a single entry file
|
|
389
473
|
Options:
|
|
@@ -393,7 +477,7 @@ Options:
|
|
|
393
477
|
--tsconfig <path> Custom tsconfig path. (default to undefined)
|
|
394
478
|
--allow-update[=true|false] Enable package.json update. (default to false)
|
|
395
479
|
--minify[=true|false] Enable minify to output JS code.(default to false)
|
|
396
|
-
--check[=true|false] Enable
|
|
480
|
+
--check[=true|false] Enable lint checks on bundled output.(default to false)
|
|
397
481
|
Notes:
|
|
398
482
|
Duplicate top-level declarations fail the build with file and location output.
|
|
399
483
|
Rename conflicting declarations in source files before bundling.
|
|
@@ -432,8 +516,9 @@ var files;
|
|
|
432
516
|
files_1.deleteFile = deleteFile;
|
|
433
517
|
async function readFile(filePath) {
|
|
434
518
|
if (!existsPath(filePath)) {
|
|
435
|
-
|
|
436
|
-
|
|
519
|
+
const info = `${filePath} does not exists`;
|
|
520
|
+
const cause = `When reading ${filePath}, file does not exists`;
|
|
521
|
+
logError(info, cause, true);
|
|
437
522
|
}
|
|
438
523
|
filePath = resolvePath(filePath);
|
|
439
524
|
const readContent = await fs.promises.readFile(filePath);
|
|
@@ -510,7 +595,9 @@ var files;
|
|
|
510
595
|
const pkgFile = resolvePath('package.json');
|
|
511
596
|
const pkgtext = await readJsonFile(pkgFile);
|
|
512
597
|
let { name, version, description, main, module, type, types, exports, ...rest } = pkgtext;
|
|
513
|
-
|
|
598
|
+
const hasCjs = files.commonjs !== undefined;
|
|
599
|
+
const hasEsm = files.esm !== undefined;
|
|
600
|
+
type = hasCjs && !hasEsm ? 'commonjs' : 'module';
|
|
514
601
|
let _main = {};
|
|
515
602
|
let _module = {};
|
|
516
603
|
let _types = {};
|
|
@@ -519,7 +606,11 @@ var files;
|
|
|
519
606
|
_main = files.main ? { main: path.relative(process.cwd(), files.main) } : {};
|
|
520
607
|
_module = files.module ? { module: path.relative(process.cwd(), files.module) } : {};
|
|
521
608
|
_types = files.types ? { types: path.relative(process.cwd(), files.types) } : {};
|
|
522
|
-
|
|
609
|
+
const normalizedExports = exports && typeof exports === 'object' && !Array.isArray(exports) ? { ...exports } : {};
|
|
610
|
+
_exports = { exports: {
|
|
611
|
+
...normalizedExports,
|
|
612
|
+
...getExports(files, exportPath)
|
|
613
|
+
} };
|
|
523
614
|
}
|
|
524
615
|
else {
|
|
525
616
|
_main = main ? { main } : {};
|
|
@@ -572,7 +663,7 @@ function jsxCompilerOptions(sourceCode, compilerOptions, isJsx) {
|
|
|
572
663
|
const pattern = `import\\s+(?:.*?)\\s+from\\s+("${txt}"|"${txt}\\/.*")`;
|
|
573
664
|
const re = new RegExp(pattern, 'gm');
|
|
574
665
|
if (!re.test(sourceCode)) {
|
|
575
|
-
console.error('[jsx-runtime-mismatch-error]:\nJSX syntax found in bundled code,but its not react runtime and jsx-runtime from bundled code and jsxImportSource from tsconfig are mismatched
|
|
666
|
+
console.error('[jsx-runtime-mismatch-error]:\nJSX syntax found in bundled code,but its not react runtime and jsx-runtime from bundled code and jsxImportSource from tsconfig are mismatched.');
|
|
576
667
|
process.exit(1);
|
|
577
668
|
}
|
|
578
669
|
}
|
|
@@ -739,18 +830,6 @@ function getCompilerOptions(customConfigPath) {
|
|
|
739
830
|
defaultOptions
|
|
740
831
|
};
|
|
741
832
|
}
|
|
742
|
-
//src/bundler.ts
|
|
743
|
-
function bundler(point) {
|
|
744
|
-
// const bundledCodeCache: WeakMap<BuildEntryPoint, string> = new WeakMap();
|
|
745
|
-
const root = process.cwd();
|
|
746
|
-
// let bundledCode = bundledCodeCache.get(point);
|
|
747
|
-
// if (!bundledCode) {
|
|
748
|
-
// bundledCode = suseeBundler(point.entry,root,point.checks).bundledCode;
|
|
749
|
-
// bundledCodeCache.set(point, bundledCode);
|
|
750
|
-
// }
|
|
751
|
-
// return bundledCode;
|
|
752
|
-
return suseeBundler(point.entry, root, point.checks).bundledCode;
|
|
753
|
-
}
|
|
754
833
|
//src/helpers/minify.ts
|
|
755
834
|
async function oxcMinify(fileName, code, point) {
|
|
756
835
|
const options = typeof point.minify === 'object' && typeof point.minify !== 'boolean' ? point.minify.options : undefined;
|
|
@@ -758,7 +837,6 @@ async function oxcMinify(fileName, code, point) {
|
|
|
758
837
|
return result.code;
|
|
759
838
|
}
|
|
760
839
|
//src/compiler/index.ts
|
|
761
|
-
//import { utils } from "../helpers/utilities.js";
|
|
762
840
|
/**
|
|
763
841
|
* Checks if the given code string contains JSX syntax.
|
|
764
842
|
* @param code The content of the file as a string.
|
|
@@ -872,6 +950,8 @@ class Compiler {
|
|
|
872
950
|
}
|
|
873
951
|
if (isMain && this._files.esm) {
|
|
874
952
|
this._files.module = this._files.esm;
|
|
953
|
+
if (this._files.esmTypes)
|
|
954
|
+
this._files.types = this._files.esmTypes;
|
|
875
955
|
}
|
|
876
956
|
}
|
|
877
957
|
await files.writeFile(mainFilePath, compiledCode);
|
|
@@ -888,6 +968,15 @@ class Compiler {
|
|
|
888
968
|
async compile() {
|
|
889
969
|
await files.clearFolder(this._object.outDir);
|
|
890
970
|
for (const point of this._object.buildEntryPoints) {
|
|
971
|
+
this._files = {
|
|
972
|
+
commonjs: undefined,
|
|
973
|
+
commonjsTypes: undefined,
|
|
974
|
+
esm: undefined,
|
|
975
|
+
esmTypes: undefined,
|
|
976
|
+
main: undefined,
|
|
977
|
+
module: undefined,
|
|
978
|
+
types: undefined
|
|
979
|
+
};
|
|
891
980
|
const bundleCode = bundler(point);
|
|
892
981
|
for (const format of point.format) {
|
|
893
982
|
switch (format) {
|
|
@@ -920,23 +1009,36 @@ class Compiler {
|
|
|
920
1009
|
*/
|
|
921
1010
|
async function build(options) {
|
|
922
1011
|
const buildTime = new LogTimer();
|
|
923
|
-
|
|
924
|
-
const _buildOptions = await finalSuseeConfig();
|
|
925
|
-
if (!options && !_buildOptions) {
|
|
926
|
-
const info = 'Required build options or susee config file at root.You can use `npx susee init` to create susee config file at root';
|
|
927
|
-
const cause = 'No build options or susee config file at root.';
|
|
928
|
-
logError(info, cause, true);
|
|
929
|
-
}
|
|
930
|
-
if (options) {
|
|
931
|
-
buildOptions = generateBuildOptions(options);
|
|
932
|
-
}
|
|
933
|
-
else if (_buildOptions) {
|
|
934
|
-
buildOptions = _buildOptions;
|
|
935
|
-
}
|
|
1012
|
+
const buildOptions = await generateFinalBuildOptions(options);
|
|
936
1013
|
const compiler = new Compiler(buildOptions);
|
|
937
1014
|
await compiler.compile();
|
|
938
1015
|
buildTime.buildTime();
|
|
939
1016
|
}
|
|
1017
|
+
//src/cli/lint.ts
|
|
1018
|
+
async function suseeCheck() {
|
|
1019
|
+
const buildOptions = await generateFinalBuildOptions();
|
|
1020
|
+
const lintOptions = {
|
|
1021
|
+
checkAnonymous: true,
|
|
1022
|
+
checkDefaultExports: true,
|
|
1023
|
+
checkNpmInstalled: true
|
|
1024
|
+
};
|
|
1025
|
+
for (const point of buildOptions.buildEntryPoints) {
|
|
1026
|
+
const result = suseeLint(point.entry, '.', lintOptions);
|
|
1027
|
+
for (const diag of result.errors) {
|
|
1028
|
+
const location = `${diag.file}:${diag.line}:${diag.column}`;
|
|
1029
|
+
const details = diag.details.length ? `\n${diag.details.map((d) => ` ${d}`).join('\n')}` : '';
|
|
1030
|
+
logError(`[${diag.rule}] ${location} — ${diag.message}${details}`, diag.rule);
|
|
1031
|
+
}
|
|
1032
|
+
for (const diag of result.warnings) {
|
|
1033
|
+
const location = `${diag.file}:${diag.line}:${diag.column}`;
|
|
1034
|
+
const details = diag.details.length ? `\n${diag.details.map((d) => ` ${d}`).join('\n')}` : '';
|
|
1035
|
+
logWarning(`[${diag.rule}] ${location} — ${diag.message}${details}`);
|
|
1036
|
+
}
|
|
1037
|
+
if (result.errors.length === 0 && result.warnings.length === 0) {
|
|
1038
|
+
logInfo(`All checks passed for ${point.entry}`);
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
940
1042
|
//src/cli/index.ts
|
|
941
1043
|
async function getPackageVersion() {
|
|
942
1044
|
const pkgPath = path.resolve(process.cwd(), 'package.json');
|
|
@@ -965,6 +1067,9 @@ async function cliBuild() {
|
|
|
965
1067
|
case 'init':
|
|
966
1068
|
await cliInit();
|
|
967
1069
|
break;
|
|
1070
|
+
case 'check':
|
|
1071
|
+
await suseeCheck();
|
|
1072
|
+
break;
|
|
968
1073
|
case '--version':
|
|
969
1074
|
case '-v':
|
|
970
1075
|
logInfo(`susee v${version}`);
|
|
@@ -983,6 +1088,16 @@ async function cliBuild() {
|
|
|
983
1088
|
const config = cliConfig(restArgs);
|
|
984
1089
|
await build(config);
|
|
985
1090
|
}
|
|
1091
|
+
else if (args.length > 1 && args[0] === 'bundle') {
|
|
1092
|
+
const restArgs = args.slice(1);
|
|
1093
|
+
const opts = cliBundleOpts(restArgs);
|
|
1094
|
+
if (opts) {
|
|
1095
|
+
await suseeCliBundle(opts);
|
|
1096
|
+
}
|
|
1097
|
+
else {
|
|
1098
|
+
errorLog();
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
986
1101
|
else {
|
|
987
1102
|
errorLog();
|
|
988
1103
|
}
|