@electron-forge/plugin-vite 7.4.0 → 7.6.0

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.
Files changed (37) hide show
  1. package/README.md +2 -0
  2. package/dist/Config.d.ts +7 -2
  3. package/dist/Config.d.ts.map +1 -1
  4. package/dist/ViteConfig.d.ts +4 -6
  5. package/dist/ViteConfig.d.ts.map +1 -1
  6. package/dist/ViteConfig.js +26 -13
  7. package/dist/VitePlugin.d.ts +1 -2
  8. package/dist/VitePlugin.d.ts.map +1 -1
  9. package/dist/VitePlugin.js +34 -43
  10. package/dist/config/vite.base.config.d.ts +11 -0
  11. package/dist/config/vite.base.config.d.ts.map +1 -0
  12. package/dist/config/vite.base.config.js +90 -0
  13. package/dist/config/vite.main.config.d.ts +3 -0
  14. package/dist/config/vite.main.config.d.ts.map +1 -0
  15. package/dist/config/vite.main.config.js +34 -0
  16. package/dist/config/vite.preload.config.d.ts +3 -0
  17. package/dist/config/vite.preload.config.d.ts.map +1 -0
  18. package/dist/config/vite.preload.config.js +30 -0
  19. package/dist/config/vite.renderer.config.d.ts +3 -0
  20. package/dist/config/vite.renderer.config.d.ts.map +1 -0
  21. package/dist/config/vite.renderer.config.js +26 -0
  22. package/dist/util/plugins.d.ts.map +1 -1
  23. package/dist/util/plugins.js +1 -1
  24. package/forge-vite-env.d.ts +23 -0
  25. package/package.json +9 -8
  26. package/src/Config.ts +7 -3
  27. package/src/ViteConfig.ts +28 -13
  28. package/src/VitePlugin.ts +36 -46
  29. package/src/config/vite.base.config.ts +97 -0
  30. package/src/config/vite.main.config.ts +33 -0
  31. package/src/config/vite.preload.config.ts +28 -0
  32. package/src/config/vite.renderer.config.ts +25 -0
  33. package/src/util/plugins.ts +0 -1
  34. package/dist/util/package.d.ts +0 -14
  35. package/dist/util/package.d.ts.map +0 -1
  36. package/dist/util/package.js +0 -93
  37. package/src/util/package.ts +0 -108
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electron-forge/plugin-vite",
3
- "version": "7.4.0",
3
+ "version": "7.6.0",
4
4
  "description": "Vite plugin for Electron Forge, lets you use Vite directly in your tooling",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,17 +15,17 @@
15
15
  "test": "xvfb-maybe mocha --config ../../../.mocharc.js test/**/*_spec.ts test/*_spec.ts"
16
16
  },
17
17
  "dependencies": {
18
- "@electron-forge/core-utils": "7.4.0",
19
- "@electron-forge/plugin-base": "7.4.0",
20
- "@electron-forge/shared-types": "7.4.0",
21
- "@electron-forge/web-multi-logger": "7.4.0",
18
+ "@electron-forge/core-utils": "7.6.0",
19
+ "@electron-forge/plugin-base": "7.6.0",
20
+ "@electron-forge/shared-types": "7.6.0",
21
+ "@electron-forge/web-multi-logger": "7.6.0",
22
22
  "chalk": "^4.0.0",
23
23
  "debug": "^4.3.1",
24
24
  "fs-extra": "^10.0.0",
25
25
  "listr2": "^7.0.2"
26
26
  },
27
27
  "devDependencies": {
28
- "@electron/packager": "^18.3.1",
28
+ "@electron/packager": "^18.3.5",
29
29
  "@malept/cross-spawn-promise": "^2.0.0",
30
30
  "@types/node": "^18.0.3",
31
31
  "chai": "^4.3.3",
@@ -42,7 +42,8 @@
42
42
  },
43
43
  "files": [
44
44
  "dist",
45
- "src"
45
+ "src",
46
+ "forge-vite-env.d.ts"
46
47
  ],
47
- "gitHead": "d3d47b2bc53be13609b5ff4d858275ce74bff819"
48
+ "gitHead": "37a66f2a42e2ea74a30d168a32aff69c90cc20b9"
48
49
  }
