jiek 0.4.6 → 0.4.7-alpha.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. package/README.md +22 -1
  2. package/bin/jiek.js +9 -5
  3. package/dist/cli.cjs +4734 -406
  4. package/dist/cli.d.cts +97 -0
  5. package/dist/cli.d.ts +96 -1
  6. package/dist/cli.js +5006 -0
  7. package/dist/cli.min.cjs +19 -2
  8. package/dist/cli.min.js +19 -0
  9. package/dist/index.cjs +0 -1
  10. package/dist/index.d.cts +58 -0
  11. package/dist/index.d.ts +47 -46
  12. package/dist/{index.esm.js → index.js} +0 -1
  13. package/dist/index.min.cjs +0 -1
  14. package/dist/index.min.js +1 -0
  15. package/dist/rollup/index.cjs +4669 -0
  16. package/dist/rollup/index.d.cts +53 -0
  17. package/dist/rollup/index.d.ts +53 -0
  18. package/dist/rollup/index.js +4666 -0
  19. package/dist/rollup/index.min.cjs +19 -0
  20. package/dist/rollup/index.min.js +19 -0
  21. package/package.json +52 -33
  22. package/src/cli.ts +9 -0
  23. package/src/commands/base.ts +8 -0
  24. package/src/commands/build.ts +159 -0
  25. package/src/commands/init.ts +373 -0
  26. package/src/commands/publish.ts +156 -0
  27. package/src/index.ts +8 -0
  28. package/src/inner.ts +11 -0
  29. package/src/merge-package-json.ts +75 -0
  30. package/src/rollup/base.ts +72 -0
  31. package/src/rollup/index.ts +420 -0
  32. package/src/rollup/plugins/globals.ts +34 -0
  33. package/src/rollup/plugins/progress.ts +26 -0
  34. package/src/rollup/plugins/skip.ts +23 -0
  35. package/src/rollup/utils/commonOptions.ts +9 -0
  36. package/src/rollup/utils/externalResolver.ts +21 -0
  37. package/src/rollup/utils/globalResolver.ts +13 -0
  38. package/src/rollup/utils/withMinify.ts +18 -0
  39. package/src/utils/filterSupport.ts +84 -0
  40. package/src/utils/getExports.ts +100 -0
  41. package/src/utils/getRoot.ts +16 -0
  42. package/src/utils/getWD.ts +31 -0
  43. package/src/utils/loadConfig.ts +93 -0
  44. package/src/utils/tsRegister.ts +22 -0
  45. package/dist/base.esm.d.ts +0 -55
  46. package/dist/cli.cjs.map +0 -1
  47. package/dist/cli.esm.d.ts +0 -2
  48. package/dist/cli.esm.js +0 -9
  49. package/dist/cli.esm.js.map +0 -1
  50. package/dist/cli.esm.min.js +0 -2
  51. package/dist/cli.esm.min.js.map +0 -1
  52. package/dist/cli.min.cjs.map +0 -1
  53. package/dist/commands/base.esm.js +0 -5
  54. package/dist/commands/base.esm.js.map +0 -1
  55. package/dist/commands/base.esm.min.js +0 -2
  56. package/dist/commands/base.esm.min.js.map +0 -1
  57. package/dist/commands/build.esm.js +0 -58
  58. package/dist/commands/build.esm.js.map +0 -1
  59. package/dist/commands/build.esm.min.js +0 -2
  60. package/dist/commands/build.esm.min.js.map +0 -1
  61. package/dist/commands/init.esm.js +0 -271
  62. package/dist/commands/init.esm.js.map +0 -1
  63. package/dist/commands/init.esm.min.js +0 -2
  64. package/dist/commands/init.esm.min.js.map +0 -1
  65. package/dist/commands/publish.esm.js +0 -87
  66. package/dist/commands/publish.esm.js.map +0 -1
  67. package/dist/commands/publish.esm.min.js +0 -2
  68. package/dist/commands/publish.esm.min.js.map +0 -1
  69. package/dist/index.cjs.map +0 -1
  70. package/dist/index.esm.d.ts +0 -6
  71. package/dist/index.esm.js.map +0 -1
  72. package/dist/index.esm.min.js +0 -2
  73. package/dist/index.esm.min.js.map +0 -1
  74. package/dist/index.min.cjs.map +0 -1
  75. package/dist/inner.esm.js +0 -10
  76. package/dist/inner.esm.js.map +0 -1
  77. package/dist/inner.esm.min.js +0 -2
  78. package/dist/inner.esm.min.js.map +0 -1
  79. package/dist/merge-package-json.esm.js +0 -64
  80. package/dist/merge-package-json.esm.js.map +0 -1
  81. package/dist/merge-package-json.esm.min.js +0 -2
  82. package/dist/merge-package-json.esm.min.js.map +0 -1
  83. package/dist/pkg.esm.js +0 -4
  84. package/dist/pkg.esm.js.map +0 -1
  85. package/dist/pkg.esm.min.js +0 -2
  86. package/dist/pkg.esm.min.js.map +0 -1
  87. package/dist/rollup/plugins/globals.esm.js +0 -31
  88. package/dist/rollup/plugins/globals.esm.js.map +0 -1
  89. package/dist/rollup/plugins/globals.esm.min.js +0 -2
  90. package/dist/rollup/plugins/globals.esm.min.js.map +0 -1
  91. package/dist/rollup/plugins/skip.esm.js +0 -16
  92. package/dist/rollup/plugins/skip.esm.js.map +0 -1
  93. package/dist/rollup/plugins/skip.esm.min.js +0 -2
  94. package/dist/rollup/plugins/skip.esm.min.js.map +0 -1
  95. package/dist/rollup/utils/commonOptions.esm.js +0 -9
  96. package/dist/rollup/utils/commonOptions.esm.js.map +0 -1
  97. package/dist/rollup/utils/commonOptions.esm.min.js +0 -2
  98. package/dist/rollup/utils/commonOptions.esm.min.js.map +0 -1
  99. package/dist/rollup/utils/externalResolver.esm.js +0 -12
  100. package/dist/rollup/utils/externalResolver.esm.js.map +0 -1
  101. package/dist/rollup/utils/externalResolver.esm.min.js +0 -2
  102. package/dist/rollup/utils/externalResolver.esm.min.js.map +0 -1
  103. package/dist/rollup/utils/globalResolver.esm.js +0 -9
  104. package/dist/rollup/utils/globalResolver.esm.js.map +0 -1
  105. package/dist/rollup/utils/globalResolver.esm.min.js +0 -2
  106. package/dist/rollup/utils/globalResolver.esm.min.js.map +0 -1
  107. package/dist/rollup/utils/withMinify.esm.js +0 -15
  108. package/dist/rollup/utils/withMinify.esm.js.map +0 -1
  109. package/dist/rollup/utils/withMinify.esm.min.js +0 -2
  110. package/dist/rollup/utils/withMinify.esm.min.js.map +0 -1
  111. package/dist/rollup.cjs +0 -330
  112. package/dist/rollup.cjs.map +0 -1
  113. package/dist/rollup.d.ts +0 -23
  114. package/dist/rollup.esm.d.ts +0 -23
  115. package/dist/rollup.esm.js +0 -248
  116. package/dist/rollup.esm.js.map +0 -1
  117. package/dist/rollup.esm.min.js +0 -2
  118. package/dist/rollup.esm.min.js.map +0 -1
  119. package/dist/rollup.min.cjs +0 -2
  120. package/dist/rollup.min.cjs.map +0 -1
  121. package/dist/utils/commondir.esm.js +0 -25
  122. package/dist/utils/commondir.esm.js.map +0 -1
  123. package/dist/utils/commondir.esm.min.js +0 -2
  124. package/dist/utils/commondir.esm.min.js.map +0 -1
  125. package/dist/utils/filterSupport.esm.js +0 -67
  126. package/dist/utils/filterSupport.esm.js.map +0 -1
  127. package/dist/utils/filterSupport.esm.min.js +0 -2
  128. package/dist/utils/filterSupport.esm.min.js.map +0 -1
  129. package/dist/utils/getRoot.esm.js +0 -14
  130. package/dist/utils/getRoot.esm.js.map +0 -1
  131. package/dist/utils/getRoot.esm.min.js +0 -2
  132. package/dist/utils/getRoot.esm.min.js.map +0 -1
  133. package/dist/utils/getWD.esm.js +0 -31
  134. package/dist/utils/getWD.esm.js.map +0 -1
  135. package/dist/utils/getWD.esm.min.js +0 -2
  136. package/dist/utils/getWD.esm.min.js.map +0 -1
  137. package/dist/utils/loadConfig.esm.js +0 -75
  138. package/dist/utils/loadConfig.esm.js.map +0 -1
  139. package/dist/utils/loadConfig.esm.min.js +0 -2
  140. package/dist/utils/loadConfig.esm.min.js.map +0 -1
  141. package/dist/utils/tsRegister.esm.js +0 -24
  142. package/dist/utils/tsRegister.esm.js.map +0 -1
  143. package/dist/utils/tsRegister.esm.min.js +0 -2
  144. package/dist/utils/tsRegister.esm.min.js.map +0 -1
