jiek 2.1.12 → 2.1.13-alpha.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "jiek",
3
3
  "type": "module",
4
- "version": "2.1.12",
4
+ "version": "2.1.13-alpha.1",
5
5
  "description": "A lightweight toolkit for compiling and managing libraries based on `package.json` metadata and suitable for `Monorepo`.",
6
6
  "author": "YiJie <yijie4188@gmail.com>",
7
7
  "homepage": "https://github.com/NWYLZW/jiek/tree/master/packages/jiek#readme",
@@ -10,12 +10,22 @@
10
10
  "directory": "packages/jiek"
11
11
  },
12
12
  "bugs": "https://github.com/NWYLZW/jiek/issues?q=is%3Aissue+is%3Aopen+jiek",
13
+ "keywords": [
14
+ "cli",
15
+ "zero-config",
16
+ "bundler",
17
+ "library",
18
+ "monorepo",
19
+ "builder",
20
+ "rollup",
21
+ "workspace"
22
+ ],
13
23
  "exports": {
14
24
  "./package.json": "./package.json",
15
25
  ".": {
16
26
  "jiek/__source__": "./src/index.ts",
17
- "require": "./dist/index.cjs",
18
- "default": "./dist/index.js"
27
+ "require": "./\"dist\"/index.cjs",
28
+ "default": "./\"dist\"/index.js"
19
29
  },
20
30
  "./bin-helper": {
21
31
  "require": "./bin-helper.cjs",
@@ -23,18 +33,18 @@
23
33
  },
24
34
  "./cli": {
25
35
  "jiek/__source__": "./src/cli.ts",
26
- "require": "./dist/cli.cjs",
27
- "default": "./dist/cli.js"
36
+ "require": "./\"dist\"/cli.cjs",
37
+ "default": "./\"dist\"/cli.js"
28
38
  },
29
39
  "./cli-only-build": {
30
40
  "jiek/__source__": "./src/cli-only-build.ts",
31
- "require": "./dist/cli-only-build.cjs",
32
- "default": "./dist/cli-only-build.js"
41
+ "require": "./\"dist\"/cli-only-build.cjs",
42
+ "default": "./\"dist\"/cli-only-build.js"
33
43
  },
34
44
  "./rollup": {
35
45
  "jiek/__source__": "./src/rollup/index.ts",
36
- "require": "./dist/rollup/index.cjs",
37
- "default": "./dist/rollup/index.js"
46
+ "require": "./\"dist\"/rollup/index.cjs",
47
+ "default": "./\"dist\"/rollup/index.js"
38
48
  }
39
49
  },
40
50
  "imports": {
@@ -55,7 +65,7 @@
55
65
  "rollup-plugin-postcss": "^4.0.2",
56
66
  "rollup-plugin-swc3": "^0.12.1",
57
67
  "typescript": "^4.0.0||^5.0.0",
58
- "vite-bundle-analyzer": "^0.15.1"
68
+ "vite-bundle-analyzer": "^0.15.2"
59
69
  },
60
70
  "dependencies": {
61
71
  "@inquirer/prompts": "^7.1.0",
@@ -71,6 +81,7 @@
71
81
  "execa": "~9.3.1",
72
82
  "js-yaml": "^4.1.0",
73
83
  "jsonc-parser": "^3.2.1",
84
+ "koa": "^2.15.3",
74
85
  "rollup": "^4.0.0",
75
86
  "@jiek/pkger": "^0.2.1",
76
87
  "@jiek/utils": "^0.2.3"
@@ -105,7 +116,7 @@
105
116
  }
106
117
  },
107
118
  "scripts": {
108
- "prepublish": "jb -nm && jk",
119
+ "prepublish": "pnpm test ./tests/publish.spec.ts && jb -nm && jk",
109
120
  "test": "vitest run"
110
121
  },
111
122
  "typesVersions": {
@@ -119,6 +130,6 @@
119
130
  ]
120
131
  }
121
132
  },
