jiek 2.2.1 → 2.2.3-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.
@@ -4155,8 +4155,7 @@ function bundleAnalyzer(modulesResolved) {
4155
4155
  return {
4156
4156
  name: "jiek:bundle-analyzer",
4157
4157
  async closeBundle(...args) {
4158
- if (typeof ana.closeBundle !== "function")
4159
- return;
4158
+ if (typeof ana.closeBundle !== "function") return;
4160
4159
  return ana.closeBundle?.call(this, ...args);
4161
4160
  }
4162
4161
  };
@@ -4238,14 +4237,24 @@ function getExports({
4238
4237
  }
4239
4238
  );
4240
4239
  const crossModuleWithConditional = crossModuleConvertor ? {
4241
- import: (opts) => !pkgIsModule && intersection(
4242
- new Set(opts.conditionals),
4243
- /* @__PURE__ */ new Set(["import", "module"])
4244
- ).size === 0 ? opts.dist.replace(/\.js$/, ".mjs") : false,
4245
- require: (opts) => pkgIsModule && intersection(
4246
- new Set(opts.conditionals),
4247
- /* @__PURE__ */ new Set(["require", "node"])
4248
- ).size === 0 ? opts.dist.replace(/\.js$/, ".cjs") : false
4240
+ import: (opts) => {
4241
+ if (pkgIsModule) return false;
4242
+ if (opts.src.endsWith(".cts")) return false;
4243
+ if (intersection(
4244
+ new Set(opts.conditionals),
4245
+ /* @__PURE__ */ new Set(["import", "module"])
4246
+ ).size !== 0) return false;
4247
+ return opts.dist.replace(/\.js$/, ".mjs");
4248
+ },
4249
+ require: (opts) => {
4250
+ if (!pkgIsModule) return false;
4251
+ if (opts.src.endsWith(".mts")) return false;
4252
+ if (intersection(
4253
+ new Set(opts.conditionals),
4254
+ /* @__PURE__ */ new Set(["require", "node"])
4255
+ ).size !== 0) return false;
4256
+ return opts.dist.replace(/\.js$/, ".cjs");
4257
+ }
4249
4258
  } : {};
4250
4259
  return [
4251
4260
  filteredResolvedEntrypoints,
@@ -4264,8 +4273,7 @@ function getExports({
4264
4273
 
4265
4274
  let root;
4266
4275
  function getRoot() {
4267
- if (root)
4268
- return root;
4276
+ if (root) return root;
4269
4277
  const rootOption = process.env.JIEK_ROOT;
4270
4278
  root = rootOption ? path.isAbsolute(rootOption) ? rootOption : path.resolve(process.cwd(), rootOption) : void 0;
4271
4279
  return root;
@@ -4282,8 +4290,7 @@ try {
4282
4290
  let wd;
4283
4291
  let notWorkspace = false;
4284
4292
  function getWD() {
4285
- if (wd)
4286
- return { wd, notWorkspace };
4293
+ if (wd) return { wd, notWorkspace };
4287
4294
  const root = getRoot();
4288
4295
  if (root !== void 0) {
4289
4296
  const isWorkspace = isWorkspaceDir(root, type);
@@ -4405,16 +4412,14 @@ function loadConfig(dirOrOptions) {
4405
4412
  default:
4406
4413
  throw new Error(`unsupported config file type: ${ext}`);
4407
4414
  }
4408
- if (!module)
4409
- throw new Error("config file is empty");
4415
+ if (!module) throw new Error("config file is empty");
4410
4416
  return module.default ?? module;
4411
4417
  }
4412
4418
 
4413
4419
  const recusiveListFiles = (dir) => fs.readdirSync(dir).reduce((acc, file) => {
4414
4420
  const filePath = resolve(dir, file);
4415
4421
  if (fs.statSync(filePath).isDirectory()) {
4416
- if (filePath.endsWith("/node_modules"))
4417
- return acc;
4422
+ if (filePath.endsWith("/node_modules")) return acc;
4418
4423
  return [...acc, ...recusiveListFiles(filePath)];
4419
4424
  }
4420
4425
  return [...acc, filePath];
@@ -4427,10 +4432,9 @@ const getExtendTSConfig = (tsconfigPath) => {
4427
4432
  const { extends: exts, ...tsconfig } = getTSConfig(tsconfigPath);
4428
4433
  const resolvePaths = (paths) => paths?.map((p) => resolve(tsconfigPathDirname, p)) ?? [];
4429
4434
  const extendsPaths = resolvePaths(
4430
- exts ? Array.isArray(exts) ? exts : [exts] : []
4435
+ exts !== void 0 ? Array.isArray(exts) ? exts : [exts] : []
4431
4436
  );
4432
- if (extendsPaths.length === 0)
4433
- return tsconfig;
4437
+ if (extendsPaths.length === 0) return tsconfig;
4434
4438
  return extendsPaths.map(getExtendTSConfig).concat(tsconfig).reduce((acc, { compilerOptions = {}, references: _, ...curr }) => ({
4435
4439
  ...acc,
4436
4440
  ...curr,
@@ -4457,24 +4461,20 @@ const getCompilerOptionsByFilePath = (tsconfigPath, filePath) => {
4457
4461
  tsconfig.include,
4458
4462
  tsconfig.exclude
4459
4463
  ].map(resolvePaths);
4460
- if (exclude.length > 0 && exclude.some((i) => micromatchExports.isMatch(filePath, i)))
4461
- return;
4462
- if (tsconfig.files?.length === 0 && tsconfig.include?.length === 0)
4463
- return;
4464
+ if (exclude.length > 0 && exclude.some((i) => micromatchExports.isMatch(filePath, i))) return;
4465
+ if (tsconfig.files?.length === 0 && tsconfig.include?.length === 0) return;
4464
4466
  let isInclude = false;
4465
4467
  isInclude || (isInclude = files.length > 0 && files.includes(filePath));
4466
4468
  isInclude || (isInclude = include.length > 0 && include.some((i) => micromatchExports.isMatch(filePath, i)));
4467
4469
  if (isInclude) {
4468
4470
  return tsconfig.compilerOptions ?? {};
4469
4471
  } else {
4470
- if (tsconfig.files && tsconfig.files.length > 0 || tsconfig.include && tsconfig.include.length > 0)
4471
- return;
4472
+ if (tsconfig.files && tsconfig.files.length > 0 || tsconfig.include && tsconfig.include.length > 0) return;
4472
4473
  }
4473
4474
  references.reverse();
4474
4475
  for (const ref of references) {
4475
4476
  const compilerOptions = getCompilerOptionsByFilePath(ref, filePath);
4476
- if (compilerOptions)
4477
- return compilerOptions;
4477
+ if (compilerOptions) return compilerOptions;
4478
4478
  }
4479
4479
  return tsconfig.compilerOptions;
4480
4480
  };
@@ -4653,10 +4653,8 @@ const resolveOutputControls = (context, output) => ({
4653
4653
  const resolveWorkspacePath = (p) => resolve(WORKSPACE_ROOT, p);
4654
4654
  const pascalCase = (str) => str.replace(/[@|/-](\w)/g, (_, $1) => $1.toUpperCase()).replace(/(?:^|-)(\w)/g, (_, $1) => $1.toUpperCase());
4655
4655
  const reveal = (obj, keys) => keys.reduce((acc, key) => {
4656
- if (typeof acc === "string")
4657
- throw new Error("key not found in exports");
4658
- if (!(key in acc))
4659
- throw new Error(`key ${key} not found in exports`);
4656
+ if (typeof acc === "string") throw new Error("key not found in exports");
4657
+ if (!(key in acc)) throw new Error(`key ${key} not found in exports`);
4660
4658
  return acc[key];
4661
4659
  }, obj);
4662
4660
  const resolveMinifyOptions = (minifyOptions) => typeof minifyOptions === "string" ? { type: minifyOptions } : minifyOptions ?? { type: "esbuild" };
@@ -4676,7 +4674,7 @@ const withMinify = (output, onlyOncePlugins = []) => {
4676
4674
  const minifyPlugin = resolvedMinifyOptions.type === "esbuild" ? import('rollup-plugin-esbuild').then(({ minify: minify2 }) => minify2(noTypeResolvedMinifyOptions)) : resolvedMinifyOptions.type === "swc" ? import('rollup-plugin-swc3').then(({ minify: minify2 }) => minify2(noTypeResolvedMinifyOptions)) : import('@rollup/plugin-terser').then(({ default: minify2 }) => minify2(noTypeResolvedMinifyOptions));
4677
4675
  return minify === "only-minify" ? [{
4678
4676
  ...output,
4679
- // TODO replace suffix when pubish to npm and the `build.output.minify` is 'only-minify'
4677
+ // TODO replace suffix when publish to npm and the `build.output.minify` is 'only-minify'
4680
4678
  // TODO resolve dts output file name
4681
4679
  entryFileNames: (chunkInfo) => typeof output.entryFileNames === "function" ? output.entryFileNames(chunkInfo) : (() => {
4682
4680
  throw new Error("entryFileNames must be a function");
@@ -4783,15 +4781,48 @@ const generateConfigs = (context, options = {}) => {
4783
4781
  const { js: jsOutput, dts: dtsOutput } = resolveOutputControls(context, build.output);
4784
4782
  const rollupOptions = [];
4785
4783
  const commonPlugins = [
4786
- nodeResolve({ exportConditions })
4784
+ nodeResolve({
4785
+ exportConditions,
4786
+ extensions: [
4787
+ ".js",
4788
+ ".cjs",
4789
+ ".mjs",
4790
+ ".jsx",
4791
+ ".cjsx",
4792
+ ".mjsx",
4793
+ ".ts",
4794
+ ".cts",
4795
+ ".mts",
4796
+ ".tsx",
4797
+ ".ctsx",
4798
+ ".mtsx"
4799
+ ]
4800
+ })
4787
4801
  ];
4788
4802
  if (jsOutput && !WITHOUT_JS) {
4789
4803
  const sourcemap = typeof options?.output?.sourcemap === "object" ? options.output.sourcemap.js : options?.output?.sourcemap;
4804
+ const features = Object.assign({
4805
+ keepImportAttributes: true
4806
+ }, build.features);
4790
4807
  const builder = resolvedBuilderOptions.type === "esbuild" ? import('rollup-plugin-esbuild').then(
4791
4808
  ({ default: esbuild }) => esbuild({
4792
4809
  sourceMap: sourcemap === "hidden" ? false : !!sourcemap,
4793
4810
  tsconfig: buildTSConfigPath,
4794
- ...noTypeResolvedBuilderOptions
4811
+ loaders: {
4812
+ cts: "ts",
4813
+ ctsx: "tsx",
4814
+ mts: "ts",
4815
+ mtsx: "tsx",
4816
+ cjs: "js",
4817
+ cjsx: "jsx",
4818
+ mjs: "js",
4819
+ mjsx: "jsx"
4820
+ },
4821
+ ...noTypeResolvedBuilderOptions,
4822
+ supported: {
4823
+ "import-attributes": features.keepImportAttributes !== false,
4824
+ ...resolvedBuilderOptions.supported
4825
+ }
4795
4826
  })
4796
4827
  ) : import('rollup-plugin-swc3').then(
4797
4828
  ({ default: swc }) => swc({
@@ -4800,7 +4831,14 @@ const generateConfigs = (context, options = {}) => {
4800
4831
  inline: "inline"
4801
4832
  }[sourcemap] ?? void 0,
4802
4833
  tsconfig: buildTSConfigPath,
4803
- ...noTypeResolvedBuilderOptions
4834
+ ...noTypeResolvedBuilderOptions,
4835
+ jsc: {
4836
+ ...resolvedBuilderOptions.jsc,
4837
+ experimental: {
4838
+ ...resolvedBuilderOptions.jsc?.experimental,
4839
+ keepImportAttributes: features.keepImportAttributes !== false
4840
+ }
4841
+ }
4804
4842
  })
4805
4843
  );
4806
4844
  const [ana, anaOutputPlugin] = bundleAnalyzer((modules) => void publishInEntry("modulesAnalyze", { modules }));
@@ -4819,6 +4857,8 @@ const generateConfigs = (context, options = {}) => {
4819
4857
  sourcemap,
4820
4858
  format,
4821
4859
  strict: typeof options?.output?.strict === "object" ? options.output.strict.js : options?.output?.strict,
4860
+ externalImportAttributes: features.keepImportAttributes !== false,
4861
+ importAttributesKey: features.keepImportAttributes === false || features.keepImportAttributes === void 0 ? void 0 : features.keepImportAttributes === true ? "with" : features.keepImportAttributes,
4822
4862
  plugins: [
4823
4863
  isFormatEsm(format === "esm")
4824
4864
  ]
@@ -4894,10 +4934,8 @@ const generateConfigs = (context, options = {}) => {
4894
4934
  function template(packageJSON) {
4895
4935
  const { name, type, exports: entrypoints } = packageJSON;
4896
4936
  const pkgIsModule = type === "module";
4897
- if (!name)
4898
- throw new Error("package.json name is required");
4899
- if (!entrypoints)
4900
- throw new Error("package.json exports is required");
4937
+ if (!name) throw new Error("package.json name is required");
4938
+ if (!entrypoints) throw new Error("package.json exports is required");
4901
4939
  const packageName = pascalCase(name);
4902
4940
  const external = externalResolver(packageJSON);
4903
4941
  const [filteredResolvedEntrypoints, exports] = getExports({
@@ -4917,6 +4955,7 @@ function template(packageJSON) {
4917
4955
  }
4918
4956
  return false;
4919
4957
  });
4958
+ console.log(exports);
4920
4959
  const configs = [];
4921
4960
  leafMap.forEach(
4922
4961
  (keysArr, input) => keysArr.forEach((keys) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "jiek",
3
3
  "type": "module",
4
- "version": "2.2.1",
4
+ "version": "2.2.3-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",
@@ -48,7 +48,11 @@
48
48
  }
49
49
  },
50
50
  "imports": {
51
- "#~/*": "./src/*"
51
+ "#~/*": [
52
+ "./src/*",
53
+ "./src/*/index.ts",
54
+ "./src/*/index.tsx"
55
+ ]
52
56
  },
53
57
  "bin": {
54
58
  "jiek": "bin/jiek.js",
@@ -57,7 +61,7 @@
57
61
  "jb": "bin/jiek-build.js"
58
62
  },
59
63
  "peerDependencies": {
60
- "@pnpm/filter-workspace-packages": "^7.2.13||^8.0.0||^9.0.0||^10.0.0",
64
+ "@pnpm/filter-workspace-packages": "^7.2.13||^8.0.0||^9.0.0||^10.0.0||>=1000.0.0",
61
65
  "@rollup/plugin-terser": "^0.4.4",
62
66
  "esbuild-register": "^3.5.0",
63
67
  "postcss": "^8.4.47",
@@ -65,7 +69,7 @@
65
69
  "rollup-plugin-postcss": "^4.0.2",
66
70
  "rollup-plugin-swc3": "^0.12.1",
67
71
  "typescript": "^4.0.0||^5.0.0",
68
- "vite-bundle-analyzer": "^0.15.2"
72
+ "vite-bundle-analyzer": "0.16.0-beta.1"
69
73
  },
70
74
  "dependencies": {
71
75
  "@inquirer/prompts": "^7.1.0",
@@ -83,8 +87,8 @@
83
87
  "jsonc-parser": "^3.2.1",
84
88
  "koa": "^2.15.3",
85
89
  "rollup": "^4.0.0",
86
- "@jiek/utils": "^0.2.3",
87
- "@jiek/pkger": "^0.2.1"
90
+ "@jiek/pkger": "^0.2.1",
91
+ "@jiek/utils": "^0.2.3"
88
92
  },
89
93
  "peerDependenciesMeta": {
90
94
  "@pnpm/filter-workspace-packages": {
@@ -0,0 +1,122 @@
1
+ import type { Command } from 'commander'
2
+
3
+ import { CLIENT_CUSTOM_RENDER_SCRIPT } from '#~/commands/build/client/index.ts'
4
+ import { parseBoolean } from '#~/commands/utils/optionParser.ts'
5
+ import type { Module } from '#~/rollup/bundle-analyzer.ts'
6
+ import type { createServer } from '#~/server.ts'
7
+ import { checkDependency } from '#~/utils/checkDependency.ts'
8
+ import { existsSync, mkdirSync, statSync, writeFileSync } from 'node:fs'
9
+ import path from 'node:path'
10
+
11
+ export interface AnalyzerBuildOptions {
12
+ ana?: boolean
13
+ /**
14
+ * @default '.jk-analyses'
15
+ */
16
+ 'ana.dir': string
17
+ /**
18
+ * @default 'server'
19
+ */
20
+ 'ana.mode': string
21
+ 'ana.open'?: boolean
22
+ /**
23
+ * @default 'parsed'
24
+ */
25
+ 'ana.size': string
26
+ }
27
+
28
+ export const registerAnalyzerCommandOptions = (command: Command) =>
29
+ command
30
+ .option('--ana', 'Enable the bundle analyzer.', parseBoolean)
31
+ .option('--ana.dir <DIR>', 'The directory of the bundle analyzer.', '.jk-analyses')
32
+ .option(
33
+ '--ana.mode <MODE>',
34
+ 'The mode of the bundle analyzer, support "static", "json" and "server".',
35
+ 'server'
36
+ )
37
+ .option('--ana.open', 'Open the bundle analyzer in the browser.', parseBoolean)
38
+ .option(
39
+ '--ana.size <SIZE>',
40
+ 'The default size of the bundle analyzer, support "stat", "parsed" and "gzip".',
41
+ 'parsed'
42
+ )
43
+
44
+ export const useAnalyzer = async (options: AnalyzerBuildOptions, server?: ReturnType<typeof createServer>) => {
45
+ const modules: Module[] = []
46
+ let bundleAnalyzerModule: typeof import('vite-bundle-analyzer') | undefined
47
+ const analyzer = options.ana
48
+ ? {
49
+ dir: options['ana.dir'],
50
+ mode: options['ana.mode'],
51
+ open: options['ana.open'],
52
+ size: options['ana.size']
53
+ }
54
+ : undefined
55
+ if (
56
+ options.ana
57
+ && ![
58
+ 'stat',
59
+ 'parsed',
60
+ 'gzip'
61
+ ].includes(analyzer?.size ?? '')
62
+ ) {
63
+ throw new Error('The value of `ana.size` must be "stat", "parsed" or "gzip"')
64
+ }
65
+
66
+ if (analyzer) {
67
+ await checkDependency('vite-bundle-analyzer')
68
+ bundleAnalyzerModule = await import('vite-bundle-analyzer')
69
+ }
70
+
71
+ const refreshAnalyzer = async (cwd: string, applyModules: typeof modules) => {
72
+ if (!(analyzer && server && bundleAnalyzerModule)) return
73
+
74
+ if (analyzer.mode === 'json') {
75
+ const anaDir = path.resolve(cwd, analyzer.dir)
76
+ if (!existsSync(anaDir)) {
77
+ mkdirSync(anaDir, { recursive: true })
78
+ }
79
+ const gitIgnorePath = path.resolve(anaDir, '.gitignore')
80
+ if (!existsSync(gitIgnorePath)) {
81
+ writeFileSync(gitIgnorePath, '*\n!.gitignore\n')
82
+ }
83
+ const npmIgnorePath = path.resolve(anaDir, '.npmignore')
84
+ if (!existsSync(npmIgnorePath)) {
85
+ writeFileSync(npmIgnorePath, '*\n')
86
+ }
87
+ if (!statSync(anaDir).isDirectory()) {
88
+ throw new Error(`The directory '${anaDir}' is not a directory.`)
89
+ }
90
+ }
91
+
92
+ const { renderView, injectHTMLTag } = bundleAnalyzerModule
93
+ applyModules.forEach(m => {
94
+ const index = modules.findIndex(({ filename }) => filename === m.filename)
95
+ if (index === -1) {
96
+ modules.push(m)
97
+ } else {
98
+ modules[index] = m
99
+ }
100
+ })
101
+ let html = await renderView(modules, {
102
+ title: `Jiek Analyzer`,
103
+ mode: analyzer.size as 'stat' | 'parsed' | 'gzip'
104
+ })
105
+ html = injectHTMLTag({
106
+ html,
107
+ injectTo: 'body',
108
+ descriptors: [
109
+ { kind: 'script', text: CLIENT_CUSTOM_RENDER_SCRIPT }
110
+ ]
111
+ })
112
+ void server.renderTo('/ana', html)
113
+ }
114
+
115
+ return {
116
+ modules,
117
+ refreshAnalyzer,
118
+ ANALYZER_ENV: {
119
+ JIEK_ANALYZER: analyzer ? JSON.stringify(analyzer) : undefined
120
+ }
121
+ }
122
+ }
@@ -0,0 +1,121 @@
1
+ import type { Module } from '#~/rollup/bundle-analyzer.ts'
2
+
3
+ interface Node {
4
+ id: string
5
+ filename: string
6
+ parent?: Node
7
+ }
8
+
9
+ declare global {
10
+ // @ts-ignore
11
+ // eslint-disable-next-line no-var,vars-on-top
12
+ var React: typeof import('react')
13
+ // eslint-disable-next-line no-var,vars-on-top
14
+ var analyzeModule: Module[]
15
+ interface WindowEventMap {
16
+ 'graph:click': CustomEvent<
17
+ | undefined
18
+ | { node: Node }
19
+ >
20
+ 'send:filter': CustomEvent<{
21
+ analyzeModule: Module[]
22
+ }>
23
+ }
24
+ }
25
+
26
+ export function Main() {
27
+ const { useState, useMemo, useEffect, useCallback } = React
28
+ const [path, setPath] = useState(() => location.pathname.replace(/^\/ana\/?/, ''))
29
+ const [pkgName, entry] = useMemo(() => {
30
+ const pkgName = /^(@[^/]+\/[^/]+|[^/]+)\/?/.exec(path)?.[1]
31
+ return [
32
+ pkgName,
33
+ (pkgName != null) ? path.replace(`${pkgName}/`, '') : undefined
34
+ ]
35
+ }, [path])
36
+ const push = useCallback((newPath: string) => {
37
+ setPath(newPath)
38
+ document.title = `${document.title.replace(/ - \/.*/, '')} - \/${newPath}`
39
+ history.pushState(null, '', `/ana/${newPath}`)
40
+ }, [])
41
+ const filterModules = useCallback((startWith: string) => {
42
+ const modules = analyzeModule.filter(m => m.filename.startsWith(startWith))
43
+ dispatchEvent(new CustomEvent('send:filter', { detail: { analyzeModule: modules } }))
44
+ }, [])
45
+ useEffect(() => {
46
+ if (path !== '') {
47
+ document.title = `${document.title.replace(/ - \/.*/, '')} - \/${path}`
48
+ } else {
49
+ document.title = document.title.replace(/ - \/.*/, '')
50
+ }
51
+ filterModules(path)
52
+ }, [path, filterModules])
53
+ useEffect(() => {
54
+ const offGraphClick = listen('graph:click', ({ detail }) => {
55
+ if (!detail) return
56
+
57
+ let root = detail.node
58
+ while (root.parent) {
59
+ root = root.parent
60
+ }
61
+ if (root.filename === path) return
62
+ push(root.filename)
63
+ })
64
+ return () => {
65
+ offGraphClick()
66
+ }
67
+ }, [push])
68
+ function listen<T extends keyof WindowEventMap>(type: T, listener: (this: Window, ev: WindowEventMap[T]) => any) {
69
+ window.addEventListener(type, listener)
70
+ return () => {
71
+ window.removeEventListener(type, listener)
72
+ }
73
+ }
74
+ return (
75
+ <div
76
+ style={{
77
+ padding: '12px 55px'
78
+ }}
79
+ >
80
+ /
81
+ <select
82
+ style={{
83
+ appearance: 'none',
84
+ border: 'none',
85
+ background: 'none'
86
+ }}
87
+ value={pkgName}
88
+ onChange={e => push(e.target.value)}
89
+ >
90
+ <option value=''>All</option>
91
+ {analyzeModule
92
+ .map(m => /^(@[^/]+\/[^/]+|[^/]+)\/?/.exec(m.filename)?.[1])
93
+ .filter((v, i, a) => a.indexOf(v) === i)
94
+ .map(v => (
95
+ <option key={v} value={v}>{v}</option>
96
+ ))}
97
+ </select>
98
+ {pkgName != null && <>
99
+ /
100
+ <select
101
+ style={{
102
+ appearance: 'none',
103
+ border: 'none',
104
+ background: 'none'
105
+ }}
106
+ value={entry}
107
+ onChange={e => push(`${pkgName}/${e.target.value}`)}
108
+ >
109
+ <option value=''>All</option>
110
+ {analyzeModule
111
+ .filter(m => m.filename.startsWith(`${pkgName}/`))
112
+ .map(m => m.filename.replace(`${pkgName}/`, ''))
113
+ .filter((v, i, a) => a.indexOf(v) === i)
114
+ .map(v => (
115
+ <option key={v} value={v}>{v}</option>
116
+ ))}
117
+ </select>
118
+ </>}
119
+ </div>
120
+ )
121
+ }
@@ -0,0 +1,28 @@
1
+ import { Main } from './analyzer'
2
+
3
+ declare global {
4
+ // eslint-disable-next-line no-var,vars-on-top
5
+ var CUSTOM_SIDE_BAR: boolean
6
+ // eslint-disable-next-line no-var,vars-on-top
7
+ var __REPLACE_INJECT__: string
8
+ }
9
+
10
+ function render() {
11
+ CUSTOM_SIDE_BAR = true
12
+ window.addEventListener('client:ready', () =>
13
+ setTimeout(() => {
14
+ window.dispatchEvent(
15
+ new CustomEvent('send:ui', {
16
+ detail: { type: 'Main', Component: __REPLACE_INJECT__ }
17
+ })
18
+ )
19
+ }, 0))
20
+ }
21
+
22
+ export const CLIENT_CUSTOM_RENDER_SCRIPT = [
23
+ Main.toString(),
24
+ render
25
+ .toString()
26
+ .replace('__REPLACE_INJECT__', Main.name),
27
+ `(${render.name})()`
28
+ ].join('\n')