jiek 1.1.12 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,11 +1,20 @@
1
1
  {
2
2
  "name": "jiek",
3
3
  "type": "module",
4
- "version": "1.1.12",
5
- "description": "YiJie's personal kits.",
4
+ "version": "2.0.0",
5
+ "description": "A lightweight toolkit for compiling and managing libraries based on `package.json` metadata and suitable for `Monorepo`.",
6
+ "author": "YiJie <yijie4188@gmail.com>",
7
+ "repository": {
8
+ "url": "nwylzw/jiek",
9
+ "directory": "packages/jiek"
10
+ },
11
+ "homepage": "https://github.com/NWYLZW/jiek/tree/master/packages/jiek#readme",
12
+ "bugs": "https://github.com/NWYLZW/jiek/issues?q=is%3Aissue+is%3Aopen+jiek",
6
13
  "bin": {
7
14
  "jiek": "bin/jiek.js",
8
- "jk": "bin/jiek.js"
15
+ "jk": "bin/jiek.js",
16
+ "jiek-build": "bin/jiek-build.js",
17
+ "jb": "bin/jiek-build.js"
9
18
  },
10
19
  "files": [
11
20
  "dist",
@@ -26,6 +35,11 @@
26
35
  "require": "./dist/cli.cjs",
27
36
  "default": "./dist/cli.js"
28
37
  },
38
+ "./cli-only-build": {
39
+ "source": "./src/cli-only-build.ts",
40
+ "require": "./dist/cli-only-build.cjs",
41
+ "default": "./dist/cli-only-build.js"
42
+ },
29
43
  "./rollup": {
30
44
  "source": "./src/rollup/index.ts",
31
45
  "require": "./dist/rollup/index.cjs",
@@ -36,12 +50,10 @@
36
50
  "#~/*": "./src/*"
37
51
  },
38
52
  "dependencies": {
39
- "@jiek/rollup-plugin-dts": "^6.1.2",
53
+ "@jiek/rollup-plugin-dts": "^6.2.1",
40
54
  "@rollup/plugin-commonjs": "^28.0.0",
41
55
  "@rollup/plugin-json": "^6.0.1",
42
56
  "@rollup/plugin-node-resolve": "^15.3.0",
43
- "@rollup/plugin-terser": "^0.4.4",
44
- "autoprefixer": "^10.4.16",
45
57
  "cli-progress": "^3.12.0",
46
58
  "commander": "^12.0.0",
47
59
  "detect-indent": "^6.1.0",
@@ -50,21 +62,24 @@
50
62
  "js-yaml": "^4.1.0",
51
63
  "jsonc-parser": "^3.2.1",
52
64
  "rollup": "4.13.2",
53
- "rollup-plugin-esbuild": "^6.1.0",
54
- "typescript": "^5.0.0",
55
65
  "@jiek/pkger": "^0.2.0",
56
66
  "@jiek/utils": "^0.2.3"
57
67
  },
58
68
  "optionalDependencies": {
69
+ "@rollup/plugin-terser": "^0.4.4",
59
70
  "@pnpm/filter-workspace-packages": "^7.2.13",
60
71
  "esbuild-register": "^3.5.0",
61
72
  "postcss": "^8.4.47",
62
- "rollup-plugin-postcss": "^4.0.2"
73
+ "rollup-plugin-postcss": "^4.0.2",
74
+ "rollup-plugin-esbuild": "^6.1.0",
75
+ "rollup-plugin-swc3": "^0.12.1",
76
+ "typescript": "^4.0.0||^5.0.0"
63
77
  },
64
78
  "devDependencies": {
65
79
  "@npm/types": "^1.0.2",
66
80
  "@pnpm/filter-workspace-packages": "^7.2.13",
67
81
  "@pnpm/workspace.pkgs-graph": "^2.0.15",
82
+ "@rollup/plugin-terser": "^0.4.4",
68
83
  "@types/cli-progress": "^3.11.5",
69
84
  "@types/inquirer": "^9.0.7",
70
85
  "@types/js-yaml": "^4.0.9",
@@ -73,10 +88,12 @@
73
88
  "micromatch": "^4.0.5",
74
89
  "node-sass": "^9.0.0",
75
90
  "postcss": "^8.4.47",
76
- "rollup-plugin-postcss": "^4.0.2"
91
+ "rollup-plugin-postcss": "^4.0.2",
92
+ "rollup-plugin-esbuild": "^6.1.0",
93
+ "rollup-plugin-swc3": "^0.12.1"
77
94
  },
78
95
  "scripts": {
79
- "prepublish": "jk build --noMin"
96
+ "prepublish": "jb --noMin"
80
97
  },
81
98
  "main": "./dist/index.cjs",
82
99
  "module": "./dist/index.js",
@@ -0,0 +1,7 @@
1
+ import './utils/filterSupport'
2
+ import './commands/base'
3
+ import './commands/build'
4
+
5
+ import { program } from 'commander'
6
+
7
+ program.parse(process.argv)
package/src/cli.ts CHANGED
@@ -1,9 +1,3 @@
1
- import './utils/filterSupport'
2
- import './commands/base'
3
- import './commands/build'
4
1
  import './commands/init'
5
2
  import './commands/publish'
6
-
7
- import { program } from 'commander'
8
-
9
- program.parse(process.argv)
3
+ import 'jiek/cli-only-build'
@@ -1,8 +1,18 @@
1
1
  import { program } from 'commander'
2
2
  import pkg from 'jiek/package.json'
3
3
 
4
+ import { filterDescription } from '#~/commands/descriptions.ts'
5
+ import { IS_WORKSPACE } from '#~/commands/meta.ts'
6
+ import { type } from '#~/utils/filterSupport.ts'
7
+
4
8
  program
9
+ .name('jk/jiek')
5
10
  .version(pkg.version)
6
- .description(pkg.description)
7
- .option('--root <root>', 'root path')
8
- .option('-c, --config-path <configPath>', 'config path')
11
+ .description(`${pkg.description} - Version ${pkg.version}`)
12
+ .option('--root <root>', 'The root path of the project')
13
+ .option('-c, --config-path <configPath>', 'Custom jiek config path')
14
+
15
+ if (type !== '' && IS_WORKSPACE) {
16
+ program
17
+ .option('-f, --filter <filter>', filterDescription)
18
+ }
@@ -6,13 +6,16 @@ import { MultiBar, Presets } from 'cli-progress'
6
6
  import { program } from 'commander'
7
7
  import { execaCommand } from 'execa'
8
8
 
9
- import { actionDone, actionRestore } from '../inner'
9
+ import { entriesDescription, filterDescription, outdirDescription } from '#~/commands/descriptions.ts'
10
+ import { IS_WORKSPACE } from '#~/commands/meta.ts'
11
+ import type { ProjectsGraph } from '#~/utils/filterSupport.ts'
12
+ import { filterPackagesGraph, getSelectedProjectsGraph } from '#~/utils/filterSupport.ts'
13
+ import { getWD } from '#~/utils/getWD.ts'
14
+ import { loadConfig } from '#~/utils/loadConfig.ts'
15
+ import { tsRegisterName } from '#~/utils/tsRegister.ts'
16
+
10
17
  import type { RollupProgressEvent, TemplateOptions } from '../rollup/base'
11
- import type { ProjectsGraph } from '../utils/filterSupport'
12
- import { filterPackagesGraph, getSelectedProjectsGraph } from '../utils/filterSupport'
13
- import { loadConfig } from '../utils/loadConfig'
14
- import { tsRegisterName } from '../utils/tsRegister'
15
- import { outdirDescription } from './descriptions'
18
+ import { BUILDER_TYPE_PACKAGE_NAME_MAP, BUILDER_TYPES } from '../rollup/base'
16
19
 
17
20
  declare module 'jiek' {
18
21
  export interface Config {
@@ -33,13 +36,21 @@ module.exports = require('jiek/rollup').template(${JSON.stringify(manifest, null
33
36
 
34
37
  const require = createRequire(import.meta.url)
35
38
 
39
+ const isDefault = process.env.JIEK_IS_ONLY_BUILD === 'true'
40
+
36
41
  const description = `
37
- Build the package according to the 'exports' field in the package.json.
38
- If you want to rewrite the rollup command options, you can pass the options after '--'.
39
- e.g. \`jiek build -- --watch\`
42
+ Build the package according to the 'exports' field from the package.json.
43
+ If you want to rewrite the \`rollup\` command options, you can pass the options after '--'.
44
+ ${isDefault ? 'This command is the default command.' : ''}
40
45
  `.trim()
41
46
 
42
- interface BuildOptions extends Record<string, unknown> {
47
+ interface BuildOptions {
48
+ /**
49
+ * Auto-detect the builder from the installed dependencies.
50
+ * If the builder is not installed, it will prompt the user to install it.
51
+ * If exists multiple builders, it will fall back to the 'esbuild'.
52
+ */
53
+ type?: typeof BUILDER_TYPES[number]
43
54
  /**
44
55
  * The output directory of the build, which relative to the target subpackage root directory.
45
56
  * Support with variables: 'PKG_NAME',
@@ -48,9 +59,11 @@ interface BuildOptions extends Record<string, unknown> {
48
59
  * @default 'dist'
49
60
  */
50
61
  outdir: string
62
+ watch: boolean
51
63
  silent: boolean
52
- entries: string
53
64
  verbose: boolean
65
+ entries?: string
66
+ external?: string
54
67
  noJs: boolean
55
68
  noDts: boolean
56
69
  noMin: boolean
@@ -59,6 +72,53 @@ interface BuildOptions extends Record<string, unknown> {
59
72
  */
60
73
  noClean: boolean
61
74
  onlyMin: boolean
75
+ /**
76
+ * The type of minify, support 'terser' and 'builder'.
77
+ *
78
+ * @default 'builder'
79
+ */
80
+ minType?: string
81
+ /**
82
+ * The path of the tsconfig file which is used to generate js and dts files.
83
+ * If not specified, it will be loaded from:
84
+ * - ./tsconfig.json
85
+ * - ./tsconfig.dts.json
86
+ * - ./tsconfig.build.json
87
+ */
88
+ tsconfig?: string
89
+ /**
90
+ * The path of the tsconfig file which is used to generate dts files.
91
+ * If not specified, it will be loaded from:
92
+ * - ./tsconfig.json
93
+ * - ./tsconfig.dts.json
94
+ */
95
+ dtsconfig?: string
96
+ }
97
+
98
+ async function checkDependency(dependency: string) {
99
+ try {
100
+ require.resolve(dependency)
101
+ } catch (e) {
102
+ console.error(`The package '${dependency}' is not installed, please install it first.`)
103
+ const answer = prompt('Do you want to install it now? (Y/n)', 'Y')
104
+ const { notWorkspace } = getWD()
105
+ if (answer === 'Y') {
106
+ await execaCommand(`pnpm install -${notWorkspace ? '' : 'w'}D ${dependency}`)
107
+ } else {
108
+ return
109
+ }
110
+ }
111
+ }
112
+
113
+ let DEFAULT_BUILDER_TYPE: typeof BUILDER_TYPES[number]
114
+ Object.entries(BUILDER_TYPE_PACKAGE_NAME_MAP).forEach(([type, packageName]) => {
115
+ try {
116
+ require.resolve(packageName)
117
+ DEFAULT_BUILDER_TYPE = type as typeof BUILDER_TYPES[number]
118
+ } catch { /* empty */ }
119
+ })
120
+ if (!DEFAULT_BUILDER_TYPE!) {
121
+ DEFAULT_BUILDER_TYPE = 'esbuild'
62
122
  }
63
123
 
64
124
  function parseBoolean(v?: unknown) {
@@ -66,38 +126,109 @@ function parseBoolean(v?: unknown) {
66
126
  return Boolean(v)
67
127
  }
68
128
 
69
- program
70
- .command('build')
129
+ const buildFilterDescription = `
130
+ ${filterDescription}
131
+ If you pass the --filter option, it will merge into the filters of the command.
132
+ `.trim()
133
+
134
+ const buildEntriesDescription = `
135
+ ${entriesDescription}
136
+ If you pass the --entries option, it will merge into the entries of the command.
137
+ `.trim()
138
+
139
+ const command = isDefault
140
+ ? program
141
+ .name('jb/jiek-build')
142
+ .helpCommand(false)
143
+ : program
144
+
145
+ if (IS_WORKSPACE) {
146
+ if (isDefault) {
147
+ command.argument('[filters]', buildFilterDescription)
148
+ } else {
149
+ command.command('build [filters]')
150
+ }
151
+ } else {
152
+ if (isDefault) {
153
+ command.argument('[entries]', buildEntriesDescription)
154
+ } else {
155
+ command.command('build [entries]')
156
+ }
157
+ }
158
+
159
+ command
71
160
  .description(description)
161
+ .option('-t, --type <TYPE>', `The type of build, support ${BUILDER_TYPES.map(s => `"${s}"`).join(', ')}.`, v => {
162
+ if (!BUILDER_TYPES.includes(v as any)) {
163
+ throw new Error(`The value of 'type' must be ${BUILDER_TYPES.map(s => `"${s}"`).join(', ')}`)
164
+ }
165
+ return String(v)
166
+ }, 'esbuild')
72
167
  .option('-o, --outdir <OUTDIR>', outdirDescription, String, 'dist')
73
- .option('-e, --entries <ENTRIES>', "Specify the entries of the package.json's 'exports' field.(support glob)")
168
+ .option('-e, --entries <ENTRIES>', entriesDescription)
169
+ .option('--external <EXTERNAL>', 'Specify the external dependencies of the package.', String)
74
170
  .option('-nj, --noJs', 'Do not output js files.', parseBoolean)
75
171
  .option('-nd, --noDts', 'Do not output dts files.', parseBoolean)
76
172
  .option('-nm, --noMin', 'Do not output minify files.', parseBoolean)
173
+ .option(
174
+ '--minType <MINTYPE>',
175
+ 'The type of minify, support "builder" and "terser".',
176
+ v => {
177
+ if (!['builder', 'terser'].includes(v)) {
178
+ throw new Error('The value of `minType` must be "builder" or "terser"')
179
+ }
180
+ return String(v)
181
+ }
182
+ )
77
183
  .option('-nc, --noClean', 'Do not clean the output directory before building.', parseBoolean)
78
184
  .option(
79
185
  '-om, --onlyMin',
80
186
  'Only output minify files, but dts files will still be output, it only replaces the js files.',
81
187
  parseBoolean
82
188
  )
189
+ .option('--tsconfig <TSCONFIG>', 'The path of the tsconfig file which is used to generate js and dts files.', String)
190
+ .option('--dtsconfig <DTSCONFIG>', 'The path of the tsconfig file which is used to generate dts files.', String)
191
+ .option('-w, --watch', 'Watch the file changes.', parseBoolean)
83
192
  .option('-s, --silent', "Don't display logs.", parseBoolean)
84
193
  .option('-v, --verbose', 'Display debug logs.', parseBoolean)
85
- .action(async ({
86
- outdir,
87
- silent,
88
- entries,
89
- verbose,
90
- noJs: withoutJs,
91
- noDts: withoutDts,
92
- noMin: withoutMin,
93
- noClean,
94
- onlyMin: onlyMin
95
- }: BuildOptions) => {
194
+ .action(async (commandFiltersOrEntries: string | undefined, options: BuildOptions) => {
195
+ /* eslint-disable prefer-const */
196
+ let {
197
+ type,
198
+ outdir,
199
+ watch,
200
+ silent,
201
+ verbose,
202
+ entries: optionEntries,
203
+ external,
204
+ noJs: withoutJs,
205
+ noDts: withoutDts,
206
+ noMin: withoutMin,
207
+ minType: minifyType,
208
+ noClean,
209
+ onlyMin,
210
+ tsconfig,
211
+ dtsconfig
212
+ } = options
213
+ /* eslint-enable prefer-const */
214
+ const resolvedType = type ?? DEFAULT_BUILDER_TYPE
215
+ if (!withoutJs) {
216
+ await checkDependency(BUILDER_TYPE_PACKAGE_NAME_MAP[resolvedType]!)
217
+ if (minifyType === 'builder') {
218
+ minifyType = resolvedType
219
+ }
220
+ }
221
+ if (!withoutMin) {
222
+ await checkDependency(
223
+ {
224
+ ...BUILDER_TYPE_PACKAGE_NAME_MAP,
225
+ terser: '@rollup/plugin-terser'
226
+ }[resolvedType]!
227
+ )
228
+ }
96
229
  let shouldPassThrough = false
97
230
 
98
- const passThroughOptions = program
99
- .parseOptions(process.argv)
100
- .unknown
231
+ const passThroughOptions = process.argv
101
232
  .reduce(
102
233
  (acc, value) => {
103
234
  if (shouldPassThrough) {
@@ -110,7 +241,6 @@ program
110
241
  },
111
242
  [] as string[]
112
243
  )
113
- actionRestore()
114
244
  const { build } = loadConfig()
115
245
  silent = silent ?? build?.silent ?? false
116
246
 
@@ -121,15 +251,27 @@ program
121
251
  throw new Error('Cannot use --without-js and --only-minify at the same time')
122
252
  }
123
253
 
254
+ let entries: string | undefined = [
255
+ optionEntries,
256
+ IS_WORKSPACE ? undefined : commandFiltersOrEntries
257
+ ].filter(Boolean).join(',')
258
+ if (entries.length === 0) {
259
+ entries = undefined
260
+ }
124
261
  const env = {
125
262
  ...process.env,
263
+ JIEK_BUILDER: type,
126
264
  JIEK_OUT_DIR: outdir,
127
265
  JIEK_CLEAN: String(!noClean),
128
266
  JIEK_ENTRIES: entries,
267
+ JIEK_EXTERNAL: external,
129
268
  JIEK_WITHOUT_JS: String(withoutJs),
130
269
  JIEK_WITHOUT_DTS: String(withoutDts),
131
270
  JIEK_WITHOUT_MINIFY: String(withoutMin),
132
- JIEK_ONLY_MINIFY: String(onlyMin)
271
+ JIEK_ONLY_MINIFY: String(onlyMin),
272
+ JIEK_MINIFY_TYPE: minifyType,
273
+ JIEK_TSCONFIG: tsconfig,
274
+ JIEK_DTSCONFIG: dtsconfig
133
275
  }
134
276
 
135
277
  const multiBars = new MultiBar({
@@ -169,12 +311,15 @@ program
169
311
  `${escapeManifestName ?? `anonymous-${i++}`}.rollup.config.js`
170
312
  )
171
313
  fs.writeFileSync(configFile, FILE_TEMPLATE(manifest))
172
- let prefix = ''
314
+ const command = [rollupBinaryPath, '--silent', '-c', configFile]
173
315
  if (tsRegisterName) {
174
- prefix = `node -r ${tsRegisterName} `
316
+ command.unshift(`node -r ${tsRegisterName}`)
317
+ }
318
+ if (watch) {
319
+ command.push('--watch')
175
320
  }
176
- const command = [`${prefix}${rollupBinaryPath} --silent -c ${configFile}`, ...passThroughOptions].join(' ')
177
- const child = execaCommand(command, {
321
+ command.push(...passThroughOptions)
322
+ const child = execaCommand(command.join(' '), {
178
323
  ipc: true,
179
324
  cwd: dir,
180
325
  env: {
@@ -202,7 +347,11 @@ program
202
347
  conditions
203
348
  }))
204
349
  )
205
- console.log(`Package '${manifest.name}' has ${targetsLength} targets to build`)
350
+ let initMessage = `Package '${manifest.name}' has ${targetsLength} targets to build`
351
+ if (watch) {
352
+ initMessage += ' and watching...'
353
+ }
354
+ console.log(initMessage)
206
355
  leafs.forEach(({ input }) => {
207
356
  inputMaxLen = Math.max(inputMaxLen, input.length)
208
357
  })
@@ -285,9 +434,23 @@ program
285
434
  })
286
435
  )
287
436
  }
288
- const filters = (program.getOptionValue('filter') as string | undefined)?.split(',')
437
+ const commandFilters = IS_WORKSPACE ? commandFiltersOrEntries : undefined
438
+ const filters = [
439
+ ...new Set([
440
+ ...(program.getOptionValue('filter') as string | undefined)
441
+ ?.split(',')
442
+ .map(s => s.trim())
443
+ .filter(s => s.length > 0)
444
+ ?? [],
445
+ ...commandFilters
446
+ ?.split(',')
447
+ .map(s => s.trim())
448
+ .filter(s => s.length > 0)
449
+ ?? []
450
+ ])
451
+ ]
289
452
  try {
290
- if (filters) {
453
+ if (filters.length > 0) {
291
454
  const packages = await filterPackagesGraph(filters)
292
455
  await Promise.all(packages.map(buildPackage))
293
456
  } else {
@@ -296,6 +459,4 @@ program
296
459
  } finally {
297
460
  multiBars.stop()
298
461
  }
299
-
300
- actionDone()
301
462
  })
@@ -1,3 +1,15 @@
1
+ export const entriesDescription = `
2
+ Specify the build entry-points of the package.json's 'exports' field.
3
+ Support glob pattern and array.
4
+ .e.g. '.', './*', './sub/*', './a,./b'.
5
+ `.trim()
6
+
7
+ export const filterDescription = `
8
+ Filter the packages from the workspace.
9
+ Support fuzzy match and array.
10
+ .e.g. 'core,utils'.
11
+ `.trim()
12
+
1
13
  export const outdirDescription = `
2
14
  The output directory of the build, which relative to the target subpackage root directory.
3
15
  Support with variables: 'PKG_NAME',
@@ -0,0 +1,5 @@
1
+ import { getWD } from '#~/utils/getWD.ts'
2
+
3
+ const { notWorkspace } = getWD()
4
+
5
+ export const IS_WORKSPACE = !notWorkspace
@@ -17,6 +17,13 @@ export interface ConfigGenerateContext {
17
17
 
18
18
  export type OutputControl = boolean | ((context: ConfigGenerateContext) => boolean)
19
19
 
20
+ export const BUILDER_TYPES = ['esbuild', 'swc'] as const
21
+
22
+ export const BUILDER_TYPE_PACKAGE_NAME_MAP = {
23
+ esbuild: 'rollup-plugin-esbuild',
24
+ swc: 'rollup-plugin-swc3'
25
+ }
26
+
20
27
  export interface TemplateOptions {
21
28
  /**
22
29
  * When the user configures type: module, the generated output from entry points that don't
@@ -27,6 +34,21 @@ export interface TemplateOptions {
27
34
  * @default true
28
35
  */
29
36
  crossModuleConvertor?: boolean
37
+ /**
38
+ * Auto-detect the builder from the installed dependencies.
39
+ * If the builder is not installed, it will prompt the user to install it.
40
+ * If exists multiple builders, it will fall back to the 'esbuild'.
41
+ *
42
+ * @default 'esbuild'
43
+ */
44
+ builder?:
45
+ | typeof BUILDER_TYPES[number]
46
+ | ({
47
+ type: 'esbuild'
48
+ } & import('rollup-plugin-esbuild').Options)
49
+ | ({
50
+ type: 'swc'
51
+ } & import('rollup-plugin-swc3').PluginOptions)
30
52
  output?: {
31
53
  /**
32
54
  * @default true
@@ -35,6 +57,24 @@ export interface TemplateOptions {
35
57
  * When minify is set to 'only-minify', the output will direct output minified files.
36
58
  */
37
59
  minify?: boolean | 'only-minify'
60
+ minifyOptions?:
61
+ | typeof BUILDER_TYPES[number]
62
+ | 'terser'
63
+ | (
64
+ {
65
+ type: 'terser'
66
+ } & import('@rollup/plugin-terser').Options
67
+ )
68
+ | (
69
+ {
70
+ type: 'esbuild'
71
+ } & Parameters<typeof import('rollup-plugin-esbuild').minify>[0]
72
+ )
73
+ | (
74
+ {
75
+ type: 'swc'
76
+ } & Parameters<typeof import('rollup-plugin-swc3').minify>[0]
77
+ )
38
78
  /**
39
79
  * @default 'dist'
40
80
  */
@@ -44,6 +84,10 @@ export interface TemplateOptions {
44
84
  js?: OutputControl
45
85
  dts?: OutputControl
46
86
  }
87
+ /**
88
+ * Set the external dependencies of the package.
89
+ */
90
+ external?: (string | RegExp)[]
47
91
  plugins?:
48
92
  | InputPluginOption
49
93
  | ((type: 'js' | 'dts', context: ConfigGenerateContext) => InputPluginOption)