susee 1.0.4 → 1.5.1
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 +111 -143
- package/bin/index.mjs +17 -2
- package/bin/init.mjs +136 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -13
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +17 -13
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +17 -18
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<!-- markdownlint-disable MD041 -->
|
|
3
3
|
<div align="center">
|
|
4
4
|
<img src="https://susee.phothin.dev/logo/susee.webp" width="160" height="160" alt="susee" />
|
|
5
|
-
<h1>
|
|
5
|
+
<h1>Susee</h1>
|
|
6
6
|
</div>
|
|
7
7
|
<!-- markdownlint-enable MD033 -->
|
|
8
8
|
|
|
@@ -10,74 +10,54 @@
|
|
|
10
10
|
|
|
11
11
|
## Overview
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Susee is a TypeScript-first bundler for library packages.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
It reads `susee.config.{ts,js,mjs}`, resolves the dependency graph for each entry,
|
|
16
|
+
bundles sources into a single unit, then compiles output for ESM and/or CommonJS with types.
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
## Features
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
- Loads config from one of:
|
|
21
|
+
- `susee.config.ts`
|
|
22
|
+
- `susee.config.js`
|
|
23
|
+
- `susee.config.mjs`
|
|
24
|
+
- Supports multiple entry points with subpath exports (`.` and `./subpath`).
|
|
25
|
+
- Validates and type-checks dependency files before bundling.
|
|
26
|
+
- Runs dependency, pre-process, and post-process plugins (sync or async).
|
|
27
|
+
- Compiles to:
|
|
28
|
+
- ESM (`.mjs`, `.d.mts`, source maps)
|
|
29
|
+
- CommonJS (`.cjs`, `.d.cts`, source maps)
|
|
30
|
+
- Can update `package.json` fields (`type`, `main`, `module`, `types`, `exports`) when `allowUpdatePackageJson` is enabled.
|
|
20
31
|
|
|
21
|
-
|
|
32
|
+
## Current Constraints
|
|
22
33
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
| CommonJS | `.cjs` | `.d.cts` |
|
|
34
|
+
- CommonJS dependencies in the source graph are rejected by core (suggested workaround: `@suseejs/plugin-commonjs`).
|
|
35
|
+
- JSX/TSX dependencies are currently rejected.
|
|
36
|
+
- CLI supports only `susee` and `susee init`.
|
|
27
37
|
|
|
28
|
-
|
|
38
|
+
## Installation and Quick Start
|
|
29
39
|
|
|
30
|
-
|
|
40
|
+
### Install
|
|
31
41
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
npm install susee --save-dev
|
|
42
|
+
```sh
|
|
43
|
+
npm i -D susee
|
|
36
44
|
```
|
|
37
45
|
|
|
38
|
-
|
|
46
|
+
### Create a config file
|
|
39
47
|
|
|
40
|
-
```
|
|
41
|
-
|
|
48
|
+
```sh
|
|
49
|
+
npx susee init
|
|
42
50
|
```
|
|
43
51
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
The `susee` CLI binary is exposed through the `bin` field and becomes available immediately after installation.
|
|
52
|
+
### Build your first project
|
|
47
53
|
|
|
48
|
-
|
|
54
|
+
Use the CLI:
|
|
49
55
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
```ts
|
|
53
|
-
import type { SuSeeConfig } from "susee";
|
|
54
|
-
|
|
55
|
-
const config: SuSeeConfig = {
|
|
56
|
-
entryPoints: [
|
|
57
|
-
{
|
|
58
|
-
entry: "src/index.ts",
|
|
59
|
-
exportPath: ".",
|
|
60
|
-
format: "both",
|
|
61
|
-
},
|
|
62
|
-
],
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export default config;
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Running Your First Build
|
|
69
|
-
|
|
70
|
-
Execute the bundler using one of these methods:
|
|
71
|
-
|
|
72
|
-
#### CLI Execution
|
|
73
|
-
|
|
74
|
-
with `npx` :
|
|
75
|
-
|
|
76
|
-
```bash
|
|
56
|
+
```sh
|
|
77
57
|
npx susee
|
|
78
58
|
```
|
|
79
59
|
|
|
80
|
-
|
|
60
|
+
Or in `package.json`:
|
|
81
61
|
|
|
82
62
|
```json
|
|
83
63
|
{
|
|
@@ -87,131 +67,118 @@ via `package.json` :
|
|
|
87
67
|
}
|
|
88
68
|
```
|
|
89
69
|
|
|
90
|
-
|
|
91
|
-
npm run build
|
|
92
|
-
```
|
|
70
|
+
## Config Reference
|
|
93
71
|
|
|
94
|
-
|
|
72
|
+
`SuSeeConfig`
|
|
95
73
|
|
|
96
|
-
```
|
|
97
|
-
|
|
74
|
+
```ts
|
|
75
|
+
interface SuSeeConfig {
|
|
76
|
+
entryPoints: EntryPoint[];
|
|
77
|
+
outDir?: string; // default: "dist"
|
|
78
|
+
plugins?: (SuseePlugin | SuseePluginFunction)[]; // default: []
|
|
79
|
+
allowUpdatePackageJson?: boolean; // default: false
|
|
80
|
+
}
|
|
98
81
|
```
|
|
99
82
|
|
|
100
|
-
|
|
83
|
+
`EntryPoint`
|
|
101
84
|
|
|
102
85
|
```ts
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
86
|
+
type OutputFormat = ("commonjs" | "esm")[];
|
|
87
|
+
|
|
88
|
+
interface EntryPoint {
|
|
89
|
+
entry: string;
|
|
90
|
+
exportPath: "." | `./${string}`;
|
|
91
|
+
format?: OutputFormat; // default: ["esm"]
|
|
92
|
+
tsconfigFilePath?: string;
|
|
93
|
+
renameDuplicates?: boolean; // default: true
|
|
94
|
+
binary?: { name: string };
|
|
95
|
+
}
|
|
106
96
|
```
|
|
107
97
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
1. Loads configuration from `susee.config.ts`
|
|
111
|
-
2. Resolves the dependency tree
|
|
112
|
-
3. Bundles local dependencies
|
|
113
|
-
4. Compiles to target formats
|
|
114
|
-
5. Optionally updates `package.json`
|
|
115
|
-
|
|
116
|
-
## Configuration summary
|
|
117
|
-
|
|
118
|
-
### Top-Level Configuration Fields
|
|
98
|
+
### Entry Validation Rules
|
|
119
99
|
|
|
120
|
-
|
|
100
|
+
- At least one `entryPoint` is required.
|
|
101
|
+
- Duplicate `exportPath` values are rejected.
|
|
102
|
+
- Each `entry` file must exist.
|
|
121
103
|
|
|
122
|
-
|
|
104
|
+
### TypeScript Options Behavior
|
|
123
105
|
|
|
124
|
-
|
|
106
|
+
For each entry point, Susee builds compiler options from:
|
|
125
107
|
|
|
126
|
-
|
|
108
|
+
1. `tsconfigFilePath` (if provided)
|
|
109
|
+
2. project `tsconfig.json`
|
|
110
|
+
3. Susee defaults
|
|
127
111
|
|
|
128
|
-
|
|
112
|
+
Susee enforces/adjusts key options internally:
|
|
129
113
|
|
|
130
|
-
|
|
131
|
-
|
|
114
|
+
- `moduleResolution: "NodeNext"`
|
|
115
|
+
- `allowJs: true`
|
|
116
|
+
- `outDir` set per entry output path
|
|
117
|
+
- `types` includes `node`
|
|
118
|
+
- `lib` includes `ESNext`
|
|
132
119
|
|
|
133
|
-
|
|
120
|
+
## Plugin Hooks
|
|
134
121
|
|
|
135
|
-
|
|
122
|
+
Susee supports these plugin stages:
|
|
136
123
|
|
|
137
|
-
|
|
124
|
+
- `dependency`
|
|
125
|
+
- receives resolved dependency files and compiler options
|
|
126
|
+
- transforms dependency metadata/content before bundling
|
|
127
|
+
- `pre-process`
|
|
128
|
+
- receives bundled code before compilation
|
|
129
|
+
- `post-process`
|
|
130
|
+
- receives emitted JS output content per file
|
|
138
131
|
|
|
139
|
-
|
|
132
|
+
Both sync and async plugins are supported.
|
|
140
133
|
|
|
141
|
-
|
|
134
|
+
## Output Behavior
|
|
142
135
|
|
|
143
|
-
|
|
136
|
+
- `format: ["esm"]`
|
|
137
|
+
- emits `.mjs` and `.d.mts`
|
|
138
|
+
- `format: ["commonjs"]`
|
|
139
|
+
- emits `.cjs` and `.d.cts`
|
|
140
|
+
- `format: ["esm", "commonjs"]`
|
|
141
|
+
- emits both sets
|
|
144
142
|
|
|
145
|
-
|
|
146
|
-
Defaults to `esm` if not specified.
|
|
143
|
+
When `allowUpdatePackageJson` is `true`, Susee can update:
|
|
147
144
|
|
|
148
|
-
|
|
145
|
+
- `type` (forced to `module`)
|
|
146
|
+
- `main`
|
|
147
|
+
- `module`
|
|
148
|
+
- `types`
|
|
149
|
+
- `exports` (including subpath exports from `exportPath`)
|
|
149
150
|
|
|
150
|
-
|
|
151
|
+
## CLI
|
|
151
152
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
3. default compiler options of `susee`
|
|
157
|
-
|
|
158
|
-
Notes: You can control TypesScript compiler options from `tsconfig.json` except , `rootDir` , `outDir`,`module`.
|
|
159
|
-
|
|
160
|
-
**renameDuplicates (optional)**: Controls whether susee automatically renames duplicate identifiers during the bundling process to avoid naming conflicts when merging files.(default to `true`).If you want to rename your self set to `false`, process will exit with code-1 and print where duplicate found.
|
|
161
|
-
|
|
162
|
-
## Plugins
|
|
163
|
-
|
|
164
|
-
Plugins in the ecosystem have three common types:
|
|
165
|
-
|
|
166
|
-
- `dependency` — transform dependency list before bundling
|
|
167
|
-
- `pre-process` — modify the joined bundle text before compilation
|
|
168
|
-
- `post-process` — modify emitted output files
|
|
169
|
-
|
|
170
|
-
Plugins may be provided as objects or factories (functions returning the plugin). They may be synchronous or async — the bundler handles both.
|
|
171
|
-
|
|
172
|
-
## package.json updates
|
|
173
|
-
|
|
174
|
-
When `allowUpdatePackageJson` is enabled, susee will:
|
|
175
|
-
|
|
176
|
-
- set `type` to `module` (to ensure ESM compatibility)
|
|
177
|
-
- add/update `main`, `module`, `types` and `exports` for the main export when building the package root
|
|
178
|
-
- merge subpath exports for non-root `exportPath`s without overwriting unrelated exports
|
|
179
|
-
|
|
180
|
-
Output file name hints (produced by the compiler):
|
|
181
|
-
|
|
182
|
-
- ESM JS -> `.mjs`
|
|
183
|
-
- ESM types -> `.d.mts`
|
|
184
|
-
- CJS JS -> `.cjs`
|
|
185
|
-
- CJS types -> `.d.cts`
|
|
186
|
-
|
|
187
|
-
## Limitations & notes
|
|
188
|
-
|
|
189
|
-
- The bundler only processes local TypeScript files and does not bundle `node_modules` packages.
|
|
190
|
-
- The entry file should be an ESM-compatible TypeScript file.
|
|
191
|
-
- Exports from the entry file are not removed — only dependency exports may be stripped during bundling.
|
|
153
|
+
```bash
|
|
154
|
+
susee
|
|
155
|
+
susee init
|
|
156
|
+
```
|
|
192
157
|
|
|
193
|
-
|
|
158
|
+
Any other argument combination exits with an error.
|
|
194
159
|
|
|
195
|
-
|
|
160
|
+
## Local Development
|
|
196
161
|
|
|
197
|
-
|
|
162
|
+
Common project scripts:
|
|
198
163
|
|
|
199
|
-
|
|
164
|
+
```bash
|
|
165
|
+
npm run build
|
|
166
|
+
npm run test
|
|
167
|
+
npm run lint
|
|
168
|
+
npm run fmt
|
|
169
|
+
npm run hooks:install
|
|
170
|
+
```
|
|
200
171
|
|
|
201
|
-
|
|
202
|
-
- [ ] Add browser-oriented library build support.
|
|
203
|
-
- [ ] Improve workflows for building React-related libraries.
|
|
172
|
+
Notes:
|
|
204
173
|
|
|
205
|
-
|
|
174
|
+
- `npm run test` opens an interactive selector (`scripts/susee-tests.ts`).
|
|
175
|
+
- Git hooks are tracked in `.githooks` and installed via `npm run hooks:install`.
|
|
206
176
|
|
|
207
|
-
|
|
177
|
+
## Contributing
|
|
208
178
|
|
|
209
|
-
|
|
179
|
+
Contributions are welcome for bug fixes, features, documentation, and code quality improvements.
|
|
210
180
|
|
|
211
|
-
|
|
212
|
-
npm run build
|
|
213
|
-
npm test
|
|
214
|
-
```
|
|
181
|
+
See detail in [CONTRIBUTING.md][file-contribute]
|
|
215
182
|
|
|
216
183
|
## License
|
|
217
184
|
|
|
@@ -220,4 +187,5 @@ npm test
|
|
|
220
187
|
<!-- markdownlint-disable MD053 -->
|
|
221
188
|
|
|
222
189
|
[license]: LICENSE
|
|
190
|
+
[file-contribute]: CONTRIBUTING.md
|
|
223
191
|
[ptm]: https://github.com/phothinmg
|
package/bin/index.mjs
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import init from "../src/binary/init.mjs";
|
|
4
|
+
import { susee } from "../dist/index.mjs";
|
|
5
|
+
|
|
6
|
+
async function suseeBuild() {
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
if (args.length === 0) {
|
|
9
|
+
await susee();
|
|
10
|
+
} else if (args.length === 1 && args[0] === "init") {
|
|
11
|
+
await init();
|
|
12
|
+
} else {
|
|
13
|
+
console.error("Unknown CLI usage");
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
await suseeBuild();
|
package/bin/init.mjs
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import readline from "node:readline/promises";
|
|
5
|
+
import tcolor from "@suseejs/tcolor";
|
|
6
|
+
|
|
7
|
+
const tsFileText = String.raw`
|
|
8
|
+
import type { SuSeeConfig } from "./src/index.js";
|
|
9
|
+
|
|
10
|
+
const config: SuSeeConfig = {
|
|
11
|
+
// Array of entry point objects.
|
|
12
|
+
// ----------------------------
|
|
13
|
+
entryPoints: [
|
|
14
|
+
// You can add more entry points for different export paths.
|
|
15
|
+
// NOTE: duplicate export paths are not allowed.
|
|
16
|
+
// --------------------------------------------
|
|
17
|
+
{
|
|
18
|
+
// (required) Entry file path.
|
|
19
|
+
entry: "src/index.ts", // replace with your entry file
|
|
20
|
+
// (required) Export path for this entry.
|
|
21
|
+
exportPath: ".", // "." stands for the main export path and can be set to "./foo", "./bar", etc.
|
|
22
|
+
// (optional) Output module formats ["commonjs"] or ["esm", "commonjs"], default: ["esm"].
|
|
23
|
+
// Uncomment the following line to edit.
|
|
24
|
+
//format: ["esm"],
|
|
25
|
+
// (optional) Rename duplicate declarations, default: true.
|
|
26
|
+
// Uncomment the following line to edit.
|
|
27
|
+
//renameDuplicates: true,
|
|
28
|
+
// (optional) Custom tsconfig.json path, default: undefined.
|
|
29
|
+
// Uncomment the following line to edit.
|
|
30
|
+
//tsconfigFilePath: undefined,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
// NOTE: the following options apply to all entry points.
|
|
34
|
+
// ----------------------------------------------------------
|
|
35
|
+
// (optional) Output directory, default: dist.
|
|
36
|
+
// Uncomment the following line to edit.
|
|
37
|
+
//outDir: "dist",
|
|
38
|
+
// (optional) Array of susee plugins, default: [].
|
|
39
|
+
// Uncomment the following line to edit.
|
|
40
|
+
//plugins: [],
|
|
41
|
+
// (optional) Allow susee to update your package.json, default: false.
|
|
42
|
+
// Uncomment the following line to edit.
|
|
43
|
+
//allowUpdatePackageJson: false,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export default config;
|
|
47
|
+
`.trim();
|
|
48
|
+
|
|
49
|
+
const jsFileText = String.raw`
|
|
50
|
+
/**
|
|
51
|
+
* @type {import("susee").SuSeeConfig}
|
|
52
|
+
*/
|
|
53
|
+
const config = {
|
|
54
|
+
// Array of entry point objects.
|
|
55
|
+
// ----------------------------
|
|
56
|
+
entryPoints: [
|
|
57
|
+
// You can add more entry points for different export paths.
|
|
58
|
+
// NOTE: duplicate export paths are not allowed.
|
|
59
|
+
// --------------------------------------------
|
|
60
|
+
{
|
|
61
|
+
// (required) Entry file path.
|
|
62
|
+
entry: "src/index.ts", // replace with your entry file
|
|
63
|
+
// (required) Export path for this entry.
|
|
64
|
+
exportPath: ".", // "." stands for the main export path and can be set to "./foo", "./bar", etc.
|
|
65
|
+
// (optional) Output module formats ["commonjs"] or ["esm", "commonjs"], default: ["esm"].
|
|
66
|
+
// Uncomment the following line to edit.
|
|
67
|
+
//format: ["esm"],
|
|
68
|
+
// (optional) Rename duplicate declarations, default: true.
|
|
69
|
+
// Uncomment the following line to edit.
|
|
70
|
+
//renameDuplicates: true,
|
|
71
|
+
// (optional) Custom tsconfig.json path, default: undefined.
|
|
72
|
+
// Uncomment the following line to edit.
|
|
73
|
+
//tsconfigFilePath: undefined,
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
// NOTE: the following options apply to all entry points.
|
|
77
|
+
// ----------------------------------------------------------
|
|
78
|
+
// (optional) Output directory, default: dist.
|
|
79
|
+
// Uncomment the following line to edit.
|
|
80
|
+
//outDir: "dist",
|
|
81
|
+
// (optional) Array of susee plugins, default: [].
|
|
82
|
+
// Uncomment the following line to edit.
|
|
83
|
+
//plugins: [],
|
|
84
|
+
// (optional) Allow susee to update your package.json, default: false.
|
|
85
|
+
// Uncomment the following line to edit.
|
|
86
|
+
//allowUpdatePackageJson: false,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export default config;
|
|
90
|
+
`.trim();
|
|
91
|
+
/**
|
|
92
|
+
*
|
|
93
|
+
* @returns {Promise<"commonjs"|"esm">}
|
|
94
|
+
*/
|
|
95
|
+
async function getPackageType() {
|
|
96
|
+
const pkgFile = "package.json";
|
|
97
|
+
const pkgPath = path.resolve(process.cwd(), pkgFile);
|
|
98
|
+
const _pkg = await fs.promises.readFile(pkgPath, "utf8");
|
|
99
|
+
const pkg = JSON.parse(_pkg);
|
|
100
|
+
let type = "commonjs";
|
|
101
|
+
if (pkg.type && pkg.type === "module") type = "esm";
|
|
102
|
+
return type;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export default async function init() {
|
|
106
|
+
const rl = readline.createInterface({
|
|
107
|
+
input: process.stdin,
|
|
108
|
+
output: process.stdout,
|
|
109
|
+
});
|
|
110
|
+
const is_ts = await rl.question(tcolor.cyan("Is TypeScript project(y/n) : "));
|
|
111
|
+
const isTs = is_ts === "y" || is_ts === "Y" || is_ts === "" ? true : false;
|
|
112
|
+
rl.close();
|
|
113
|
+
let configFile;
|
|
114
|
+
let str;
|
|
115
|
+
if (isTs) {
|
|
116
|
+
configFile = "susee.config.ts";
|
|
117
|
+
str = tsFileText;
|
|
118
|
+
} else {
|
|
119
|
+
str = jsFileText;
|
|
120
|
+
const pkgType = await getPackageType();
|
|
121
|
+
switch (pkgType) {
|
|
122
|
+
case "commonjs":
|
|
123
|
+
configFile = "susee.config.mjs";
|
|
124
|
+
break;
|
|
125
|
+
case "esm":
|
|
126
|
+
configFile = "susee.config.js";
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const configFilePath = path.resolve(process.cwd(), configFile);
|
|
131
|
+
if (fs.existsSync(configFilePath)) await fs.promises.unlink(configFilePath);
|
|
132
|
+
await fs.promises.writeFile(configFilePath, str);
|
|
133
|
+
console.info(
|
|
134
|
+
tcolor.cyan(`Susee config file ${configFile} is created at project root`),
|
|
135
|
+
);
|
|
136
|
+
}
|