@@ -0,0 +1,420 @@
1
+ import '../rollup/base'
2
+
3
+ import fs from 'node:fs'
4
+ import { dirname, relative, resolve } from 'node:path'
5
+
6
+ import type { RecursiveRecord } from '@jiek/pkger/entrypoints'
7
+ import { getAllLeafs } from '@jiek/pkger/entrypoints'
8
+ import { dts } from '@jiek/rollup-plugin-dts'
9
+ import { getWorkspaceDir } from '@jiek/utils/getWorkspaceDir'
10
+ import commonjs from '@rollup/plugin-commonjs'
11
+ import json from '@rollup/plugin-json'
12
+ import { nodeResolve } from '@rollup/plugin-node-resolve'
13
+ import terser from '@rollup/plugin-terser'
14
+ import { sendMessage } from 'execa'
15
+ import { parse } from 'jsonc-parser'
16
+ import { isMatch } from 'micromatch'
17
+ import type { OutputOptions, OutputPlugin, RollupOptions } from 'rollup'
18
+ import esbuild from 'rollup-plugin-esbuild'
19
+ import ts from 'typescript'
20
+
21
+ import { getExports } from '../utils/getExports'
22
+ import { loadConfig } from '../utils/loadConfig'
23
+ import type { RollupProgressEvent, TemplateOptions } from './base'
24
+ import progress from './plugins/progress'
25
+ import skip from './plugins/skip'
26
+ import externalResolver from './utils/externalResolver'
27
+
28
+ interface PackageJSON {
29
+ name?: string
30
+ type?: string
31
+ exports?: Record<string, unknown> | string | string[]
32
+ }
33
+
34
+ const {
35
+ JIEK_ROOT,
36
+ JIEK_ENTRIES
37
+ } = process.env
38
+ const WORKSPACE_ROOT = JIEK_ROOT ?? getWorkspaceDir()
39
+ const COMMON_OPTIONS = {} satisfies RollupOptions
40
+ const COMMON_PLUGINS = [
41
+ json()
42
+ ]
43
+
44
+ const config = loadConfig() ?? {}
45
+ const { build = {} } = config
46
+ const jsOutdir = `./${
47
+ relative(
48
+ process.cwd(),
49
+ resolve(
50
+ (
51
+ typeof build?.output?.dir === 'object'
52
+ // the outdir only affect js output in this function
53
+ ? build.output.dir.js
54
+ : build?.output?.dir
55
+ ) ?? 'dist'
56
+ )
57
+ )
58
+ }`
59
+
60
+ const STYLE_REGEXP = /\.(css|s[ac]ss|less|styl)$/
61
+
62
+ // eslint-disable-next-line unused-imports/no-unused-vars
63
+ const debug = (...args: unknown[]) => sendMessage({ type: 'debug', data: args } satisfies RollupProgressEvent)
64
+
65
+ const resolveWorkspacePath = (p: string) => resolve(WORKSPACE_ROOT, p)
66
+
67
+ const pascalCase = (str: string) =>
68
+ str
69
+ .replace(/[@|/-](\w)/g, (_, $1) => $1.toUpperCase())
70
+ .replace(/(?:^|-)(\w)/g, (_, $1) => $1.toUpperCase())
71
+
72
+ const reveal = (obj: string | Record<string, unknown>, keys: string[]) =>
73
+ keys.reduce((acc, key) => {
74
+ if (typeof acc === 'string') throw new Error('key not found in exports')
75
+ if (!(key in acc)) throw new Error(`key ${key} not found in exports`)
76
+ return acc[key] as string | Record<string, unknown>
77
+ }, obj)
78
+
79
+ const withMinify = (
80
+ output: OutputOptions & {
81
+ plugins?: OutputPlugin[]
82
+ },
83
+ minify = build?.output?.minify
84
+ ) =>
85
+ minify === false
86
+ ? [output]
87
+ : minify === 'only-minify'
88
+ ? [{
89
+ ...output,
90
+ // TODO replace suffix when pubish to npm and the `build.output.minify` is 'only-minify'
91
+ // TODO resolve dts output file name
92
+ file: output.file?.replace(/(\.[cm]?js)$/, '.min$1'),
93
+ plugins: [
94
+ ...(output.plugins ?? []),
95
+ terser()
96
+ ]
97
+ }]
98
+ : [
99
+ output,
100
+ {
101
+ ...output,
102
+ file: output.file?.replace(/(\.[cm]?js)$/, '.min$1'),
103
+ plugins: [
104
+ ...(output.plugins ?? []),
105
+ terser()
106
+ ]
107
+ }
108
+ ]
109
+
110
+ type TSConfig = {
111
+ extends?: string | string[]
112
+ compilerOptions?: Record<string, unknown>
113
+ references?: { path: string }[]
114
+ files?: string[]
115
+ include?: string[]
116
+ exclude?: string[]
117
+ }
118
+
119
+ const getTSConfig = (p: string): TSConfig =>
120
+ !fs.existsSync(p) || !fs.statSync(p).isFile()
121
+ ? {}
122
+ : parse(fs.readFileSync(p, 'utf-8'), [], { allowTrailingComma: true, allowEmptyContent: true })
123
+
124
+ const getExtendTSConfig = (tsconfigPath: string): TSConfig => {
125
+ tsconfigPath = resolve(tsconfigPath)
126
+ const tsconfigPathDirname = dirname(tsconfigPath)
127
+ const { extends: exts, ...tsconfig } = getTSConfig(tsconfigPath)
128
+ const resolvePaths = (paths: string[] | undefined) => paths?.map(p => resolve(tsconfigPathDirname, p)) ?? []
129
+
130
+ const extendsPaths = resolvePaths(
131
+ exts ? Array.isArray(exts) ? exts : [exts] : []
132
+ )
133
+ if (extendsPaths.length === 0) return tsconfig
134
+ return extendsPaths
135
+ .map(getExtendTSConfig)
136
+ // https://www.typescriptlang.org/tsconfig/#files:~:text=Currently%2C%20the%20only%20top%2Dlevel%20property%20that%20is%20excluded%20from%20inheritance%20is%20references.
137
+ // Currently, the only top-level property that is excluded from inheritance is references.
138
+ .reduce((acc, { compilerOptions = {}, references: _, ...curr }) => ({
139
+ ...acc,
140
+ ...curr,
141
+ compilerOptions: {
142
+ ...acc.compilerOptions,
143
+ ...compilerOptions
144
+ }
145
+ }), tsconfig)
146
+ }
147
+
148
+ const getCompilerOptionsByFilePath = (tsconfigPath: string, filePath: string): Record<string, unknown> | undefined => {
149
+ tsconfigPath = resolve(tsconfigPath)
150
+ filePath = resolve(filePath)
151
+ const tsconfigPathDirname = dirname(tsconfigPath)
152
+ // https://www.typescriptlang.org/tsconfig/#files:~:text=It%E2%80%99s%20worth%20noting%20that%20files%2C%20include%2C%20and%20exclude%20from%20the%20inheriting%20config%20file%20overwrite%20those%20from%20the%20base%20config%20file%2C%20and%20that%20circularity%20between%20configuration%20files%20is%20not%20allowed.
153
+ // It’s worth noting that files, include, and exclude from the inheriting config file overwrite
154
+ // those from the base config file, and that circularity between configuration files is not allowed.
155
+ const tsconfig = getExtendTSConfig(tsconfigPath)
156
+
157
+ const resolvePaths = (paths: string[] | undefined) => paths?.map(p => resolve(tsconfigPathDirname, p)) ?? []
158
+
159
+ const [
160
+ references,
161
+ files,
162
+ include,
163
+ exclude
164
+ ] = [
165
+ tsconfig.references?.map(({ path }) => path),
166
+ tsconfig.files,
167
+ tsconfig.include,
168
+ tsconfig.exclude
169
+ ].map(resolvePaths)
170
+ if (exclude.length > 0 && exclude.some(i => isMatch(filePath, i))) return
171
+
172
+ // when files or include is not empty, the tsconfig should be ignored
173
+ if (tsconfig.files?.length === 0 && tsconfig.include?.length === 0) return
174
+ let isInclude = false
175
+ isInclude ||= files.length > 0 && files.includes(filePath)
176
+ isInclude ||= include.length > 0 && include.some(i => isMatch(filePath, i))
177
+ if (isInclude) {
178
+ return tsconfig.compilerOptions ?? {}
179
+ } else {
180
+ // when files or include is not empty, but the file is not matched, the tsconfig should be ignored
181
+ if (
182
+ (tsconfig.files && tsconfig.files.length > 0)
183
+ || (tsconfig.include && tsconfig.include.length > 0)
184
+ ) return
185
+ }
186
+
187
+ references.reverse()
188
+ for (const ref of references) {
189
+ const compilerOptions = getCompilerOptionsByFilePath(ref, filePath)
190
+ if (compilerOptions) return compilerOptions
191
+ }
192
+ return tsconfig.compilerOptions
193
+ }
194
+
195
+ const generateConfigs = ({
196
+ path,
197
+ name,
198
+ input,
199
+ output,
200
+ external,
201
+ pkgIsModule,
202
+ conditionals
203
+ }: {
204
+ path: string
205
+ name: string
206
+ input: string
207
+ output: string
208
+ external: (string | RegExp)[]
209
+ pkgIsModule: boolean
210
+ conditionals: string[]
211
+ }, options: TemplateOptions = {}): RollupOptions[] => {
212
+ const isModule = conditionals.includes('import')
213
+ const isCommonJS = conditionals.includes('require')
214
+ const isBrowser = conditionals.includes('browser')
215
+ const dtsTSConfigPaths = [
216
+ resolveWorkspacePath('tsconfig.json'),
217
+ resolveWorkspacePath('tsconfig.dts.json')
218
+ ]
219
+ let dtsTSConfigPath: string | undefined
220
+ dtsTSConfigPaths.forEach(p => {
221
+ if (fs.existsSync(p) && fs.statSync(p).isFile()) {
222
+ dtsTSConfigPath = p
223
+ }
224
+ })
225
+ let compilerOptions: ts.CompilerOptions = {}
226
+ if (dtsTSConfigPath) {
227
+ const jsonCompilerOptions = getCompilerOptionsByFilePath(dtsTSConfigPath, resolve(input))
228
+ const { options, errors } = ts.convertCompilerOptionsFromJson(
229
+ jsonCompilerOptions,
230
+ dirname(dtsTSConfigPath)
231
+ )
232
+ if (errors.length > 0) {
233
+ throw new Error(errors.map(e => e.messageText).join('\n'))
234
+ }
235
+ compilerOptions = options
236
+ }
237
+ const exportConditions = [...conditionals, ...(compilerOptions.customConditions ?? [])]
238
+ const throughEventProps: RollupProgressEvent & { type: 'progress' } = {
239
+ type: 'progress',
240
+ data: { name, path, exportConditions, input }
241
+ }
242
+ const outdir = options?.output?.dir
243
+ return [
244
+ {
245
+ input,
246
+ external,
247
+ output: [
248
+ ...withMinify({
249
+ file: output,
250
+ name,
251
+ sourcemap: typeof options?.output?.sourcemap === 'object'
252
+ ? options.output.sourcemap.js
253
+ : options?.output?.sourcemap,
254
+ format: isModule ? 'esm' : (
255
+ isCommonJS ? 'cjs' : (
256
+ isBrowser ? 'umd' : (
257
+ pkgIsModule ? 'esm' : 'cjs'
258
+ )
259
+ )
260
+ ),
261
+ strict: typeof options?.output?.strict === 'object'
262
+ ? options.output.strict.js
263
+ : options?.output?.strict
264
+ })
265
+ ],
266
+ plugins: [
267
+ nodeResolve({ exportConditions }),
268
+ import('rollup-plugin-postcss')
269
+ .then(({ default: postcss }) =>
270
+ postcss({
271
+ extract: resolve(output.replace(/\.[cm]?js$/, '.css')),
272
+ minimize: true
273
+ })
274
+ )
275
+ .catch(() => void 0),
276
+ esbuild(),
277
+ commonjs(),
278
+ progress({
279
+ onEvent: (event, message) =>
280
+ sendMessage(
281
+ {
282
+ ...throughEventProps,
283
+ data: { ...throughEventProps.data, event, message, tags: ['js'] }
284
+ } satisfies RollupProgressEvent
285
+ )
286
+ })
287
+ ]
288
+ },
289
+ {
290
+ input,
291
+ external,
292
+ output: [
293
+ {
294
+ dir: resolve((typeof outdir === 'object' ? outdir.dts : outdir) ?? 'dist'),
295
+ sourcemap: typeof options?.output?.sourcemap === 'object'
296
+ ? options.output.sourcemap.dts
297
+ : options?.output?.sourcemap,
298
+ entryFileNames: () =>
299
+ output
300
+ .replace(`${jsOutdir}/`, '')
301
+ .replace(/(\.[cm]?)js$/, '.d$1ts'),
302
+ strict: typeof options?.output?.strict === 'object'
303
+ ? options.output.strict.dts
304
+ : options?.output?.strict
305
+ }
306
+ ],
307
+ plugins: [
308
+ nodeResolve({ exportConditions }),
309
+ skip({ patterns: [STYLE_REGEXP] }),
310
+ dts({
311
+ respectExternal: true,
312
+ compilerOptions
313
+ }),
314
+ progress({
315
+ onEvent: (event, message) =>
316
+ sendMessage(
317
+ {
318
+ ...throughEventProps,
319
+ data: { ...throughEventProps.data, event, message, tags: ['dts'] }
320
+ } satisfies RollupProgressEvent
321
+ )
322
+ })
323
+ ]
324
+ }
325
+ ]
326
+ }
327
+
328
+ export function template(packageJSON: PackageJSON): RollupOptions[] {
329
+ const { name, type, exports: entrypoints } = packageJSON
330
+ const pkgIsModule = type === 'module'
331
+ if (!name) throw new Error('package.json name is required')
332
+ if (!entrypoints) throw new Error('package.json exports is required')
333
+
334
+ const entries = JIEK_ENTRIES
335
+ ?.split(',')
336
+ .map(e => e.trim())
337
+ .map(e => ({
338
+ 'index': '.'
339
+ }[e] ?? e))
340
+
341
+ const packageName = pascalCase(name)
342
+
343
+ const external = externalResolver(packageJSON as Record<string, unknown>)
344
+
345
+ const [filteredResolvedEntrypoints, exports] = getExports({
346
+ entrypoints,
347
+ pkgIsModule,
348
+ entries,
349
+ config
350
+ })
351
+
352
+ const leafMap = new Map<string, string[][]>()
353
+ getAllLeafs(filteredResolvedEntrypoints as RecursiveRecord<string>, ({ keys, value }) => {
354
+ if (typeof value === 'string') {
355
+ const keysArr = leafMap.get(value) ?? []
356
+ leafMap.set(value, keysArr)
357
+ keysArr.push(keys)
358
+ }
359
+ return false
360
+ })
361
+
362
+ const configs: RollupOptions[] = []
363
+ leafMap.forEach((keysArr, input) =>
364
+ keysArr.forEach((keys) => {
365
+ const [path, ...conditionals] = keys
366
+
367
+ const name = packageName + (path === '.' ? '' : pascalCase(path))
368
+ const keyExports = reveal(exports, keys)
369
+ const commonOptions = {
370
+ path,
371
+ name,
372
+ input,
373
+ external,
374
+ pkgIsModule
375
+ }
376
+
377
+ switch (typeof keyExports) {
378
+ case 'string': {
379
+ configs.push(...generateConfigs({
380
+ ...commonOptions,
381
+ output: keyExports,
382
+ conditionals
383
+ }, build))
384
+ break
385
+ }
386
+ case 'object': {
387
+ getAllLeafs(keyExports as RecursiveRecord<string>, ({ keys: nextKeys, value }) => {
388
+ const allConditionals = [...new Set([...conditionals, ...nextKeys])]
389
+ if (typeof value === 'string') {
390
+ configs.push(...generateConfigs({
391
+ ...commonOptions,
392
+ output: value,
393
+ conditionals: allConditionals
394
+ }, build))
395
+ }
396
+ return false
397
+ })
398
+ break
399
+ }
400
+ }
401
+ })
402
+ )
403
+ sendMessage(
404
+ {
405
+ type: 'init',
406
+ data: {
407
+ leafMap,
408
+ targetsLength: configs.length
409
+ }
410
+ } satisfies RollupProgressEvent
411
+ )
412
+ return configs.map(c => ({
413
+ ...COMMON_OPTIONS,
414
+ ...c,
415
+ plugins: [
416
+ ...COMMON_PLUGINS,
417
+ c.plugins
418
+ ]
419
+ }))
420
+ }
@@ -0,0 +1,34 @@
1
+ import type { Plugin, PluginImpl } from 'rollup'
2
+
3
+ import globalResolver from '../utils/globalResolver'
4
+
5
+ interface GlobalsOptions {
6
+ external?: (string | RegExp)[]
7
+ }
8
+
9
+ export function createGlobalsLinkage() {
10
+ let globals = {}
11
+ const dependencies = new Set<string>([])
12
+ return [
13
+ (({ external } = {}) => {
14
+ return {
15
+ name: 'globals',
16
+ resolveId(id) {
17
+ if (external?.some(dep => dep instanceof RegExp ? dep.test(id) : dep === id)) {
18
+ dependencies.add(id)
19
+ return { id, external: true }
20
+ }
21
+ return null
22
+ },
23
+ outputOptions(options) {
24
+ globals = [...dependencies].reduce((acc, value) => ({
25
+ ...acc,
26
+ [value]: globalResolver(value)
27
+ }), {})
28
+ return { ...options, globals }
29
+ }
30
+ }
31
+ }) as PluginImpl<GlobalsOptions>,
32
+ { outputOptions: options => ({ ...options, globals }) } as Plugin
33
+ ] as const
34
+ }
@@ -0,0 +1,26 @@
1
+ import type { PluginImpl } from 'rollup'
2
+
3
+ interface Options {
4
+ onEvent?: (event: string, message?: string) => void
5
+ }
6
+
7
+ export default ((options = {}) => {
8
+ const { onEvent } = options
9
+ return {
10
+ name: 'progress',
11
+ buildStart: () => onEvent?.('start', 'Start building...'),
12
+ buildEnd: () => onEvent?.('end', 'Build completed!'),
13
+ resolveId: {
14
+ order: 'post',
15
+ handler: source => onEvent?.('resolve', `Resolving ${source}...`)
16
+ },
17
+ load: {
18
+ order: 'post',
19
+ handler: id => onEvent?.('load', `Loading ${id}...`)
20
+ },
21
+ transform: {
22
+ order: 'post',
23
+ handler: (_, id) => onEvent?.('transform', `Transforming ${id}...`)
24
+ }
25
+ }
26
+ }) as PluginImpl<Options>
@@ -0,0 +1,23 @@
1
+ import type { PluginImpl } from 'rollup'
2
+
3
+ interface Options {
4
+ patterns?: (string | RegExp)[]
5
+ }
6
+
7
+ export default ((options = {}) => {
8
+ return {
9
+ name: 'skip',
10
+ // skip the specified files by `options.patterns`
11
+ load(id) {
12
+ if (
13
+ options.patterns?.some((pattern) =>
14
+ typeof pattern === 'string'
15
+ ? id.includes(pattern)
16
+ : pattern.test(id)
17
+ )
18
+ ) {
19
+ return ''
20
+ }
21
+ }
22
+ }
23
+ }) as PluginImpl<Options>
@@ -0,0 +1,9 @@
1
+ import type { OutputOptions } from 'rollup'
2
+
3
+ const defineOutput = <O extends OutputOptions>(output: O) => output
4
+
5
+ export const commonOutputOptions = defineOutput({
6
+ exports: 'named',
7
+ interop: 'auto',
8
+ sourcemap: true
9
+ })
@@ -0,0 +1,21 @@
1
+ import fs from 'node:fs'
2
+
3
+ export default function(json: Record<string, unknown>): (string | RegExp)[]
4
+ export default function(path?: string): (string | RegExp)[]
5
+ export default function(jsonOrPath: string | Record<string, unknown> = process.cwd()): (string | RegExp)[] {
6
+ const pkg = typeof jsonOrPath === 'string'
7
+ ? fs.existsSync(`${jsonOrPath}/package.json`)
8
+ ? JSON.parse(fs.readFileSync(`${jsonOrPath}/package.json`, 'utf-8'))
9
+ : {}
10
+ : jsonOrPath
11
+ const { dependencies = {}, peerDependencies = {}, optionalDependencies = {} } = pkg
12
+ const external = <(string | RegExp)[]> Object
13
+ .keys(dependencies)
14
+ .concat(Object.keys(peerDependencies))
15
+ .concat(Object.keys(optionalDependencies))
16
+ return external
17
+ .map(dep => new RegExp(`^${dep}(/.*)?$`))
18
+ .concat([
19
+ /^node:/
20
+ ])
21
+ }
@@ -0,0 +1,13 @@
1
+ export default function (external: string) {
2
+ // a/b => AB
3
+ // a-b => AB
4
+ // a@b => AB
5
+ // a@b/c => ABC
6
+ // node:a => a
7
+ // node:a_b => a_b
8
+ if (external.startsWith('node:')) {
9
+ return external.slice(5)
10
+ }
11
+ return external
12
+ .replace(/[@|/-](\w)/g, (_, $1) => $1.toUpperCase())
13
+ }
@@ -0,0 +1,18 @@
1
+ import terser from '@rollup/plugin-terser'
2
+ import type { OutputOptions, OutputPlugin } from 'rollup'
3
+
4
+ export default function(
5
+ output: OutputOptions & {
6
+ entryFileNames?: string
7
+ plugins?: OutputPlugin[]
8
+ }
9
+ ): OutputOptions[] {
10
+ return [
11
+ output,
12
+ {
13
+ ...output,
14
+ entryFileNames: output.entryFileNames?.replace(/(\.[cm]?js)$/, '.min$1'),
15
+ plugins: [...(output.plugins ?? []), terser()]
16
+ }
17
+ ]
18
+ }
@@ -0,0 +1,84 @@
1
+ import fs from 'node:fs'
2
+ import { createRequire } from 'node:module'
3
+ import path from 'node:path'
4
+
5
+ import { filterPackagesFromDir } from '@pnpm/filter-workspace-packages'
6
+ import { program } from 'commander'
7
+ import { load } from 'js-yaml'
8
+
9
+ import { getRoot } from './getRoot'
10
+ import { getWD } from './getWD'
11
+
12
+ export let type = ''
13
+
14
+ try {
15
+ const require = createRequire(import.meta.url)
16
+ require.resolve('@pnpm/filter-workspace-packages')
17
+ type = 'pnpm'
18
+ } catch { /* empty */ }
19
+ if (type !== '') {
20
+ program
21
+ .option('-f, --filter <filter>', 'filter packages')
22
+ }
23
+
24
+ interface ProjectsGraph {
25
+ wd: string
26
+ root: string
27
+ value?: Record<string, {
28
+ name?: string
29
+ type?: string
30
+ exports?: string | string[] | Record<string, unknown>
31
+ }>
32
+ }
33
+
34
+ export async function getSelectedProjectsGraph(): Promise<ProjectsGraph> {
35
+ let filter = program.getOptionValue('filter')
36
+ const root = getRoot()
37
+ const { wd, notWorkspace } = getWD()
38
+ if (!notWorkspace && type === 'pnpm') {
39
+ const pnpmWorkspaceFilePath = path.resolve(wd, 'pnpm-workspace.yaml')
40
+ const pnpmWorkspaceFileContent = fs.readFileSync(pnpmWorkspaceFilePath, 'utf-8')
41
+ const pnpmWorkspace = load(pnpmWorkspaceFileContent) as {
42
+ packages: string[]
43
+ }
44
+ if (root === wd && !filter) {
45
+ throw new Error('root path is workspace root, please provide a filter')
46
+ // TODO inquirer prompt support user select packages
47
+ }
48
+ if (root !== wd && !filter) {
49
+ const packageJSONIsExist = fs.existsSync(path.resolve(root, 'package.json'))
50
+ if (!packageJSONIsExist) {
51
+ throw new Error('root path is not workspace root, please provide a filter')
52
+ }
53
+ const packageJSON = JSON.parse(fs.readFileSync(path.resolve(root, 'package.json'), 'utf-8'))
54
+ if (!packageJSON.name) {
55
+ throw new Error('root path is not workspace root, please provide a filter')
56
+ }
57
+ filter = packageJSON.name
58
+ }
59
+ const { selectedProjectsGraph } = await filterPackagesFromDir(wd, [{
60
+ filter: filter ?? '',
61
+ followProdDepsOnly: true
62
+ }], {
63
+ prefix: root,
64
+ workspaceDir: wd,
65
+ patterns: pnpmWorkspace.packages
66
+ })
67
+ return {
68
+ wd,
69
+ root,
70
+ value: Object.entries(selectedProjectsGraph)
71
+ .reduce((acc, [key, value]) => {
72
+ acc[key] = value.package.manifest
73
+ return acc
74
+ }, {} as NonNullable<ProjectsGraph['value']>)
75
+ }
76
+ }
77
+ return {
78
+ wd,
79
+ root,
80
+ value: {
81
+ [wd]: JSON.parse(fs.readFileSync(path.resolve(wd, 'package.json'), 'utf-8'))
82
+ }
83
+ }
84
+ }