122
- "main": "./dist/index.cjs",
123
- "module": "./dist/index.js"
133
+ "main": "./\"dist\"/index.cjs",
134
+ "module": "./\"dist\"/index.js"
124
135
  }
package/src/bridge.ts ADDED
@@ -0,0 +1,46 @@
1
+ import type { Module } from '#~/rollup/bundle-analyzer.ts'
2
+
3
+ import { sendMessage } from 'execa'
4
+
5
+ export const bridgeDisabledRef = { value: false }
6
+
7
+ export interface RollupBuildEntryCtx {
8
+ type: 'esm' | 'cjs'
9
+ name: string
10
+ path: string
11
+ exportConditions: string[]
12
+ input: string
13
+ }
14
+
15
+ export interface RollupBuildEventMap {
16
+ init: {
17
+ leafMap: Map<string, string[][]>
18
+ targetsLength: number
19
+ }
20
+ progress: RollupBuildEntryCtx & {
21
+ tags?: string[]
22
+ event?: string
23
+ message?: string
24
+ }
25
+ watchChange: RollupBuildEntryCtx & {
26
+ id: string
27
+ }
28
+ modulesAnalyze: RollupBuildEntryCtx & {
29
+ modules: Module[]
30
+ }
31
+ debug: unknown
32
+ }
33
+
34
+ export type RollupBuildEvent = keyof RollupBuildEventMap extends infer K
35
+ ? K extends infer Item extends keyof RollupBuildEventMap ? {
36
+ type: Item
37
+ data: RollupBuildEventMap[Item]
38
+ }
39
+ : never
40
+ : never
41
+
42
+ export const publish = async <K extends keyof RollupBuildEventMap>(type: K, data: RollupBuildEventMap[K]) => {
43
+ if (bridgeDisabledRef.value) return Promise.resolve()
44
+
45
+ return sendMessage({ type, data })
46
+ }
@@ -1,4 +1,4 @@
1
- import fs, { existsSync, statSync } from 'node:fs'
1
+ import { existsSync, mkdirSync, statSync, writeFileSync } from 'node:fs'
2
2
  import { createRequire } from 'node:module'
3
3
  import path from 'node:path'
4
4
  import process from 'node:process'
@@ -7,18 +7,21 @@ import { confirm } from '@inquirer/prompts'
7
7
  import { MultiBar, Presets } from 'cli-progress'
8
8
  import { program } from 'commander'
9
9
  import { execaCommand } from 'execa'
10
+ import type { renderView } from 'vite-bundle-analyzer'
10
11
 
12
+ import type { RollupBuildEvent } from '#~/bridge.ts'
11
13
  import { entriesDescription, filterDescription, outdirDescription } from '#~/commands/descriptions.ts'
12
14
  import { IS_WORKSPACE } from '#~/commands/meta.ts'
15
+ import type { TemplateOptions } from '#~/rollup/base.ts'
16
+ import { BUILDER_TYPES, BUILDER_TYPE_PACKAGE_NAME_MAP } from '#~/rollup/base.ts'
17
+ import type { Module } from '#~/rollup/bundle-analyzer.ts'
18
+ import { createServer } from '#~/server.ts'
13
19
  import type { ProjectsGraph } from '#~/utils/filterSupport.ts'
14
20
  import { filterPackagesGraph, getSelectedProjectsGraph } from '#~/utils/filterSupport.ts'
15
21
  import { getWD } from '#~/utils/getWD.ts'
16
22
  import { loadConfig } from '#~/utils/loadConfig.ts'
17
23
  import { tsRegisterName } from '#~/utils/tsRegister.ts'
18
24
 