package/src/Config.ts CHANGED
@@ -1,22 +1,26 @@
1
- // eslint-disable-next-line node/no-unpublished-import
2
1
  import type { LibraryOptions } from 'vite';
3
2
 
4
3
  export interface VitePluginBuildConfig {
5
4
  /**
6
5
  * Alias of `build.lib.entry` in `config`.
7
6
  */
8
- entry?: LibraryOptions['entry'];
7
+ entry: LibraryOptions['entry'];
9
8
  /**
10
9
  * Vite config file path.
11
10
  */
12
11
  config: string;
12
+ /**
13
+ * The build target is main process or preload script.
14
+ * @defaultValue 'main'
15
+ */
16
+ target?: 'main' | 'preload';
13
17
  }
14
18
 
15
19
  export interface VitePluginRendererConfig {
16
20
  /**
17
21
  * Human friendly name of your entry point.
18
22
  */
19
- name?: string;
23
+ name: string;
20
24
  /**
21
25
  * Vite config file path.
22
26
  */
package/src/ViteConfig.ts CHANGED
@@ -1,33 +1,47 @@
1
1
  import debug from 'debug';
2
- // eslint-disable-next-line node/no-unpublished-import
3
2
  import { loadConfigFromFile } from 'vite';
4
3
 
4
+ import { getConfig as getMainViteConfig } from './config/vite.main.config';
5
+ import { getConfig as getPreloadViteConfig } from './config/vite.preload.config';
6
+ import { getConfig as getRendererViteConfig } from './config/vite.renderer.config';
7
+
5
8
  import type { VitePluginBuildConfig, VitePluginConfig, VitePluginRendererConfig } from './Config';
6
- // eslint-disable-next-line node/no-unpublished-import
7
9
  import type { ConfigEnv, UserConfig } from 'vite';
8
10
 
9
11
  const d = debug('@electron-forge/plugin-vite:ViteConfig');
10
12
 
13
+ type Target = NonNullable<VitePluginBuildConfig['target']> | 'renderer';
14
+
11
15
  export default class ViteConfigGenerator {
12
16
  constructor(private readonly pluginConfig: VitePluginConfig, private readonly projectDir: string, private readonly isProd: boolean) {
13
17
  d('Config mode:', this.mode);
14
18
  }
15
19
 
16
- resolveConfig(buildConfig: VitePluginBuildConfig | VitePluginRendererConfig, configEnv: Partial<ConfigEnv> = {}) {
17
- // @see - https://vitejs.dev/config/#conditional-config
18
- configEnv.command ??= this.isProd ? 'build' : 'serve';
19
- // `mode` affects `.env.[mode]` file load.
20
- configEnv.mode ??= this.mode;
20
+ async resolveConfig(buildConfig: VitePluginBuildConfig | VitePluginRendererConfig, target: Target): Promise<UserConfig> {
21
+ const configEnv: ConfigEnv = {
22
+ // @see - https://vitejs.dev/config/#conditional-config
23
+ command: this.isProd ? 'build' : 'serve',
24
+ // `mode` affects `.env.[mode]` file load.
25
+ mode: this.mode,
21
26
 
22
- // Hack! Pass the forge runtime config to the vite config file in the template.
23
- Object.assign(configEnv, {
27
+ // Forge extension variables.
24
28
  root: this.projectDir,
25
29
  forgeConfig: this.pluginConfig,
26
30
  forgeConfigSelf: buildConfig,
27
- });
31
+ };
28
32
 
29
33
  // `configEnv` is to be passed as an arguments when the user export a function in `vite.config.js`.
30
- return loadConfigFromFile(configEnv as ConfigEnv, buildConfig.config);
34
+ const userConfig = (await loadConfigFromFile(configEnv, buildConfig.config))?.config;
35
+ switch (target) {
36
+ case 'main':
37
+ return getMainViteConfig(configEnv as ConfigEnv<'build'>, userConfig);
38
+ case 'preload':
39
+ return getPreloadViteConfig(configEnv as ConfigEnv<'build'>, userConfig);
40
+ case 'renderer':
41
+ return getRendererViteConfig(configEnv as ConfigEnv<'renderer'>, userConfig);
42
+ default:
43
+ throw new Error(`Unknown target: ${target}, expected 'main', 'preload' or 'renderer'`);
44
+ }
31
45
  }
32
46
 
33
47
  get mode(): string {
@@ -45,7 +59,7 @@ export default class ViteConfigGenerator {
45
59
  const configs = this.pluginConfig.build
46
60
  // Prevent load the default `vite.config.js` file.
47
61
  .filter(({ config }) => config)
48
- .map<Promise<UserConfig>>(async (buildConfig) => (await this.resolveConfig(buildConfig))?.config ?? {});
62
+ .map((buildConfig) => this.resolveConfig(buildConfig, buildConfig.target ?? 'main'));
49
63
 
50
64
  return await Promise.all(configs);
51
65
  }
@@ -56,8 +70,9 @@ export default class ViteConfigGenerator {
56
70
  }
57
71
 
58
72
  const configs = this.pluginConfig.renderer
73
+ // Prevent load the default `vite.config.js` file.
59
74
  .filter(({ config }) => config)
60
- .map<Promise<UserConfig>>(async (buildConfig) => (await this.resolveConfig(buildConfig))?.config ?? {});
75
+ .map((buildConfig) => this.resolveConfig(buildConfig, 'renderer'));
61
76
 
62
77
  return await Promise.all(configs);
63
78
  }
package/src/VitePlugin.ts CHANGED
@@ -5,15 +5,13 @@ import chalk from 'chalk';
5
5
  import debug from 'debug';
6
6
  import fs from 'fs-extra';
7
7
  import { PRESET_TIMER } from 'listr2';
8
- // eslint-disable-next-line node/no-unpublished-import
9
8
  import { default as vite } from 'vite';
10
9
 
11
- import { getFlatDependencies } from './util/package';
12
10
  import { onBuildDone } from './util/plugins';
13
11
  import ViteConfigGenerator from './ViteConfig';
14
12
 
15
13
  import type { VitePluginConfig } from './Config';
16
- import type { ForgeMultiHookMap, ResolvedForgeConfig, StartResult } from '@electron-forge/shared-types';
14
+ import type { ForgeMultiHookMap, ResolvedForgeConfig } from '@electron-forge/shared-types';
17
15
  import type { AddressInfo } from 'node:net';
18
16
  // eslint-disable-next-line node/no-extraneous-import
19
17
  import type { RollupWatcher } from 'rollup';
@@ -58,6 +56,37 @@ export default class VitePlugin extends PluginBase<VitePluginConfig> {
58
56
 
59
57
  getHooks = (): ForgeMultiHookMap => {
60
58
  return {
59
+ preStart: [
60
+ namedHookWithTaskFn<'preStart'>(async (task) => {
61
+ if (VitePlugin.alreadyStarted) return;
62
+ VitePlugin.alreadyStarted = true;
63
+
64
+ await fs.remove(this.baseDir);
65
+
66
+ return task?.newListr([
67
+ {
68
+ title: 'Launching dev servers for renderer process code',
69
+ task: async () => {
70
+ await this.launchRendererDevServers();
71
+ },
72
+ rendererOptions: {
73
+ persistentOutput: true,
74
+ timer: { ...PRESET_TIMER },
75
+ },
76
+ },
77
+ // The main process depends on the `server.port` of the renderer process, so the renderer process is run first.
78
+ {
79
+ title: 'Compiling main process code',
80
+ task: async () => {
81
+ await this.build();
82
+ },
83
+ rendererOptions: {
84
+ timer: { ...PRESET_TIMER },
85
+ },
86
+ },
87
+ ]) as any;
88
+ }, 'Preparing vite bundles'),
89
+ ],
61
90
  prePackage: [
62
91
  namedHookWithTaskFn<'prePackage'>(async () => {
63
92
  this.isProd = true;
@@ -95,8 +124,10 @@ Your packaged app may be larger than expected if you dont ignore everything othe
95
124
  forgeConfig.packagerConfig.ignore = (file: string) => {
96
125
  if (!file) return false;
97
126
 
98
- // Always starts with `/`
127
+ // `file` always starts with `/`
99
128
  // @see - https://github.com/electron/packager/blob/v18.1.3/src/copy-filter.ts#L89-L93
129
+
130
+ // Collect the files built by Vite
100
131
  return !file.startsWith('/.vite');
101
132
  };
102
133
  return forgeConfig;
@@ -104,7 +135,6 @@ Your packaged app may be larger than expected if you dont ignore everything othe
104
135
 
105
136
  packageAfterCopy = async (_forgeConfig: ResolvedForgeConfig, buildPath: string): Promise<void> => {
106
137
  const pj = await fs.readJson(path.resolve(this.projectDir, 'package.json'));
107
- const flatDependencies = await getFlatDependencies(this.projectDir);
108
138
 
109
139
  if (!pj.main?.includes('.vite/')) {
110
140
  throw new Error(`Electron Forge is configured to use the Vite plugin. The plugin expects the
@@ -116,47 +146,7 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}`);
116
146
  delete pj.config.forge;
117
147
  }
118
148
 
119
- await fs.writeJson(path.resolve(buildPath, 'package.json'), pj, {
120
- spaces: 2,
121
- });
122
-
123
- // Copy the dependencies in package.json
124
- for (const dep of flatDependencies) {
125
- await fs.copy(dep.src, path.resolve(buildPath, dep.dest));
126
- }
127
- };
128
-
129
- startLogic = async (): Promise<StartResult> => {
130
- if (VitePlugin.alreadyStarted) return false;
131
- VitePlugin.alreadyStarted = true;
132
-
133
- await fs.remove(this.baseDir);
134
-
135
- return {
136
- tasks: [
137
- {
138
- title: 'Launching dev servers for renderer process code',
139
- task: async () => {
140
- await this.launchRendererDevServers();
141
- },
142
- rendererOptions: {
143
- persistentOutput: true,
144
- timer: { ...PRESET_TIMER },
145
- },
146
- },
147
- // The main process depends on the `server.port` of the renderer process, so the renderer process is run first.
148
- {
149
- title: 'Compiling main process code',
150
- task: async () => {
151
- await this.build();
152
- },
153
- rendererOptions: {
154
- timer: { ...PRESET_TIMER },
155
- },
156
- },
157
- ],
158
- result: false,
159
- };
149
+ await fs.writeJson(path.resolve(buildPath, 'package.json'), pj, { spaces: 2 });
160
150
  };
161
151
 
162
152
  // Main process, Preload scripts and Worker process, etc.
@@ -0,0 +1,97 @@
1
+ import { builtinModules } from 'node:module';
2
+
3
+ import type { AddressInfo } from 'node:net';
4
+ import type { ConfigEnv, Plugin, UserConfig, ViteDevServer } from 'vite';
5
+
6
+ export const builtins = ['electron', ...builtinModules.map((m) => [m, `node:${m}`]).flat()];
7
+
8
+ export const external = [...builtins];
9
+
10
+ // Used for hot reload after preload scripts.
11
+ const viteDevServers: Record<string, ViteDevServer> = {};
12
+ const viteDevServerUrls: Record<string, string> = {};
13
+
14
+ export function getBuildConfig(env: ConfigEnv<'build'>): UserConfig {
15
+ const { root, mode, command } = env;
16
+
17
+ return {
18
+ root,
19
+ mode,
20
+ build: {
21
+ // Prevent multiple builds from interfering with each other.
22
+ emptyOutDir: false,
23
+ // 🚧 Multiple builds may conflict.
24
+ outDir: '.vite/build',
25
+ watch: command === 'serve' ? {} : null,
26
+ minify: command === 'build',
27
+ },
28
+ clearScreen: false,
29
+ };
30
+ }
31
+
32
+ export function getDefineKeys(names: string[]) {
33
+ const define: { [name: string]: VitePluginRuntimeKeys } = {};
34
+
35
+ return names.reduce((acc, name) => {
36
+ const NAME = name.toUpperCase();
37
+ const keys: VitePluginRuntimeKeys = {
38
+ VITE_DEV_SERVER_URL: `${NAME}_VITE_DEV_SERVER_URL`,
39
+ VITE_NAME: `${NAME}_VITE_NAME`,
40
+ };
41
+
42
+ return { ...acc, [name]: keys };
43
+ }, define);
44
+ }
45
+
46
+ export function getBuildDefine(env: ConfigEnv<'build'>) {
47
+ const { command, forgeConfig } = env;
48
+ const names = forgeConfig.renderer.filter(({ name }) => name != null).map(({ name }) => name!);
49
+ const defineKeys = getDefineKeys(names);
50
+ const define = Object.entries(defineKeys).reduce((acc, [name, keys]) => {
51
+ const { VITE_DEV_SERVER_URL, VITE_NAME } = keys;
52
+ const def = {
53
+ [VITE_DEV_SERVER_URL]: command === 'serve' ? JSON.stringify(viteDevServerUrls[VITE_DEV_SERVER_URL]) : undefined,
54
+ [VITE_NAME]: JSON.stringify(name),
55
+ };
56
+ return { ...acc, ...def };
57
+ }, {} as Record<string, any>);
58
+
59
+ return define;
60
+ }
61
+
62
+ export function pluginExposeRenderer(name: string): Plugin {
63
+ const { VITE_DEV_SERVER_URL } = getDefineKeys([name])[name];
64
+
65
+ return {
66
+ name: '@electron-forge/plugin-vite:expose-renderer',
67
+ configureServer(server) {
68
+ // Expose server for preload scripts hot reload.
69
+ viteDevServers[name] = server;
70
+
71
+ server.httpServer?.once('listening', () => {
72
+ const addressInfo = server.httpServer?.address() as AddressInfo;
73
+ // Expose env constant for main process use.
74
+ viteDevServerUrls[VITE_DEV_SERVER_URL] = `http://localhost:${addressInfo?.port}`;
75
+ });
76
+ },
77
+ };
78
+ }
79
+
80
+ export function pluginHotRestart(command: 'reload' | 'restart'): Plugin {
81
+ return {
82
+ name: '@electron-forge/plugin-vite:hot-restart',
83
+ closeBundle() {
84
+ if (command === 'reload') {
85
+ for (const server of Object.values(viteDevServers)) {
86
+ // Preload scripts hot reload.
87
+ server.ws.send({ type: 'full-reload' });
88
+ }
89
+ } else if (command === 'restart') {
90
+ // Main process hot restart.
91
+ // https://github.com/electron/forge/blob/v7.2.0/packages/api/core/src/api/start.ts#L216-L223
92
+ // TODO: blocked in #3380
93
+ // process.stdin.emit('data', 'rs');
94
+ }
95
+ },
96
+ };
97
+ }
@@ -0,0 +1,33 @@
1
+ import { type ConfigEnv, mergeConfig, type UserConfig } from 'vite';
2
+
3
+ import { external, getBuildConfig, getBuildDefine, pluginHotRestart } from './vite.base.config';
4
+
5
+ export function getConfig(forgeEnv: ConfigEnv<'build'>, userConfig: UserConfig = {}): UserConfig {
6
+ const { forgeConfigSelf } = forgeEnv;
7
+ const define = getBuildDefine(forgeEnv);
8
+ const config: UserConfig = {
9
+ build: {
10
+ rollupOptions: {
11
+ external,
12
+ },
13
+ },
14
+ plugins: [pluginHotRestart('restart')],
15
+ define,
16
+ resolve: {
17
+ // Load the Node.js entry.
18
+ conditions: ['node'],
19
+ mainFields: ['module', 'jsnext:main', 'jsnext'],
20
+ },
21
+ };
22
+ const buildConfig = getBuildConfig(forgeEnv);
23
+
24
+ if (userConfig.build?.lib == null) {
25
+ config.build!.lib = {
26
+ entry: forgeConfigSelf.entry,
27
+ fileName: () => '[name].js',
28
+ formats: ['cjs'],
29
+ };
30
+ }
31
+
32
+ return mergeConfig(mergeConfig(buildConfig, config), userConfig);
33
+ }
@@ -0,0 +1,28 @@
1
+ import { type ConfigEnv, mergeConfig, type UserConfig } from 'vite';
2
+
3
+ import { external, getBuildConfig, pluginHotRestart } from './vite.base.config';
4
+
5
+ export function getConfig(forgeEnv: ConfigEnv<'build'>, userConfig: UserConfig = {}): UserConfig {
6
+ const { forgeConfigSelf } = forgeEnv;
7
+ const config: UserConfig = {
8
+ build: {
9
+ rollupOptions: {
10
+ external,
11
+ // Preload scripts may contain Web assets, so use the `build.rollupOptions.input` instead `build.lib.entry`.
12
+ input: forgeConfigSelf.entry,
13
+ output: {
14
+ format: 'cjs',
15
+ // It should not be split chunks.
16
+ inlineDynamicImports: true,
17
+ entryFileNames: '[name].js',
18
+ chunkFileNames: '[name].js',
19
+ assetFileNames: '[name].[ext]',
20
+ },
21
+ },
22
+ },
23
+ plugins: [pluginHotRestart('reload')],
24
+ };
25
+ const buildConfig = getBuildConfig(forgeEnv);
26
+
27
+ return mergeConfig(mergeConfig(buildConfig, config), userConfig);
28
+ }
@@ -0,0 +1,25 @@
1
+ import { type ConfigEnv, mergeConfig, type UserConfig } from 'vite';
2
+
3
+ import { pluginExposeRenderer } from './vite.base.config';
4
+
5
+ // https://vitejs.dev/config
6
+ export function getConfig(forgeEnv: ConfigEnv<'renderer'>, userConfig: UserConfig = {}) {
7
+ const { root, mode, forgeConfigSelf } = forgeEnv;
8
+ const name = forgeConfigSelf.name ?? '';
9
+
10
+ const config: UserConfig = {
11
+ root,
12
+ mode,
13
+ base: './',
14
+ build: {
15
+ outDir: `.vite/renderer/${name}`,
16
+ },
17
+ plugins: [pluginExposeRenderer(name)],
18
+ resolve: {
19
+ preserveSymlinks: true,
20
+ },
21
+ clearScreen: false,
22
+ };
23
+
24
+ return mergeConfig(config, userConfig);
25
+ }
@@ -1,4 +1,3 @@
1
- // eslint-disable-next-line node/no-unpublished-import
2
1
  import type { Plugin } from 'vite';
3
2
 
4
3
  export function onBuildDone(callback: () => void) {
@@ -1,14 +0,0 @@
1
- export interface Dependency {
2
- name: string;
3
- path: SourceAndDestination;
4
- dependencies: Dependency[];
5
- }
6
- export interface SourceAndDestination {
7
- src: string;
8
- dest: string;
9
- }
10
- export declare function isDirectory(p: string): Promise<boolean>;
11
- export declare function lookupNodeModulesPaths(root: string, paths?: string[]): Promise<string[]>;
12
- export declare function resolveDependencies(root: string): Promise<Dependency[]>;
13
- export declare function getFlatDependencies(root?: string): Promise<SourceAndDestination[]>;
14
- //# sourceMappingURL=package.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../../src/util/package.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,oBAAoB,CAAC;IAC3B,YAAY,EAAE,UAAU,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAOD,wBAAsB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO7D;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAYlG;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,yBAmDrD;AAED,wBAAsB,mBAAmB,CAAC,IAAI,SAAgB,mCAW7D"}
@@ -1,93 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getFlatDependencies = exports.resolveDependencies = exports.lookupNodeModulesPaths = exports.isDirectory = void 0;
7
- const node_path_1 = __importDefault(require("node:path"));
8
- const fs_extra_1 = __importDefault(require("fs-extra"));
9
- function isRootPath(dir) {
10
- // *unix or Windows root path
11
- return dir === '/' || /^[a-zA-Z]:\\$/i.test(dir);
12
- }
13
- async function isDirectory(p) {
14
- try {
15
- const stat = await fs_extra_1.default.promises.stat(p);
16
- return stat.isDirectory();
17
- }
18
- catch {
19
- return false;
20
- }
21
- }
22
- exports.isDirectory = isDirectory;
23
- async function lookupNodeModulesPaths(root, paths = []) {
24
- if (!root)
25
- return paths;
26
- if (!node_path_1.default.isAbsolute(root))
27
- return paths;
28
- const p = node_path_1.default.join(root, 'node_modules');
29
- if (await isDirectory(p)) {
30
- paths = paths.concat(p);
31
- }
32
- root = node_path_1.default.join(root, '..');
33
- return isRootPath(root) ? paths : await lookupNodeModulesPaths(root, paths);
34
- }
35
- exports.lookupNodeModulesPaths = lookupNodeModulesPaths;
36
- async function resolveDependencies(root) {
37
- const rootDependencies = Object.keys((await fs_extra_1.default.readJson(node_path_1.default.join(root, 'package.json'))).dependencies || {});
38
- const resolve = async (prePath, dependencies, collected = new Map()) => await Promise.all(dependencies.map(async (name) => {
39
- let curPath = prePath, depPath = null, packageJson = null;
40
- while (!packageJson && !isRootPath(curPath)) {
41
- const allNodeModules = await lookupNodeModulesPaths(curPath);
42
- for (const nodeModules of allNodeModules) {
43
- depPath = node_path_1.default.join(nodeModules, name);
44
- if (await fs_extra_1.default.pathExists(depPath))
45
- break;
46
- }
47
- if (depPath) {
48
- try {
49
- packageJson = await fs_extra_1.default.readJson(node_path_1.default.join(depPath, 'package.json'));
50
- }
51
- catch (err) {
52
- // lookup node_modules
53
- curPath = node_path_1.default.join(curPath, '..');
54
- if (curPath.length < root.length) {
55
- console.error(`not found 'node_modules' in root path: ${root}`);
56
- throw err;
57
- }
58
- }
59
- }
60
- }
61
- if (!depPath || !packageJson) {
62
- throw new Error(`find dependencies error in: ${curPath}`);
63
- }
64
- const result = {
65
- name,
66
- path: {
67
- src: depPath,
68
- dest: node_path_1.default.relative(root, depPath),
69
- },
70
- dependencies: [],
71
- };
72
- const shouldResolveDeps = !collected.has(depPath);
73
- collected.set(depPath, result);
74
- if (shouldResolveDeps) {
75
- result.dependencies = await resolve(depPath, Object.keys(packageJson.dependencies || {}), collected);
76
- }
77
- return result;
78
- }));
79
- return resolve(root, rootDependencies);
80
- }
81
- exports.resolveDependencies = resolveDependencies;
82
- async function getFlatDependencies(root = process.cwd()) {
83
- const depsTree = await resolveDependencies(root);
84
- const depsFlat = new Map();
85
- const flatten = (dep) => {
86
- depsFlat.set(dep.path.src, dep.path); // dedup
87
- dep.dependencies.forEach(flatten);
88
- };
89
- depsTree.forEach(flatten);
90
- return [...depsFlat.values()];
91
- }
92
- exports.getFlatDependencies = getFlatDependencies;
93
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFja2FnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsL3BhY2thZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsMERBQTZCO0FBRTdCLHdEQUEwQjtBQWExQixTQUFTLFVBQVUsQ0FBQyxHQUFXO0lBQzdCLDZCQUE2QjtJQUM3QixPQUFPLEdBQUcsS0FBSyxHQUFHLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFFTSxLQUFLLFVBQVUsV0FBVyxDQUFDLENBQVM7SUFDekMsSUFBSTtRQUNGLE1BQU0sSUFBSSxHQUFHLE1BQU0sa0JBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLE9BQU8sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0tBQzNCO0lBQUMsTUFBTTtRQUNOLE9BQU8sS0FBSyxDQUFDO0tBQ2Q7QUFDSCxDQUFDO0FBUEQsa0NBT0M7QUFFTSxLQUFLLFVBQVUsc0JBQXNCLENBQUMsSUFBWSxFQUFFLFFBQWtCLEVBQUU7SUFDN0UsSUFBSSxDQUFDLElBQUk7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUN4QixJQUFJLENBQUMsbUJBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFFekMsTUFBTSxDQUFDLEdBQUcsbUJBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBRTFDLElBQUksTUFBTSxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7UUFDeEIsS0FBSyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7S0FDekI7SUFDRCxJQUFJLEdBQUcsbUJBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBRTdCLE9BQU8sVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxL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