jiek 2.1.12 → 2.1.13
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/dist/cli-only-build.cjs +221 -96
- package/dist/cli-only-build.js +221 -97
- package/dist/rollup/index.cjs +75 -94
- package/dist/rollup/index.js +76 -95
- package/package.json +13 -2
- package/src/bridge.ts +42 -0
- package/src/commands/build.ts +207 -99
- package/src/rollup/base.ts +0 -35
- package/src/rollup/bundle-analyzer.ts +62 -0
- package/src/rollup/index.ts +43 -117
- package/src/server.ts +22 -0
package/src/commands/build.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import
|
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,12 @@ command
|
|
336
373
|
throw new Error('no package found')
|
337
374
|
}
|
338
375
|
const wdNodeModules = path.resolve(wd, 'node_modules')
|
339
|
-
if (!
|
340
|
-
|
376
|
+
if (!existsSync(wdNodeModules)) {
|
377
|
+
mkdirSync(wdNodeModules)
|
341
378
|
}
|
342
379
|
const jiekTempDir = (...paths: string[]) => path.resolve(wdNodeModules, '.jiek', ...paths)
|
343
|
-
if (!
|
344
|
-
|
380
|
+
if (!existsSync(jiekTempDir())) {
|
381
|
+
mkdirSync(jiekTempDir())
|
345
382
|
}
|
346
383
|
|
347
384
|
const rollupBinaryPath = require.resolve('rollup')
|
@@ -355,15 +392,15 @@ command
|
|
355
392
|
if (analyzer) {
|
356
393
|
const anaDir = path.resolve(dir, analyzer.dir)
|
357
394
|
if (!existsSync(anaDir)) {
|
358
|
-
|
395
|
+
mkdirSync(anaDir, { recursive: true })
|
359
396
|
}
|
360
397
|
const gitIgnorePath = path.resolve(anaDir, '.gitignore')
|
361
398
|
if (!existsSync(gitIgnorePath)) {
|
362
|
-
|
399
|
+
writeFileSync(gitIgnorePath, '*\n!.gitignore\n')
|
363
400
|
}
|
364
401
|
const npmIgnorePath = path.resolve(anaDir, '.npmignore')
|
365
402
|
if (!existsSync(npmIgnorePath)) {
|
366
|
-
|
403
|
+
writeFileSync(npmIgnorePath, '*\n')
|
367
404
|
}
|
368
405
|
if (!statSync(anaDir).isDirectory()) {
|
369
406
|
throw new Error(`The directory '${anaDir}' is not a directory.`)
|
@@ -375,7 +412,7 @@ command
|
|
375
412
|
const configFile = jiekTempDir(
|
376
413
|
`${escapeManifestName ?? `anonymous-${i++}`}.rollup.config.js`
|
377
414
|
)
|
378
|
-
|
415
|
+
writeFileSync(configFile, FILE_TEMPLATE(manifest))
|
379
416
|
const command = [rollupBinaryPath, '--silent', '-c', configFile]
|
380
417
|
if (tsRegisterName != null) {
|
381
418
|
command.unshift(`node -r ${tsRegisterName}`)
|
@@ -397,97 +434,152 @@ command
|
|
397
434
|
const times: Record<string, number> = {}
|
398
435
|
const locks: Record<string, boolean> = {}
|
399
436
|
let inputMaxLen = 10
|
400
|
-
child.on('message', (e:
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
437
|
+
child.on('message', (e: RollupBuildEvent) => {
|
438
|
+
if (
|
439
|
+
silent && [
|
440
|
+
'init',
|
441
|
+
'progress',
|
442
|
+
'watchChange'
|
443
|
+
].includes(e.type)
|
444
|
+
) return
|
445
|
+
switch (e.type) {
|
446
|
+
case 'init': {
|
447
|
+
const { leafMap, targetsLength } = e.data
|
448
|
+
const leafs = Array
|
449
|
+
.from(leafMap.entries())
|
450
|
+
.flatMap(([input, pathAndCondiions]) =>
|
451
|
+
pathAndCondiions.map(([path, ...conditions]) => ({
|
452
|
+
input,
|
453
|
+
path,
|
454
|
+
conditions
|
455
|
+
}))
|
456
|
+
)
|
457
|
+
let initMessage = `Package '${manifest.name}' has ${targetsLength} targets to build`
|
458
|
+
if (watch) {
|
459
|
+
initMessage += ' and watching...'
|
460
|
+
}
|
461
|
+
// eslint-disable-next-line no-console
|
462
|
+
console.log(initMessage)
|
463
|
+
leafs.forEach(({ input }) => {
|
464
|
+
inputMaxLen = Math.max(inputMaxLen, input.length)
|
465
|
+
})
|
466
|
+
leafs.forEach(({ input, path }) => {
|
467
|
+
const key = `${input}:${path}`
|
468
|
+
// eslint-disable-next-line ts/strict-boolean-expressions
|
469
|
+
if (bars[key]) return
|
470
|
+
bars[key] = multiBars.create(50, 0, {
|
471
|
+
pkgName: manifest.name,
|
472
|
+
input: input.padEnd(inputMaxLen + 5),
|
473
|
+
status: 'waiting'.padEnd(10)
|
474
|
+
}, {
|
475
|
+
barsize: 20,
|
476
|
+
linewrap: true
|
477
|
+
})
|
478
|
+
})
|
479
|
+
break
|
480
|
+
}
|
481
|
+
case 'progress': {
|
482
|
+
const {
|
483
|
+
path,
|
484
|
+
tags,
|
485
|
+
input,
|
486
|
+
event,
|
487
|
+
message
|
488
|
+
} = e.data
|
489
|
+
const bar = bars[`${input}:${path}`]
|
490
|
+
// eslint-disable-next-line ts/strict-boolean-expressions
|
491
|
+
if (!bar) return
|
492
|
+
const time = times[`${input}:${path}`]
|
493
|
+
bar.update(
|
494
|
+
{
|
495
|
+
start: 0,
|
496
|
+
resolve: 20,
|
497
|
+
end: 50
|
498
|
+
}[event ?? 'start'] ?? 0,
|
499
|
+
{
|
500
|
+
input: (
|
501
|
+
time
|
502
|
+
? `${input}(x${time.toString().padStart(2, '0')})`
|
503
|
+
: input
|
504
|
+
).padEnd(inputMaxLen + 5),
|
505
|
+
status: event?.padEnd(10),
|
506
|
+
message: `${tags?.join(', ')}: ${message}`
|
507
|
+
}
|
415
508
|
)
|
416
|
-
|
417
|
-
if (watch) {
|
418
|
-
initMessage += ' and watching...'
|
509
|
+
break
|
419
510
|
}
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
leafs.forEach(({ input, path }) => {
|
511
|
+
case 'watchChange': {
|
512
|
+
const {
|
513
|
+
path,
|
514
|
+
input
|
515
|
+
} = e.data
|
426
516
|
const key = `${input}:${path}`
|
517
|
+
const bar = bars[key]
|
427
518
|
// eslint-disable-next-line ts/strict-boolean-expressions
|
428
|
-
if (
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
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}`
|
519
|
+
if (!bar) return
|
520
|
+
let time = times[key] ?? 1
|
521
|
+
if (!locks[key]) {
|
522
|
+
time += 1
|
523
|
+
times[key] = time
|
524
|
+
setTimeout(() => {
|
525
|
+
locks[key] = false
|
526
|
+
}, 100)
|
527
|
+
bar.update(0, {
|
528
|
+
input: `${input}(x${time.toString().padStart(2, '0')})`.padEnd(inputMaxLen + 5),
|
529
|
+
status: 'watching'.padEnd(10),
|
530
|
+
message: 'watching...'
|
531
|
+
})
|
465
532
|
}
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
533
|
+
locks[key] = true
|
534
|
+
break
|
535
|
+
}
|
536
|
+
case 'modulesAnalyze': {
|
537
|
+
const {
|
538
|
+
data: {
|
539
|
+
type,
|
540
|
+
path,
|
541
|
+
modules: pkgModules
|
542
|
+
}
|
543
|
+
} = e
|
544
|
+
pkgModules.forEach(m => {
|
545
|
+
const newM = {
|
546
|
+
...m,
|
547
|
+
filename: `${manifest.name}/${m.filename}`,
|
548
|
+
label: `${manifest.name}/${m.label}`
|
549
|
+
}
|
550
|
+
const pushOrReplace = (arr: Module[]) => {
|
551
|
+
const index = arr.findIndex(({ filename }) => filename === newM.filename)
|
552
|
+
if (index === -1) {
|
553
|
+
arr.push(newM)
|
554
|
+
} else {
|
555
|
+
arr[index] = newM
|
556
|
+
}
|
557
|
+
}
|
558
|
+
pushOrReplace(modules)
|
559
|
+
if (type === 'esm') {
|
560
|
+
pushOrReplace(esmModules)
|
561
|
+
}
|
562
|
+
if (type === 'cjs') {
|
563
|
+
pushOrReplace(cjsModules)
|
564
|
+
}
|
488
565
|
})
|
566
|
+
void refreshAnalyzer()
|
567
|
+
void refreshAnalyzer(
|
568
|
+
`/${type}`,
|
569
|
+
{
|
570
|
+
cjs: cjsModules,
|
571
|
+
esm: esmModules
|
572
|
+
}[type]
|
573
|
+
)
|
574
|
+
void refreshAnalyzer(`/${type}/${manifest.name}/${path.slice(2)}`, pkgModules)
|
575
|
+
break
|
489
576
|
}
|
490
|
-
|
577
|
+
case 'debug': {
|
578
|
+
// eslint-disable-next-line no-console,ts/no-unsafe-argument
|
579
|
+
console.log(...(Array.isArray(e.data) ? e.data : [e.data]))
|
580
|
+
break
|
581
|
+
}
|
582
|
+
default:
|
491
583
|
}
|
492
584
|
})
|
493
585
|
await new Promise<void>((resolve, reject) => {
|
@@ -504,6 +596,7 @@ command
|
|
504
596
|
})
|
505
597
|
)
|
506
598
|
}
|
599
|
+
|
507
600
|
const commandFilters = IS_WORKSPACE ? commandFiltersOrEntries : undefined
|
508
601
|
const filters = [
|
509
602
|
...new Set([
|
@@ -528,5 +621,20 @@ command
|
|
528
621
|
}
|
529
622
|
} finally {
|
530
623
|
multiBars.stop()
|
624
|
+
let message = 'The build is complete'
|
625
|
+
if (analyzer) {
|
626
|
+
message += ` and the analyzer is running at http://localhost:${options.port}/ana in ${analyzer.mode} mode.\n`
|
627
|
+
message += analyzer.open ? ' The browser will open automatically.\n' : ''
|
628
|
+
if (anaPaths.size > 0) {
|
629
|
+
message += `The analyzer has ${anaPaths.size} pages:\n${
|
630
|
+
Array
|
631
|
+
.from(anaPaths)
|
632
|
+
.map(p => `http://localhost:${options.port}${p}`)
|
633
|
+
.join('\n')
|
634
|
+
}`
|
635
|
+
}
|
636
|
+
}
|
637
|
+
// eslint-disable-next-line no-console
|
638
|
+
!silent && console.log(message)
|
531
639
|
}
|
532
640
|
})
|
package/src/rollup/base.ts
CHANGED
@@ -100,38 +100,3 @@ export interface TemplateOptions {
|
|
100
100
|
dts: InputPluginOption
|
101
101
|
}
|
102
102
|
}
|
103
|
-
|
104
|
-
export type RollupProgressEvent =
|
105
|
-
| {
|
106
|
-
type: 'init'
|
107
|
-
data: {
|
108
|
-
leafMap: Map<string, string[][]>
|
109
|
-
targetsLength: number
|
110
|
-
}
|
111
|
-
}
|
112
|
-
| {
|
113
|
-
type: 'watchChange'
|
114
|
-
data: {
|
115
|
-
id: string
|
116
|
-
name: string
|
117
|
-
path: string
|
118
|
-
input: string
|
119
|
-
}
|
120
|
-
}
|
121
|
-
| {
|
122
|
-
type: 'debug'
|
123
|
-
data: unknown
|
124
|
-
}
|
125
|
-
| {
|
126
|
-
type: 'progress'
|
127
|
-
data: {
|
128
|
-
// name, path, exportConditions, input
|
129
|
-
name: string
|
130
|
-
path: string
|
131
|
-
exportConditions: string[]
|
132
|
-
input: string
|
133
|
-
tags?: string[]
|
134
|
-
event?: string
|
135
|
-
message?: string
|
136
|
-
}
|
137
|
-
}
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import process from 'node:process'
|
2
|
+
|
3
|
+
import type { InputPluginOption, OutputPlugin, Plugin } from 'rollup'
|
4
|
+
import type { AnalyzerPluginInternalAPI } from 'vite-bundle-analyzer'
|
5
|
+
|
6
|
+
export type Module = ReturnType<AnalyzerPluginInternalAPI['processModule']>[number]
|
7
|
+
|
8
|
+
const {
|
9
|
+
JIEK_ANALYZER
|
10
|
+
} = process.env
|
11
|
+
|
12
|
+
const ANALYZER = (JIEK_ANALYZER != null) && JSON.parse(JIEK_ANALYZER) as {
|
13
|
+
dir?: string
|
14
|
+
mode?: string
|
15
|
+
size?: string
|
16
|
+
port?: number
|
17
|
+
open?: boolean
|
18
|
+
}
|
19
|
+
|
20
|
+
export function bundleAnalyzer(modulesResolved: (modules: Module[]) => void) {
|
21
|
+
// eslint-disable-next-line ts/strict-boolean-expressions
|
22
|
+
if (!ANALYZER) {
|
23
|
+
return []
|
24
|
+
}
|
25
|
+
|
26
|
+
const defaultSizes = ({
|
27
|
+
parsed: 'parsed',
|
28
|
+
stat: 'stat',
|
29
|
+
gzip: 'gzip'
|
30
|
+
} as const)[ANALYZER.size ?? 'stat'] ?? 'parsed'
|
31
|
+
|
32
|
+
let module: typeof import('vite-bundle-analyzer') | undefined
|
33
|
+
let ana: Plugin | undefined
|
34
|
+
async function initAna() {
|
35
|
+
const { adapter, analyzer } = module ?? await import('vite-bundle-analyzer')
|
36
|
+
ana = ana ?? adapter(analyzer({
|
37
|
+
defaultSizes,
|
38
|
+
analyzerMode: modulesResolved
|
39
|
+
}))
|
40
|
+
}
|
41
|
+
|
42
|
+
return [
|
43
|
+
(async () => {
|
44
|
+
await initAna()
|
45
|
+
return {
|
46
|
+
name: 'jiek:bundle-analyzer',
|
47
|
+
async closeBundle(...args) {
|
48
|
+
if (typeof ana!.closeBundle !== 'function') return
|
49
|
+
|
50
|
+
return ana!.closeBundle?.call(this, ...args)
|
51
|
+
}
|
52
|
+
} satisfies InputPluginOption
|
53
|
+
})(),
|
54
|
+
(async () => {
|
55
|
+
await initAna()
|
56
|
+
return {
|
57
|
+
...ana,
|
58
|
+
name: 'jiek:bundle-analyzer-output'
|
59
|
+
} satisfies OutputPlugin
|
60
|
+
})()
|
61
|
+
] as const
|
62
|
+
}
|