19
- import type { RollupProgressEvent, TemplateOptions } from '../rollup/base'
20
- import { BUILDER_TYPES, BUILDER_TYPE_PACKAGE_NAME_MAP } from '../rollup/base'
21
-
22
25
  declare module 'jiek' {
23
26
  export interface Config {
24
27
  build?: TemplateOptions & {
@@ -56,7 +59,6 @@ interface BuildOptions {
56
59
  * @default 'server'
57
60
  */
58
61
  'ana.mode': string
59
- 'ana.port'?: number
60
62
  'ana.open'?: boolean
61
63
  /**
62
64
  * @default 'parsed'
@@ -77,6 +79,12 @@ interface BuildOptions {
77
79
  */
78
80
  outdir: string
79
81
  watch: boolean
82
+ /**
83
+ * The port of the server.
84
+ *
85
+ * @default 8888
86
+ */
87
+ port: number
80
88
  silent: boolean
81
89
  verbose: boolean
82
90
  entries?: string
@@ -207,12 +215,12 @@ command = command
207
215
 
208
216
  command = command
209
217
  .option('-w, --watch', 'Watch the file changes.', parseBoolean)
218
+ .option('-p, --port <PORT>', 'The port of the server.', Number.parseInt, 8888)
210
219
 
211
220
  command = command
212
221
  .option('--ana', 'Enable the bundle analyzer.', parseBoolean)
213
222
  .option('--ana.dir <DIR>', 'The directory of the bundle analyzer.', '.jk-analyses')
214
223
  .option('--ana.mode <MODE>', 'The mode of the bundle analyzer, support "static", "json" and "server".', 'server')
215
- .option('--ana.port <PORT>', 'The port of the bundle analyzer.', Number.parseInt)
216
224
  .option('--ana.open', 'Open the bundle analyzer in the browser.', parseBoolean)
217
225
  .option(
218
226
  '--ana.size <SIZE>',
@@ -274,18 +282,47 @@ command
274
282
  [] as string[]
275
283
  )
276
284
 
285
+ const modules: Module[] = []
286
+ const cjsModules: Module[] = []
287
+ const esmModules: Module[] = []
288
+ let render: typeof renderView | undefined
277
289
  const analyzer = options.ana
278
290
  ? {
279
291
  dir: options['ana.dir'],
280
292
  mode: options['ana.mode'],
281
- port: options['ana.port'],
282
293
  open: options['ana.open'],
283
294
  size: options['ana.size']
284
295
  }
285
296
  : undefined
297
+ if (
298
+ options.ana
299
+ && ![
300
+ 'stat',
301
+ 'parsed',
302
+ 'gzip'
303
+ ].includes(analyzer?.size ?? '')
304
+ ) {
305
+ throw new Error('The value of `ana.size` must be "stat", "parsed" or "gzip"')
306
+ }
307
+ const server = analyzer && createServer(options.port, 'localhost')
286
308
 
287
309
  if (analyzer) {
288
310
  await checkDependency('vite-bundle-analyzer')
311
+ const { renderView } = await import('vite-bundle-analyzer')
312
+ render = renderView
313
+ }
314
+ const anaPaths = new Set<string>()
315
+ const refreshAnalyzer = async (subPath = '', renderModules = modules) => {
316
+ if (!(analyzer && server && render)) return
317
+ const p = `/ana${subPath}`
318
+ anaPaths.add(p)
319
+ void server.renderTo(
320
+ p,
321
+ await render(renderModules, {
322
+ title: `Jiek Analyzer - ${subPath}`,
323
+ mode: analyzer.size as 'stat' | 'parsed' | 'gzip'
324
+ })
325
+ )
289
326
  }
290
327
 
291
328
  const { build } = loadConfig()
@@ -336,12 +373,15 @@ command
336
373
  throw new Error('no package found')
337
374
  }
338
375
  const wdNodeModules = path.resolve(wd, 'node_modules')
339
- if (!fs.existsSync(wdNodeModules)) {
340
- fs.mkdirSync(wdNodeModules)
376
+ if (!existsSync(wdNodeModules)) {
377
+ mkdirSync(wdNodeModules)
341
378
  }
342
- const jiekTempDir = (...paths: string[]) => path.resolve(wdNodeModules, '.jiek', ...paths)
343
- if (!fs.existsSync(jiekTempDir())) {
344
- fs.mkdirSync(jiekTempDir())
379
+ const resolveByJiekTemp = (...paths: string[]) => path.resolve(wdNodeModules, '.jiek', ...paths)
380
+ const jiekTemp = resolveByJiekTemp()
381
+ if (!existsSync(jiekTemp)) {
382
+ try {
383
+ mkdirSync(jiekTemp)
384
+ } catch {}
345
385
  }
346
386
 
347
387
  const rollupBinaryPath = require.resolve('rollup')
@@ -355,15 +395,15 @@ command
355
395
  if (analyzer) {
356
396
  const anaDir = path.resolve(dir, analyzer.dir)
357
397
  if (!existsSync(anaDir)) {
358
- fs.mkdirSync(anaDir, { recursive: true })
398
+ mkdirSync(anaDir, { recursive: true })
359
399
  }
360
400
  const gitIgnorePath = path.resolve(anaDir, '.gitignore')
361
401
  if (!existsSync(gitIgnorePath)) {
362
- fs.writeFileSync(gitIgnorePath, '*\n!.gitignore\n')
402
+ writeFileSync(gitIgnorePath, '*\n!.gitignore\n')
363
403
  }
364
404
  const npmIgnorePath = path.resolve(anaDir, '.npmignore')
365
405
  if (!existsSync(npmIgnorePath)) {
366
- fs.writeFileSync(npmIgnorePath, '*\n')
406
+ writeFileSync(npmIgnorePath, '*\n')
367
407
  }
368
408
  if (!statSync(anaDir).isDirectory()) {
369
409
  throw new Error(`The directory '${anaDir}' is not a directory.`)
@@ -372,10 +412,10 @@ command
372
412
 
373
413
  // TODO support auto build child packages in workspaces
374
414
  const escapeManifestName = manifest.name.replace(/^@/g, '').replace(/\//g, '+')
375
- const configFile = jiekTempDir(
415
+ const configFile = resolveByJiekTemp(
376
416
  `${escapeManifestName ?? `anonymous-${i++}`}.rollup.config.js`
377
417
  )
378
- fs.writeFileSync(configFile, FILE_TEMPLATE(manifest))
418
+ writeFileSync(configFile, FILE_TEMPLATE(manifest))
379
419
  const command = [rollupBinaryPath, '--silent', '-c', configFile]
380
420
  if (tsRegisterName != null) {
381
421
  command.unshift(`node -r ${tsRegisterName}`)
@@ -397,97 +437,152 @@ command
397
437
  const times: Record<string, number> = {}
398
438
  const locks: Record<string, boolean> = {}
399
439
  let inputMaxLen = 10
400
- child.on('message', (e: RollupProgressEvent) => {
401
- // eslint-disable-next-line no-console,ts/no-unsafe-argument
402
- if (e.type === 'debug') console.log(...(Array.isArray(e.data) ? e.data : [e.data]))
403
- })
404
- !silent && child.on('message', (e: RollupProgressEvent) => {
405
- if (e.type === 'init') {
406
- const { leafMap, targetsLength } = e.data
407
- const leafs = Array
408
- .from(leafMap.entries())
409
- .flatMap(([input, pathAndCondiions]) =>
410
- pathAndCondiions.map(([path, ...conditions]) => ({
411
- input,
412
- path,
413
- conditions
414
- }))
440
+ child.on('message', (e: RollupBuildEvent) => {
441
+ if (
442
+ silent && [
443
+ 'init',
444
+ 'progress',
445
+ 'watchChange'
446
+ ].includes(e.type)
447
+ ) return
448
+ switch (e.type) {
449
+ case 'init': {
450
+ const { leafMap, targetsLength } = e.data
451
+ const leafs = Array
452
+ .from(leafMap.entries())
453
+ .flatMap(([input, pathAndCondiions]) =>
454
+ pathAndCondiions.map(([path, ...conditions]) => ({
455
+ input,
456
+ path,
457
+ conditions
458
+ }))
459
+ )
460
+ let initMessage = `Package '${manifest.name}' has ${targetsLength} targets to build`
461
+ if (watch) {
462
+ initMessage += ' and watching...'
463
+ }
464
+ // eslint-disable-next-line no-console
465
+ console.log(initMessage)
466
+ leafs.forEach(({ input }) => {
467
+ inputMaxLen = Math.max(inputMaxLen, input.length)
468
+ })
469
+ leafs.forEach(({ input, path }) => {
470
+ const key = `${input}:${path}`
471
+ // eslint-disable-next-line ts/strict-boolean-expressions
472
+ if (bars[key]) return
473
+ bars[key] = multiBars.create(50, 0, {
474
+ pkgName: manifest.name,
475
+ input: input.padEnd(inputMaxLen + 5),
476
+ status: 'waiting'.padEnd(10)
477
+ }, {
478
+ barsize: 20,
479
+ linewrap: true
480
+ })
481
+ })
482
+ break
483
+ }
484
+ case 'progress': {
485
+ const {
486
+ path,
487
+ tags,
488
+ input,
489
+ event,
490
+ message
491
+ } = e.data
492
+ const bar = bars[`${input}:${path}`]
493
+ // eslint-disable-next-line ts/strict-boolean-expressions
494
+ if (!bar) return
495
+ const time = times[`${input}:${path}`]
496
+ bar.update(
497
+ {
498
+ start: 0,
499
+ resolve: 20,
500
+ end: 50
501
+ }[event ?? 'start'] ?? 0,
502
+ {
503
+ input: (
504
+ time
505
+ ? `${input}(x${time.toString().padStart(2, '0')})`
506
+ : input
507
+ ).padEnd(inputMaxLen + 5),
508
+ status: event?.padEnd(10),
509
+ message: `${tags?.join(', ')}: ${message}`
510
+ }
415
511
  )
416
- let initMessage = `Package '${manifest.name}' has ${targetsLength} targets to build`
417
- if (watch) {
418
- initMessage += ' and watching...'
512
+ break
419
513
  }
420
- // eslint-disable-next-line no-console
421
- console.log(initMessage)
422
- leafs.forEach(({ input }) => {
423
- inputMaxLen = Math.max(inputMaxLen, input.length)
424
- })
425
- leafs.forEach(({ input, path }) => {
514
+ case 'watchChange': {
515
+ const {
516
+ path,
517
+ input
518
+ } = e.data
426
519
  const key = `${input}:${path}`
520
+ const bar = bars[key]
427
521
  // eslint-disable-next-line ts/strict-boolean-expressions
428
- if (bars[key]) return
429
- bars[key] = multiBars.create(50, 0, {
430
- pkgName: manifest.name,
431
- input: input.padEnd(inputMaxLen + 5),
432
- status: 'waiting'.padEnd(10)
433
- }, {
434
- barsize: 20,
435
- linewrap: true
436
- })
437
- })
438
- }
439
- if (e.type === 'progress') {
440
- const {
441
- path,
442
- tags,
443
- input,
444
- event,
445
- message
446
- } = e.data
447
- const bar = bars[`${input}:${path}`]
448
- // eslint-disable-next-line ts/strict-boolean-expressions
449
- if (!bar) return
450
- const time = times[`${input}:${path}`]
451
- bar.update(
452
- {
453
- start: 0,
454
- resolve: 20,
455
- end: 50
456
- }[event ?? 'start'] ?? 0,
457
- {
458
- input: (
459
- time
460
- ? `${input}(x${time.toString().padStart(2, '0')})`
461
- : input
462
- ).padEnd(inputMaxLen + 5),
463
- status: event?.padEnd(10),
464
- message: `${tags?.join(', ')}: ${message}`
522
+ if (!bar) return
523
+ let time = times[key] ?? 1
524
+ if (!locks[key]) {
525
+ time += 1
526
+ times[key] = time
527
+ setTimeout(() => {
528
+ locks[key] = false
529
+ }, 100)
530
+ bar.update(0, {
531
+ input: `${input}(x${time.toString().padStart(2, '0')})`.padEnd(inputMaxLen + 5),
532
+ status: 'watching'.padEnd(10),
533
+ message: 'watching...'
534
+ })
465
535
  }
466
- )
467
- }
468
- if (e.type === 'watchChange') {
469
- const {
470
- path,
471
- input
472
- } = e.data
473
- const key = `${input}:${path}`
474
- const bar = bars[key]
475
- // eslint-disable-next-line ts/strict-boolean-expressions
476
- if (!bar) return
477
- let time = times[key] ?? 1
478
- if (!locks[key]) {
479
- time += 1
480
- times[key] = time
481
- setTimeout(() => {
482
- locks[key] = false
483
- }, 100)
484
- bar.update(0, {
485
- input: `${input}(x${time.toString().padStart(2, '0')})`.padEnd(inputMaxLen + 5),
486
- status: 'watching'.padEnd(10),
487
- message: 'watching...'
536
+ locks[key] = true
537
+ break
538
+ }
539
+ case 'modulesAnalyze': {
540
+ const {
541
+ data: {
542
+ type,
543
+ path,
544
+ modules: pkgModules
545
+ }
546
+ } = e
547
+ pkgModules.forEach(m => {
548
+ const newM = {
549
+ ...m,
550
+ filename: `${manifest.name}/${m.filename}`,
551
+ label: `${manifest.name}/${m.label}`
552
+ }
553
+ const pushOrReplace = (arr: Module[]) => {
554
+ const index = arr.findIndex(({ filename }) => filename === newM.filename)
555
+ if (index === -1) {
556
+ arr.push(newM)
557
+ } else {
558
+ arr[index] = newM
559
+ }
560
+ }
561
+ pushOrReplace(modules)
562
+ if (type === 'esm') {
563
+ pushOrReplace(esmModules)
564
+ }
565
+ if (type === 'cjs') {
566
+ pushOrReplace(cjsModules)
567
+ }
488
568
  })
569
+ void refreshAnalyzer()
570
+ void refreshAnalyzer(
571
+ `/${type}`,
572
+ {
573
+ cjs: cjsModules,
574
+ esm: esmModules
575
+ }[type]
576
+ )
577
+ void refreshAnalyzer(`/${type}/${manifest.name}/${path.slice(2)}`, pkgModules)
578
+ break
489
579
  }
490
- locks[key] = true
580
+ case 'debug': {
581
+ // eslint-disable-next-line no-console,ts/no-unsafe-argument
582
+ console.log(...(Array.isArray(e.data) ? e.data : [e.data]))
583
+ break
584
+ }
585
+ default:
491
586
  }
492
587
  })
493
588
  await new Promise<void>((resolve, reject) => {
@@ -504,6 +599,7 @@ command
504
599
  })
505
600
  )
506
601
  }
602
+
507
603
  const commandFilters = IS_WORKSPACE ? commandFiltersOrEntries : undefined
508
604
  const filters = [
509
605
  ...new Set([
@@ -528,5 +624,20 @@ command
528
624
  }
529
625
  } finally {
530
626
  multiBars.stop()
627
+ let message = 'The build is complete'
628
+ if (analyzer) {
629
+ message += ` and the analyzer is running at http://localhost:${options.port}/ana in ${analyzer.mode} mode.\n`
630
+ message += analyzer.open ? ' The browser will open automatically.\n' : ''
631
+ if (anaPaths.size > 0) {
632
+ message += `The analyzer has ${anaPaths.size} pages:\n${
633
+ Array
634
+ .from(anaPaths)
635
+ .map(p => `http://localhost:${options.port}${p}`)
636
+ .join('\n')
637
+ }`
638
+ }
639
+ }
640
+ // eslint-disable-next-line no-console
641
+ !silent && console.log(message)
531
642
  }
532
643
  })