From 548596903684ff592474763f768382913d239473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Wang=28=E8=8D=89=E9=9E=8B=E6=B2=A1=E5=8F=B7=29?= <308487730@qq.com> Date: Sun, 28 Apr 2024 23:25:19 +0800 Subject: [PATCH 01/12] refactor(plugin-vite): better \`node_modules\` collect strategy --- package.json | 1 + packages/plugin/vite/package.json | 1 + packages/plugin/vite/src/VitePlugin.ts | 21 ++-- packages/plugin/vite/src/util/package.ts | 110 +----------------- .../plugin/vite/test/util/package_spec.ts | 61 +--------- 5 files changed, 22 insertions(+), 172 deletions(-) diff --git a/package.json b/package.json index b829274128..1b8374bbc3 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "fast-glob": "^3.2.7", "filenamify": "^4.1.0", "find-up": "^5.0.0", + "flora-colossus": "^2.0.0", "form-data": "^4.0.0", "fs-extra": "^10.0.0", "got": "^11.8.5", diff --git a/packages/plugin/vite/package.json b/packages/plugin/vite/package.json index c3f80b91bc..88867c5e61 100644 --- a/packages/plugin/vite/package.json +++ b/packages/plugin/vite/package.json @@ -21,6 +21,7 @@ "@electron-forge/web-multi-logger": "7.4.0", "chalk": "^4.0.0", "debug": "^4.3.1", + "flora-colossus": "^2.0.0", "fs-extra": "^10.0.0", "listr2": "^7.0.2" }, diff --git a/packages/plugin/vite/src/VitePlugin.ts b/packages/plugin/vite/src/VitePlugin.ts index 1df51a905f..523542acb5 100644 --- a/packages/plugin/vite/src/VitePlugin.ts +++ b/packages/plugin/vite/src/VitePlugin.ts @@ -92,11 +92,20 @@ Your packaged app may be larger than expected if you dont ignore everything othe return forgeConfig; } + const flatDeps = await getFlatDependencies(this.projectDir); forgeConfig.packagerConfig.ignore = (file: string) => { if (!file) return false; - // Always starts with `/` + // `file` always starts with `/` // @see - https://github.com/electron/packager/blob/v18.1.3/src/copy-filter.ts#L89-L93 + + // Collect dependencies from package.json + if (file.startsWith('/node_modules')) { + const [, , name] = file.split('/'); + return flatDeps.some((dep) => dep.name === name); + } + + // Collect the files built by Vite return !file.startsWith('/.vite'); }; return forgeConfig; @@ -104,7 +113,6 @@ Your packaged app may be larger than expected if you dont ignore everything othe packageAfterCopy = async (_forgeConfig: ResolvedForgeConfig, buildPath: string): Promise => { const pj = await fs.readJson(path.resolve(this.projectDir, 'package.json')); - const flatDependencies = await getFlatDependencies(this.projectDir); if (!pj.main?.includes('.vite/')) { throw new Error(`Electron Forge is configured to use the Vite plugin. The plugin expects the @@ -116,14 +124,7 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}`); delete pj.config.forge; } - await fs.writeJson(path.resolve(buildPath, 'package.json'), pj, { - spaces: 2, - }); - - // Copy the dependencies in package.json - for (const dep of flatDependencies) { - await fs.copy(dep.src, path.resolve(buildPath, dep.dest)); - } + await fs.writeJson(path.resolve(buildPath, 'package.json'), pj, { spaces: 2 }); }; startLogic = async (): Promise => { diff --git a/packages/plugin/vite/src/util/package.ts b/packages/plugin/vite/src/util/package.ts index 0fbb9a4a78..3d1d358f42 100644 --- a/packages/plugin/vite/src/util/package.ts +++ b/packages/plugin/vite/src/util/package.ts @@ -1,108 +1,8 @@ -import path from 'node:path'; +import { DepType, Walker } from 'flora-colossus'; -import fs from 'fs-extra'; +export async function getFlatDependencies(root: string) { + const walker = new Walker(root); + const deps = await walker.walkTree(); -export interface Dependency { - name: string; - path: SourceAndDestination; - dependencies: Dependency[]; -} - -export interface SourceAndDestination { - src: string; - dest: string; -} - -function isRootPath(dir: string) { - // *unix or Windows root path - return dir === '/' || /^[a-zA-Z]:\\$/i.test(dir); -} - -export async function isDirectory(p: string): Promise { - try { - const stat = await fs.promises.stat(p); - return stat.isDirectory(); - } catch { - return false; - } -} - -export async function lookupNodeModulesPaths(root: string, paths: string[] = []): Promise { - if (!root) return paths; - if (!path.isAbsolute(root)) return paths; - - const p = path.join(root, 'node_modules'); - - if (await isDirectory(p)) { - paths = paths.concat(p); - } - root = path.join(root, '..'); - - return isRootPath(root) ? paths : await lookupNodeModulesPaths(root, paths); -} - -export async function resolveDependencies(root: string) { - const rootDependencies = Object.keys((await fs.readJson(path.join(root, 'package.json'))).dependencies || {}); - const resolve = async (prePath: string, dependencies: string[], collected: Map = new Map()) => - await Promise.all( - dependencies.map(async (name) => { - let curPath = prePath, - depPath = null, - packageJson = null; - while (!packageJson && !isRootPath(curPath)) { - const allNodeModules = await lookupNodeModulesPaths(curPath); - - for (const nodeModules of allNodeModules) { - depPath = path.join(nodeModules, name); - if (await fs.pathExists(depPath)) break; - } - - if (depPath) { - try { - packageJson = await fs.readJson(path.join(depPath, 'package.json')); - } catch (err) { - // lookup node_modules - curPath = path.join(curPath, '..'); - if (curPath.length < root.length) { - console.error(`not found 'node_modules' in root path: ${root}`); - throw err; - } - } - } - } - - if (!depPath || !packageJson) { - throw new Error(`find dependencies error in: ${curPath}`); - } - - const result: Dependency = { - name, - path: { - src: depPath, - dest: path.relative(root, depPath), - }, - dependencies: [], - }; - const shouldResolveDeps = !collected.has(depPath); - collected.set(depPath, result); - if (shouldResolveDeps) { - result.dependencies = await resolve(depPath, Object.keys(packageJson.dependencies || {}), collected); - } - return result; - }) - ); - return resolve(root, rootDependencies); -} - -export async function getFlatDependencies(root = process.cwd()) { - const depsTree = await resolveDependencies(root); - const depsFlat = new Map(); - - const flatten = (dep: Dependency) => { - depsFlat.set(dep.path.src, dep.path); // dedup - dep.dependencies.forEach(flatten); - }; - depsTree.forEach(flatten); - - return [...depsFlat.values()]; + return deps.filter((dep) => dep.depType === DepType.PROD); } diff --git a/packages/plugin/vite/test/util/package_spec.ts b/packages/plugin/vite/test/util/package_spec.ts index 8833d43afd..74bc75b1df 100644 --- a/packages/plugin/vite/test/util/package_spec.ts +++ b/packages/plugin/vite/test/util/package_spec.ts @@ -4,52 +4,11 @@ import { promisify } from 'node:util'; import { expect } from 'chai'; -import { getFlatDependencies, isDirectory, lookupNodeModulesPaths, resolveDependencies } from '../../src/util/package'; +import { getFlatDependencies } from '../../src/util/package'; const execPromise = promisify(exec); const packageRoot = path.join(__dirname, '../fixture/package'); -const depsTree = [ - { - name: 'electron-squirrel-startup', - path: { - src: path.join(packageRoot, 'node_modules', 'electron-squirrel-startup'), - dest: path.join('node_modules', 'electron-squirrel-startup'), - }, - dependencies: [ - { - name: 'debug', - path: { - src: path.join(packageRoot, 'node_modules', 'debug'), - dest: path.join('node_modules', 'debug'), - }, - dependencies: [ - { - name: 'ms', - path: { - src: path.join(packageRoot, 'node_modules', 'ms'), - dest: path.join('node_modules', 'ms'), - }, - dependencies: [], - }, - ], - }, - ], - }, -]; -const depsFlat = [ - { - src: path.join(packageRoot, 'node_modules', 'electron-squirrel-startup'), - dest: path.join('node_modules', 'electron-squirrel-startup'), - }, - { - src: path.join(packageRoot, 'node_modules', 'debug'), - dest: path.join('node_modules', 'debug'), - }, - { - src: path.join(packageRoot, 'node_modules', 'ms'), - dest: path.join('node_modules', 'ms'), - }, -]; +const proDeps = ['electron-squirrel-startup', 'debug', 'ms']; describe('util/package', () => { before(async () => { @@ -57,19 +16,7 @@ describe('util/package', () => { }); it('dependencies of package.json is resolved correct', async () => { - const depsT = await resolveDependencies(packageRoot); - const depsF = await getFlatDependencies(packageRoot); - expect(depsTree).deep.equal(depsT); - expect(depsFlat).deep.equal(depsF); - }); - - it('isDirectory check is correct', async () => { - expect(await isDirectory(packageRoot)).true; - expect(await isDirectory(path.join(packageRoot, 'package.json'))).false; - }); - - it('node_modules paths is lookup correct', async () => { - const paths = await lookupNodeModulesPaths(packageRoot); - expect(paths.length).gt(0); + const flatDeps = await getFlatDependencies(packageRoot); + expect(proDeps).deep.equal(flatDeps.map((dep) => dep.name)); }); }); From 34c6446c270c6a36abe90488ca9887aa79d19bfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Wang=28=E8=8D=89=E9=9E=8B=E6=B2=A1=E5=8F=B7=29?= <308487730@qq.com> Date: Tue, 30 Apr 2024 12:27:46 +0800 Subject: [PATCH 02/12] refactor(plugin-vite): move vite config from template to plugin --- .../vite/forge-vite-env.d.ts} | 0 .../vite/src/config}/vite.base.config.ts | 10 +- .../vite/src/config/vite.main.config.ts} | 23 ++-- .../vite/src/config/vite.preload.config.ts} | 22 ++-- .../vite/src/config/vite.renderer.config.ts} | 15 ++- .../vite-typescript/tmpl/forge.config.ts | 2 + .../vite-typescript/tmpl/forge.env.d.ts | 32 +---- .../vite-typescript/tmpl/vite.main.config.ts | 30 +---- .../tmpl/vite.preload.config.ts | 29 +---- .../tmpl/vite.renderer.config.ts | 22 +--- packages/template/vite/src/ViteTemplate.ts | 10 +- .../template/vite/test/ViteTemplate_spec.ts | 7 +- packages/template/vite/tmpl/forge.config.js | 8 +- packages/template/vite/tmpl/forge.env.d.ts | 1 + .../template/vite/tmpl/vite.base.config.mjs | 109 ------------------ .../template/vite/tmpl/vite.main.config.js | 4 + .../template/vite/tmpl/vite.preload.config.js | 4 + .../vite/tmpl/vite.renderer.config.js | 4 + 18 files changed, 63 insertions(+), 269 deletions(-) rename packages/{template/vite/tmpl/forge.env.d.txt => plugin/vite/forge-vite-env.d.ts} (100%) rename packages/{template/vite-typescript/tmpl => plugin/vite/src/config}/vite.base.config.ts (91%) rename packages/{template/vite/tmpl/vite.main.config.mjs => plugin/vite/src/config/vite.main.config.ts} (54%) rename packages/{template/vite/tmpl/vite.preload.config.mjs => plugin/vite/src/config/vite.preload.config.ts} (60%) rename packages/{template/vite/tmpl/vite.renderer.config.mjs => plugin/vite/src/config/vite.renderer.config.ts} (56%) create mode 100644 packages/template/vite/tmpl/forge.env.d.ts delete mode 100644 packages/template/vite/tmpl/vite.base.config.mjs create mode 100644 packages/template/vite/tmpl/vite.main.config.js create mode 100644 packages/template/vite/tmpl/vite.preload.config.js create mode 100644 packages/template/vite/tmpl/vite.renderer.config.js diff --git a/packages/template/vite/tmpl/forge.env.d.txt b/packages/plugin/vite/forge-vite-env.d.ts similarity index 100% rename from packages/template/vite/tmpl/forge.env.d.txt rename to packages/plugin/vite/forge-vite-env.d.ts diff --git a/packages/template/vite-typescript/tmpl/vite.base.config.ts b/packages/plugin/vite/src/config/vite.base.config.ts similarity index 91% rename from packages/template/vite-typescript/tmpl/vite.base.config.ts rename to packages/plugin/vite/src/config/vite.base.config.ts index 25120d990d..ee81f5a870 100644 --- a/packages/template/vite-typescript/tmpl/vite.base.config.ts +++ b/packages/plugin/vite/src/config/vite.base.config.ts @@ -1,11 +1,12 @@ import { builtinModules } from 'node:module'; + import type { AddressInfo } from 'node:net'; +// eslint-disable-next-line node/no-unpublished-import import type { ConfigEnv, Plugin, UserConfig } from 'vite'; -import pkg from './package.json'; export const builtins = ['electron', ...builtinModules.map((m) => [m, `node:${m}`]).flat()]; -export const external = [...builtins, ...Object.keys('dependencies' in pkg ? (pkg.dependencies as Record) : {})]; +export const external = [...builtins]; export function getBuildConfig(env: ConfigEnv<'build'>): UserConfig { const { root, mode, command } = env; @@ -66,7 +67,7 @@ export function pluginExposeRenderer(name: string): Plugin { process.viteDevServers[name] = server; server.httpServer?.once('listening', () => { - const addressInfo = server.httpServer!.address() as AddressInfo; + const addressInfo = server.httpServer?.address() as AddressInfo; // Expose env constant for main process use. process.env[VITE_DEV_SERVER_URL] = `http://localhost:${addressInfo?.port}`; }); @@ -86,7 +87,8 @@ export function pluginHotRestart(command: 'reload' | 'restart'): Plugin { } else { // Main process hot restart. // https://github.com/electron/forge/blob/v7.2.0/packages/api/core/src/api/start.ts#L216-L223 - process.stdin.emit('data', 'rs'); + // TODO: blocked in #3380 + // process.stdin.emit('data', 'rs'); } }, }; diff --git a/packages/template/vite/tmpl/vite.main.config.mjs b/packages/plugin/vite/src/config/vite.main.config.ts similarity index 54% rename from packages/template/vite/tmpl/vite.main.config.mjs rename to packages/plugin/vite/src/config/vite.main.config.ts index aa16d6e5e3..073c6c76ec 100644 --- a/packages/template/vite/tmpl/vite.main.config.mjs +++ b/packages/plugin/vite/src/config/vite.main.config.ts @@ -1,21 +1,15 @@ -import { defineConfig, mergeConfig } from 'vite'; -import { - getBuildConfig, - getBuildDefine, - external, - pluginHotRestart, -} from './vite.base.config.mjs'; +// eslint-disable-next-line node/no-unpublished-import +import { type ConfigEnv, mergeConfig, type UserConfig } from 'vite'; -// https://vitejs.dev/config -export default defineConfig((env) => { - /** @type {import('vite').ConfigEnv<'build'>} */ - const forgeEnv = env; +import { external, getBuildConfig, getBuildDefine, pluginHotRestart } from './vite.base.config'; + +export function getConfig(forgeEnv: ConfigEnv<'build'>): UserConfig { const { forgeConfigSelf } = forgeEnv; const define = getBuildDefine(forgeEnv); - const config = { + const config: UserConfig = { build: { lib: { - entry: forgeConfigSelf.entry, + entry: forgeConfigSelf.entry!, fileName: () => '[name].js', formats: ['cjs'], }, @@ -27,9 +21,10 @@ export default defineConfig((env) => { define, resolve: { // Load the Node.js entry. + conditions: ['node'], mainFields: ['module', 'jsnext:main', 'jsnext'], }, }; return mergeConfig(getBuildConfig(forgeEnv), config); -}); +} diff --git a/packages/template/vite/tmpl/vite.preload.config.mjs b/packages/plugin/vite/src/config/vite.preload.config.ts similarity index 60% rename from packages/template/vite/tmpl/vite.preload.config.mjs rename to packages/plugin/vite/src/config/vite.preload.config.ts index 40314c34d7..3629d4a8f7 100644 --- a/packages/template/vite/tmpl/vite.preload.config.mjs +++ b/packages/plugin/vite/src/config/vite.preload.config.ts @@ -1,22 +1,16 @@ -import { defineConfig, mergeConfig } from 'vite'; -import { - getBuildConfig, - external, - pluginHotRestart, -} from './vite.base.config.mjs'; +// eslint-disable-next-line node/no-unpublished-import +import { type ConfigEnv, mergeConfig, type UserConfig } from 'vite'; -// https://vitejs.dev/config -export default defineConfig((env) => { - /** @type {import('vite').ConfigEnv<'build'>} */ - const forgeEnv = env; +import { external, getBuildConfig, pluginHotRestart } from './vite.base.config'; + +export function getConfig(forgeEnv: ConfigEnv<'build'>): UserConfig { const { forgeConfigSelf } = forgeEnv; - /** @type {import('vite').UserConfig} */ - const config = { + const config: UserConfig = { build: { rollupOptions: { external, // Preload scripts may contain Web assets, so use the `build.rollupOptions.input` instead `build.lib.entry`. - input: forgeConfigSelf.entry, + input: forgeConfigSelf.entry!, output: { format: 'cjs', // It should not be split chunks. @@ -31,4 +25,4 @@ export default defineConfig((env) => { }; return mergeConfig(getBuildConfig(forgeEnv), config); -}); +} diff --git a/packages/template/vite/tmpl/vite.renderer.config.mjs b/packages/plugin/vite/src/config/vite.renderer.config.ts similarity index 56% rename from packages/template/vite/tmpl/vite.renderer.config.mjs rename to packages/plugin/vite/src/config/vite.renderer.config.ts index 34e8b6b3d3..e8d0f994ac 100644 --- a/packages/template/vite/tmpl/vite.renderer.config.mjs +++ b/packages/plugin/vite/src/config/vite.renderer.config.ts @@ -1,14 +1,13 @@ -import { defineConfig } from 'vite'; -import { pluginExposeRenderer } from './vite.base.config.mjs'; +// eslint-disable-next-line node/no-unpublished-import +import { type ConfigEnv, type UserConfig } from 'vite'; + +import { pluginExposeRenderer } from './vite.base.config'; // https://vitejs.dev/config -export default defineConfig((env) => { - /** @type {import('vite').ConfigEnv<'renderer'>} */ - const forgeEnv = env; +export function getConfig(forgeEnv: ConfigEnv<'renderer'>) { const { root, mode, forgeConfigSelf } = forgeEnv; const name = forgeConfigSelf.name ?? ''; - /** @type {import('vite').UserConfig} */ return { root, mode, @@ -21,5 +20,5 @@ export default defineConfig((env) => { preserveSymlinks: true, }, clearScreen: false, - }; -}); + } as UserConfig; +} diff --git a/packages/template/vite-typescript/tmpl/forge.config.ts b/packages/template/vite-typescript/tmpl/forge.config.ts index 1ab9f7e906..42181d2f2d 100644 --- a/packages/template/vite-typescript/tmpl/forge.config.ts +++ b/packages/template/vite-typescript/tmpl/forge.config.ts @@ -22,10 +22,12 @@ const config: ForgeConfig = { // `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`. entry: 'src/main.ts', config: 'vite.main.config.ts', + target: 'main', }, { entry: 'src/preload.ts', config: 'vite.preload.config.ts', + target: 'preload', }, ], renderer: [ diff --git a/packages/template/vite-typescript/tmpl/forge.env.d.ts b/packages/template/vite-typescript/tmpl/forge.env.d.ts index 8cbf19d3c4..9700e0ae19 100644 --- a/packages/template/vite-typescript/tmpl/forge.env.d.ts +++ b/packages/template/vite-typescript/tmpl/forge.env.d.ts @@ -1,31 +1 @@ -export {}; // Make this a module - -declare global { - // This allows TypeScript to pick up the magic constants that's auto-generated by Forge's Vite - // plugin that tells the Electron app where to look for the Vite-bundled app code (depending on - // whether you're running in development or production). - const MAIN_WINDOW_VITE_DEV_SERVER_URL: string; - const MAIN_WINDOW_VITE_NAME: string; - - namespace NodeJS { - interface Process { - // Used for hot reload after preload scripts. - viteDevServers: Record; - } - } - - type VitePluginConfig = ConstructorParameters[0]; - - interface VitePluginRuntimeKeys { - VITE_DEV_SERVER_URL: `${string}_VITE_DEV_SERVER_URL`; - VITE_NAME: `${string}_VITE_NAME`; - } -} - -declare module 'vite' { - interface ConfigEnv { - root: string; - forgeConfig: VitePluginConfig; - forgeConfigSelf: VitePluginConfig[K][number]; - } -} +/// diff --git a/packages/template/vite-typescript/tmpl/vite.main.config.ts b/packages/template/vite-typescript/tmpl/vite.main.config.ts index a4b3769d86..690be5b1a9 100644 --- a/packages/template/vite-typescript/tmpl/vite.main.config.ts +++ b/packages/template/vite-typescript/tmpl/vite.main.config.ts @@ -1,30 +1,4 @@ -import type { ConfigEnv, UserConfig } from 'vite'; -import { defineConfig, mergeConfig } from 'vite'; -import { getBuildConfig, getBuildDefine, external, pluginHotRestart } from './vite.base.config'; +import { defineConfig } from 'vite'; // https://vitejs.dev/config -export default defineConfig((env) => { - const forgeEnv = env as ConfigEnv<'build'>; - const { forgeConfigSelf } = forgeEnv; - const define = getBuildDefine(forgeEnv); - const config: UserConfig = { - build: { - lib: { - entry: forgeConfigSelf.entry!, - fileName: () => '[name].js', - formats: ['cjs'], - }, - rollupOptions: { - external, - }, - }, - plugins: [pluginHotRestart('restart')], - define, - resolve: { - // Load the Node.js entry. - mainFields: ['module', 'jsnext:main', 'jsnext'], - }, - }; - - return mergeConfig(getBuildConfig(forgeEnv), config); -}); +export default defineConfig({}); diff --git a/packages/template/vite-typescript/tmpl/vite.preload.config.ts b/packages/template/vite-typescript/tmpl/vite.preload.config.ts index 3cbadf6f59..690be5b1a9 100644 --- a/packages/template/vite-typescript/tmpl/vite.preload.config.ts +++ b/packages/template/vite-typescript/tmpl/vite.preload.config.ts @@ -1,29 +1,4 @@ -import type { ConfigEnv, UserConfig } from 'vite'; -import { defineConfig, mergeConfig } from 'vite'; -import { getBuildConfig, external, pluginHotRestart } from './vite.base.config'; +import { defineConfig } from 'vite'; // https://vitejs.dev/config -export default defineConfig((env) => { - const forgeEnv = env as ConfigEnv<'build'>; - const { forgeConfigSelf } = forgeEnv; - const config: UserConfig = { - build: { - rollupOptions: { - external, - // Preload scripts may contain Web assets, so use the `build.rollupOptions.input` instead `build.lib.entry`. - input: forgeConfigSelf.entry!, - output: { - format: 'cjs', - // It should not be split chunks. - inlineDynamicImports: true, - entryFileNames: '[name].js', - chunkFileNames: '[name].js', - assetFileNames: '[name].[ext]', - }, - }, - }, - plugins: [pluginHotRestart('reload')], - }; - - return mergeConfig(getBuildConfig(forgeEnv), config); -}); +export default defineConfig({}); diff --git a/packages/template/vite-typescript/tmpl/vite.renderer.config.ts b/packages/template/vite-typescript/tmpl/vite.renderer.config.ts index e821a3bb6d..690be5b1a9 100644 --- a/packages/template/vite-typescript/tmpl/vite.renderer.config.ts +++ b/packages/template/vite-typescript/tmpl/vite.renderer.config.ts @@ -1,24 +1,4 @@ -import type { ConfigEnv, UserConfig } from 'vite'; import { defineConfig } from 'vite'; -import { pluginExposeRenderer } from './vite.base.config'; // https://vitejs.dev/config -export default defineConfig((env) => { - const forgeEnv = env as ConfigEnv<'renderer'>; - const { root, mode, forgeConfigSelf } = forgeEnv; - const name = forgeConfigSelf.name ?? ''; - - return { - root, - mode, - base: './', - build: { - outDir: `.vite/renderer/${name}`, - }, - plugins: [pluginExposeRenderer(name)], - resolve: { - preserveSymlinks: true, - }, - clearScreen: false, - } as UserConfig; -}); +export default defineConfig({}); diff --git a/packages/template/vite/src/ViteTemplate.ts b/packages/template/vite/src/ViteTemplate.ts index bed574da2f..5a92ab7f2c 100644 --- a/packages/template/vite/src/ViteTemplate.ts +++ b/packages/template/vite/src/ViteTemplate.ts @@ -15,17 +15,15 @@ class ViteTemplate extends BaseTemplate { title: 'Setting up Forge configuration', task: async () => { await this.copyTemplateFile(directory, 'forge.config.js'); - await this.copyTemplateFile(directory, 'forge.env.d.txt'); - await fs.rename(path.join(directory, 'forge.env.d.txt'), path.join(directory, 'forge.env.d.ts')); + await this.copyTemplateFile(directory, 'forge.env.d.ts'); }, }, { title: 'Setting up Vite configuration', task: async () => { - await this.copyTemplateFile(directory, 'vite.base.config.mjs'); - await this.copyTemplateFile(directory, 'vite.main.config.mjs'); - await this.copyTemplateFile(directory, 'vite.preload.config.mjs'); - await this.copyTemplateFile(directory, 'vite.renderer.config.mjs'); + await this.copyTemplateFile(directory, 'vite.main.config.js'); + await this.copyTemplateFile(directory, 'vite.preload.config.js'); + await this.copyTemplateFile(directory, 'vite.renderer.config.js'); await this.copyTemplateFile(path.join(directory, 'src'), 'renderer.js'); await this.copyTemplateFile(path.join(directory, 'src'), 'preload.js'); diff --git a/packages/template/vite/test/ViteTemplate_spec.ts b/packages/template/vite/test/ViteTemplate_spec.ts index 259fe61589..34bc50e1d2 100644 --- a/packages/template/vite/test/ViteTemplate_spec.ts +++ b/packages/template/vite/test/ViteTemplate_spec.ts @@ -30,10 +30,9 @@ describe('ViteTemplate', () => { 'package.json', 'forge.env.d.ts', 'forge.config.js', - 'vite.base.config.mjs', - 'vite.main.config.mjs', - 'vite.preload.config.mjs', - 'vite.renderer.config.mjs', + 'vite.main.config.js', + 'vite.preload.config.js', + 'vite.renderer.config.js', path.join('src', 'renderer.js'), path.join('src', 'preload.js'), ]; diff --git a/packages/template/vite/tmpl/forge.config.js b/packages/template/vite/tmpl/forge.config.js index 45572b88fe..94a6e7d35b 100644 --- a/packages/template/vite/tmpl/forge.config.js +++ b/packages/template/vite/tmpl/forge.config.js @@ -34,17 +34,19 @@ module.exports = { { // `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`. entry: 'src/main.js', - config: 'vite.main.config.mjs', + config: 'vite.main.config.js', + target: 'main', }, { entry: 'src/preload.js', - config: 'vite.preload.config.mjs', + config: 'vite.preload.config.js', + target: 'preload', }, ], renderer: [ { name: 'main_window', - config: 'vite.renderer.config.mjs', + config: 'vite.renderer.config.js', }, ], }, diff --git a/packages/template/vite/tmpl/forge.env.d.ts b/packages/template/vite/tmpl/forge.env.d.ts new file mode 100644 index 0000000000..9700e0ae19 --- /dev/null +++ b/packages/template/vite/tmpl/forge.env.d.ts @@ -0,0 +1 @@ +/// diff --git a/packages/template/vite/tmpl/vite.base.config.mjs b/packages/template/vite/tmpl/vite.base.config.mjs deleted file mode 100644 index 6f9b0c52f4..0000000000 --- a/packages/template/vite/tmpl/vite.base.config.mjs +++ /dev/null @@ -1,109 +0,0 @@ -import { builtinModules } from 'node:module'; -import pkg from './package.json'; - -export const builtins = [ - 'electron', - ...builtinModules.map((m) => [m, `node:${m}`]).flat(), -]; - -export const external = [...builtins, ...Object.keys(pkg.dependencies || {})]; - -/** @type {(env: import('vite').ConfigEnv<'build'>) => import('vite').UserConfig} */ -export const getBuildConfig = (env) => { - const { root, mode, command } = env; - - return { - root, - mode, - build: { - // Prevent multiple builds from interfering with each other. - emptyOutDir: false, - // 🚧 Multiple builds may conflict. - outDir: '.vite/build', - watch: command === 'serve' ? {} : null, - minify: command === 'build', - }, - clearScreen: false, - }; -}; - -/** @type {(names: string[]) => { [name: string]: VitePluginRuntimeKeys } }} */ -export const getDefineKeys = (names) => { - /** @type {{ [name: string]: VitePluginRuntimeKeys }} */ - const define = {}; - - return names.reduce((acc, name) => { - const NAME = name.toUpperCase(); - /** @type {VitePluginRuntimeKeys} */ - const keys = { - VITE_DEV_SERVER_URL: `${NAME}_VITE_DEV_SERVER_URL`, - VITE_NAME: `${NAME}_VITE_NAME`, - }; - - return { ...acc, [name]: keys }; - }, define); -}; - -/** @type {(env: import('vite').ConfigEnv<'build'>) => Record} */ -export const getBuildDefine = (env) => { - const { command, forgeConfig } = env; - const names = forgeConfig.renderer - .filter(({ name }) => name != null) - .map(({ name }) => name); - const defineKeys = getDefineKeys(names); - const define = Object.entries(defineKeys).reduce((acc, [name, keys]) => { - const { VITE_DEV_SERVER_URL, VITE_NAME } = keys; - const def = { - [VITE_DEV_SERVER_URL]: - command === 'serve' - ? JSON.stringify(process.env[VITE_DEV_SERVER_URL]) - : undefined, - [VITE_NAME]: JSON.stringify(name), - }; - return { ...acc, ...def }; - }, {}); - - return define; -}; - -/** @type {(name: string) => import('vite').Plugin} */ -export const pluginExposeRenderer = (name) => { - const { VITE_DEV_SERVER_URL } = getDefineKeys([name])[name]; - - return { - name: '@electron-forge/plugin-vite:expose-renderer', - configureServer(server) { - process.viteDevServers ??= {}; - // Expose server for preload scripts hot reload. - process.viteDevServers[name] = server; - - server.httpServer?.once('listening', () => { - /** @type {import('node:net').AddressInfo} */ - const addressInfo = server.httpServer?.address(); - // Expose env constant for main process use. - process.env[ - VITE_DEV_SERVER_URL - ] = `http://localhost:${addressInfo?.port}`; - }); - }, - }; -}; - -/** @type {(command: 'reload' | 'restart') => import('vite').Plugin} */ -export const pluginHotRestart = (command) => { - return { - name: '@electron-forge/plugin-vite:hot-restart', - closeBundle() { - if (command === 'reload') { - for (const server of Object.values(process.viteDevServers)) { - // Preload scripts hot reload. - server.ws.send({ type: 'full-reload' }); - } - } else { - // Main process hot restart. - // https://github.com/electron/forge/blob/v7.2.0/packages/api/core/src/api/start.ts#L216-L223 - process.stdin.emit('data', 'rs'); - } - }, - }; -}; diff --git a/packages/template/vite/tmpl/vite.main.config.js b/packages/template/vite/tmpl/vite.main.config.js new file mode 100644 index 0000000000..690be5b1a9 --- /dev/null +++ b/packages/template/vite/tmpl/vite.main.config.js @@ -0,0 +1,4 @@ +import { defineConfig } from 'vite'; + +// https://vitejs.dev/config +export default defineConfig({}); diff --git a/packages/template/vite/tmpl/vite.preload.config.js b/packages/template/vite/tmpl/vite.preload.config.js new file mode 100644 index 0000000000..690be5b1a9 --- /dev/null +++ b/packages/template/vite/tmpl/vite.preload.config.js @@ -0,0 +1,4 @@ +import { defineConfig } from 'vite'; + +// https://vitejs.dev/config +export default defineConfig({}); diff --git a/packages/template/vite/tmpl/vite.renderer.config.js b/packages/template/vite/tmpl/vite.renderer.config.js new file mode 100644 index 0000000000..690be5b1a9 --- /dev/null +++ b/packages/template/vite/tmpl/vite.renderer.config.js @@ -0,0 +1,4 @@ +import { defineConfig } from 'vite'; + +// https://vitejs.dev/config +export default defineConfig({}); From c7013364a1c06ffa3a28322f52c43e1e5cdc2b6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Wang=28=E8=8D=89=E9=9E=8B=E6=B2=A1=E5=8F=B7=29?= <308487730@qq.com> Date: Tue, 30 Apr 2024 12:28:38 +0800 Subject: [PATCH 03/12] feat(plugin-vite): load built in vite config --- packages/plugin/vite/src/Config.ts | 5 ++++ packages/plugin/vite/src/ViteConfig.ts | 36 +++++++++++++++++--------- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/packages/plugin/vite/src/Config.ts b/packages/plugin/vite/src/Config.ts index bf20f6386a..0665a49444 100644 --- a/packages/plugin/vite/src/Config.ts +++ b/packages/plugin/vite/src/Config.ts @@ -10,6 +10,11 @@ export interface VitePluginBuildConfig { * Vite config file path. */ config: string; + /** + * The build target is main process or preload script. + * @defaultValue 'main' + */ + target?: 'main' | 'preload'; } export interface VitePluginRendererConfig { diff --git a/packages/plugin/vite/src/ViteConfig.ts b/packages/plugin/vite/src/ViteConfig.ts index b91d8abb9e..c3d2cef378 100644 --- a/packages/plugin/vite/src/ViteConfig.ts +++ b/packages/plugin/vite/src/ViteConfig.ts @@ -1,6 +1,10 @@ import debug from 'debug'; // eslint-disable-next-line node/no-unpublished-import -import { loadConfigFromFile } from 'vite'; +import { loadConfigFromFile, mergeConfig } from 'vite'; + +import { getConfig as getMainViteConfig } from './config/vite.main.config'; +import { getConfig as getPreloadViteConfig } from './config/vite.preload.config'; +import { getConfig as getRendererViteConfig } from './config/vite.renderer.config'; import type { VitePluginBuildConfig, VitePluginConfig, VitePluginRendererConfig } from './Config'; // eslint-disable-next-line node/no-unpublished-import @@ -13,21 +17,28 @@ export default class ViteConfigGenerator { d('Config mode:', this.mode); } - resolveConfig(buildConfig: VitePluginBuildConfig | VitePluginRendererConfig, configEnv: Partial = {}) { - // @see - https://vitejs.dev/config/#conditional-config - configEnv.command ??= this.isProd ? 'build' : 'serve'; - // `mode` affects `.env.[mode]` file load. - configEnv.mode ??= this.mode; + async resolveConfig(buildConfig: VitePluginBuildConfig | VitePluginRendererConfig, target?: VitePluginBuildConfig['target']) { + const configEnv: ConfigEnv = { + // @see - https://vitejs.dev/config/#conditional-config + command: this.isProd ? 'build' : 'serve', + // `mode` affects `.env.[mode]` file load. + mode: this.mode, - // Hack! Pass the forge runtime config to the vite config file in the template. - Object.assign(configEnv, { + // Forge extension variables. root: this.projectDir, forgeConfig: this.pluginConfig, forgeConfigSelf: buildConfig, - }); + }; // `configEnv` is to be passed as an arguments when the user export a function in `vite.config.js`. - return loadConfigFromFile(configEnv as ConfigEnv, buildConfig.config); + const userConfig = (await loadConfigFromFile(configEnv as ConfigEnv, buildConfig.config))?.config ?? {}; + if (target === 'main') { + return mergeConfig(getMainViteConfig(configEnv as ConfigEnv<'build'>), userConfig); + } + if (target === 'preload') { + return mergeConfig(getPreloadViteConfig(configEnv as ConfigEnv<'build'>), userConfig); + } + return mergeConfig(getRendererViteConfig(configEnv as ConfigEnv<'renderer'>), userConfig); } get mode(): string { @@ -45,7 +56,7 @@ export default class ViteConfigGenerator { const configs = this.pluginConfig.build // Prevent load the default `vite.config.js` file. .filter(({ config }) => config) - .map>(async (buildConfig) => (await this.resolveConfig(buildConfig))?.config ?? {}); + .map>((buildConfig) => this.resolveConfig(buildConfig, buildConfig.target ?? 'main')); return await Promise.all(configs); } @@ -56,8 +67,9 @@ export default class ViteConfigGenerator { } const configs = this.pluginConfig.renderer + // Prevent load the default `vite.config.js` file. .filter(({ config }) => config) - .map>(async (buildConfig) => (await this.resolveConfig(buildConfig))?.config ?? {}); + .map>((buildConfig) => this.resolveConfig(buildConfig)); return await Promise.all(configs); } From 182fa3f8549dbea0385a7651544e689841ffea70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Wang=28=E8=8D=89=E9=9E=8B=E6=B2=A1=E5=8F=B7=29?= <308487730@qq.com> Date: Tue, 30 Apr 2024 13:18:41 +0800 Subject: [PATCH 04/12] fix(plugin-vite): return `undefined` avoid `packagerConfig.ignore` logic BUG --- packages/plugin/vite/src/VitePlugin.ts | 35 ++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/packages/plugin/vite/src/VitePlugin.ts b/packages/plugin/vite/src/VitePlugin.ts index 523542acb5..496d88b0fb 100644 --- a/packages/plugin/vite/src/VitePlugin.ts +++ b/packages/plugin/vite/src/VitePlugin.ts @@ -93,20 +93,45 @@ Your packaged app may be larger than expected if you dont ignore everything othe } const flatDeps = await getFlatDependencies(this.projectDir); + const names = flatDeps.map((dep) => dep.name); forgeConfig.packagerConfig.ignore = (file: string) => { if (!file) return false; // `file` always starts with `/` // @see - https://github.com/electron/packager/blob/v18.1.3/src/copy-filter.ts#L89-L93 - // Collect dependencies from package.json + // Collect dependencies from package.json by default if (file.startsWith('/node_modules')) { - const [, , name] = file.split('/'); - return flatDeps.some((dep) => dep.name === name); + const [, , orgOrName, sub] = file.split('/'); + + if (orgOrName) { + if (orgOrName.startsWith('@')) { + if (sub) { + // /node_modules/@org/name + const name = `${orgOrName}/${sub}`; + + if (names.includes(name)) return false; + } else { + // /node_modules/@org + return names.some((name) => name.startsWith(orgOrName)) ? false : true; + } + } else { + const name = orgOrName; + + if (names.includes(name)) return false; + + // .bin, .vite, .yarn-integrity etc + // TODO: Something must be explicitly filtered out here, prehaps this a BUG of `ignore` + if (name.startsWith('.')) return true; + } + } + } else { + // Collect the files built by Vite + return !file.startsWith('/.vite'); } - // Collect the files built by Vite - return !file.startsWith('/.vite'); + // TODO: return false behavior diff than reutrn undefined, prehaps this a BUG of `ignore` + return undefined as unknown as boolean; }; return forgeConfig; }; From bb9ee5591831d9e206f7de88c541b3a913ce8c3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Wang=28=E8=8D=89=E9=9E=8B=E6=B2=A1=E5=8F=B7=29?= <308487730@qq.com> Date: Fri, 3 May 2024 08:40:32 +0800 Subject: [PATCH 05/12] chore(plugin-vite): remove `process` reference --- packages/plugin/vite/forge-vite-env.d.ts | 7 ------- .../plugin/vite/src/config/vite.base.config.ts | 17 ++++++++++------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/packages/plugin/vite/forge-vite-env.d.ts b/packages/plugin/vite/forge-vite-env.d.ts index 8cbf19d3c4..0a1b24ebf0 100644 --- a/packages/plugin/vite/forge-vite-env.d.ts +++ b/packages/plugin/vite/forge-vite-env.d.ts @@ -7,13 +7,6 @@ declare global { const MAIN_WINDOW_VITE_DEV_SERVER_URL: string; const MAIN_WINDOW_VITE_NAME: string; - namespace NodeJS { - interface Process { - // Used for hot reload after preload scripts. - viteDevServers: Record; - } - } - type VitePluginConfig = ConstructorParameters[0]; interface VitePluginRuntimeKeys { diff --git a/packages/plugin/vite/src/config/vite.base.config.ts b/packages/plugin/vite/src/config/vite.base.config.ts index ee81f5a870..c480a106f6 100644 --- a/packages/plugin/vite/src/config/vite.base.config.ts +++ b/packages/plugin/vite/src/config/vite.base.config.ts @@ -2,12 +2,16 @@ import { builtinModules } from 'node:module'; import type { AddressInfo } from 'node:net'; // eslint-disable-next-line node/no-unpublished-import -import type { ConfigEnv, Plugin, UserConfig } from 'vite'; +import type { ConfigEnv, Plugin, UserConfig, ViteDevServer } from 'vite'; export const builtins = ['electron', ...builtinModules.map((m) => [m, `node:${m}`]).flat()]; export const external = [...builtins]; +// Used for hot reload after preload scripts. +const viteDevServers: Record = {}; +const viteDevServerUrls: Record = {}; + export function getBuildConfig(env: ConfigEnv<'build'>): UserConfig { const { root, mode, command } = env; @@ -47,7 +51,7 @@ export function getBuildDefine(env: ConfigEnv<'build'>) { const define = Object.entries(defineKeys).reduce((acc, [name, keys]) => { const { VITE_DEV_SERVER_URL, VITE_NAME } = keys; const def = { - [VITE_DEV_SERVER_URL]: command === 'serve' ? JSON.stringify(process.env[VITE_DEV_SERVER_URL]) : undefined, + [VITE_DEV_SERVER_URL]: command === 'serve' ? JSON.stringify(viteDevServerUrls[VITE_DEV_SERVER_URL]) : undefined, [VITE_NAME]: JSON.stringify(name), }; return { ...acc, ...def }; @@ -62,14 +66,13 @@ export function pluginExposeRenderer(name: string): Plugin { return { name: '@electron-forge/plugin-vite:expose-renderer', configureServer(server) { - process.viteDevServers ??= {}; // Expose server for preload scripts hot reload. - process.viteDevServers[name] = server; + viteDevServers[name] = server; server.httpServer?.once('listening', () => { const addressInfo = server.httpServer?.address() as AddressInfo; // Expose env constant for main process use. - process.env[VITE_DEV_SERVER_URL] = `http://localhost:${addressInfo?.port}`; + viteDevServerUrls[VITE_DEV_SERVER_URL] = `http://localhost:${addressInfo?.port}`; }); }, }; @@ -80,11 +83,11 @@ export function pluginHotRestart(command: 'reload' | 'restart'): Plugin { name: '@electron-forge/plugin-vite:hot-restart', closeBundle() { if (command === 'reload') { - for (const server of Object.values(process.viteDevServers)) { + for (const server of Object.values(viteDevServers)) { // Preload scripts hot reload. server.ws.send({ type: 'full-reload' }); } - } else { + } else if (command === 'restart') { // Main process hot restart. // https://github.com/electron/forge/blob/v7.2.0/packages/api/core/src/api/start.ts#L216-L223 // TODO: blocked in #3380 From 1bae6ab81db482308604a67fca3b6c007bd439a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Wang=28=E8=8D=89=E9=9E=8B=E6=B2=A1=E5=8F=B7=29?= <308487730@qq.com> Date: Sat, 4 May 2024 08:14:34 +0800 Subject: [PATCH 06/12] feat(plugin-vite): remove copy `dependencies` to built App --- packages/plugin/vite/src/VitePlugin.ts | 37 ++---------------------- packages/plugin/vite/src/util/package.ts | 8 ----- 2 files changed, 2 insertions(+), 43 deletions(-) delete mode 100644 packages/plugin/vite/src/util/package.ts diff --git a/packages/plugin/vite/src/VitePlugin.ts b/packages/plugin/vite/src/VitePlugin.ts index 496d88b0fb..6a6f8a7eee 100644 --- a/packages/plugin/vite/src/VitePlugin.ts +++ b/packages/plugin/vite/src/VitePlugin.ts @@ -8,7 +8,6 @@ import { PRESET_TIMER } from 'listr2'; // eslint-disable-next-line node/no-unpublished-import import { default as vite } from 'vite'; -import { getFlatDependencies } from './util/package'; import { onBuildDone } from './util/plugins'; import ViteConfigGenerator from './ViteConfig'; @@ -92,46 +91,14 @@ Your packaged app may be larger than expected if you dont ignore everything othe return forgeConfig; } - const flatDeps = await getFlatDependencies(this.projectDir); - const names = flatDeps.map((dep) => dep.name); forgeConfig.packagerConfig.ignore = (file: string) => { if (!file) return false; // `file` always starts with `/` // @see - https://github.com/electron/packager/blob/v18.1.3/src/copy-filter.ts#L89-L93 - // Collect dependencies from package.json by default - if (file.startsWith('/node_modules')) { - const [, , orgOrName, sub] = file.split('/'); - - if (orgOrName) { - if (orgOrName.startsWith('@')) { - if (sub) { - // /node_modules/@org/name - const name = `${orgOrName}/${sub}`; - - if (names.includes(name)) return false; - } else { - // /node_modules/@org - return names.some((name) => name.startsWith(orgOrName)) ? false : true; - } - } else { - const name = orgOrName; - - if (names.includes(name)) return false; - - // .bin, .vite, .yarn-integrity etc - // TODO: Something must be explicitly filtered out here, prehaps this a BUG of `ignore` - if (name.startsWith('.')) return true; - } - } - } else { - // Collect the files built by Vite - return !file.startsWith('/.vite'); - } - - // TODO: return false behavior diff than reutrn undefined, prehaps this a BUG of `ignore` - return undefined as unknown as boolean; + // Collect the files built by Vite + return !file.startsWith('/.vite'); }; return forgeConfig; }; diff --git a/packages/plugin/vite/src/util/package.ts b/packages/plugin/vite/src/util/package.ts deleted file mode 100644 index 3d1d358f42..0000000000 --- a/packages/plugin/vite/src/util/package.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { DepType, Walker } from 'flora-colossus'; - -export async function getFlatDependencies(root: string) { - const walker = new Walker(root); - const deps = await walker.walkTree(); - - return deps.filter((dep) => dep.depType === DepType.PROD); -} From 75815ac02e42bed16ab86ac15c70cfdbd9ac5858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Wang=28=E8=8D=89=E9=9E=8B=E6=B2=A1=E5=8F=B7=29?= <308487730@qq.com> Date: Fri, 28 Jun 2024 15:32:38 +0800 Subject: [PATCH 07/12] chore(plugin-vite): update config --- packages/plugin/vite/test/ViteConfig_spec.ts | 123 ++++++++++++------ .../test/fixture/config/vite.main.config.mjs | 31 ----- .../fixture/config/vite.renderer.config.mjs | 11 -- .../vite/test/fixture/package/package.json | 7 - .../test/{fixture => fixtures}/.gitignore | 0 .../fixtures/vite-configs/vite.main.config.js | 2 + .../vite-configs/vite.preload.config.js | 2 + .../vite-configs/vite.renderer.config.js | 2 + .../plugin/vite/test/util/package_spec.ts | 22 ---- 9 files changed, 86 insertions(+), 114 deletions(-) delete mode 100644 packages/plugin/vite/test/fixture/config/vite.main.config.mjs delete mode 100644 packages/plugin/vite/test/fixture/config/vite.renderer.config.mjs delete mode 100644 packages/plugin/vite/test/fixture/package/package.json rename packages/plugin/vite/test/{fixture => fixtures}/.gitignore (100%) create mode 100644 packages/plugin/vite/test/fixtures/vite-configs/vite.main.config.js create mode 100644 packages/plugin/vite/test/fixtures/vite-configs/vite.preload.config.js create mode 100644 packages/plugin/vite/test/fixtures/vite-configs/vite.renderer.config.js delete mode 100644 packages/plugin/vite/test/util/package_spec.ts diff --git a/packages/plugin/vite/test/ViteConfig_spec.ts b/packages/plugin/vite/test/ViteConfig_spec.ts index 9ee0c4f3ab..951b081bf7 100644 --- a/packages/plugin/vite/test/ViteConfig_spec.ts +++ b/packages/plugin/vite/test/ViteConfig_spec.ts @@ -1,64 +1,101 @@ -import { builtinModules } from 'node:module'; import path from 'node:path'; import { expect } from 'chai'; +import { external } from '../src/config/vite.base.config'; import ViteConfigGenerator from '../src/ViteConfig'; import type { VitePluginConfig } from '../src/Config'; -import type { UserConfig } from 'vite'; +import type { Plugin } from 'vite'; -const builtins = ['electron', ...builtinModules.map((m) => [m, `node:${m}`]).flat()]; -const configRoot = path.join(__dirname, 'fixture/config'); +const configRoot = path.join(__dirname, 'fixtures/vite-configs'); describe('ViteConfigGenerator', () => { - it('getBuildConfig', async () => { - const config = { - build: [{ config: path.join(configRoot, 'vite.main.config.mjs') }], - renderer: [], - } as VitePluginConfig; - const generator = new ViteConfigGenerator(config, configRoot, true); - const buildConfig1 = (await generator.getBuildConfig())[0]; - const buildConfig2: UserConfig = { - root: configRoot, - mode: 'production', - build: { - lib: { + it('getBuildConfig:main', async () => { + const forgeConfig: VitePluginConfig = { + build: [ + { entry: 'src/main.js', - formats: ['cjs'], - // shims - fileName: (buildConfig1.build?.lib as any)?.fileName, - }, - emptyOutDir: false, - outDir: '.vite/build', - minify: true, // this.isProd === true - watch: null, - rollupOptions: { - external: builtins, + config: path.join(configRoot, 'vite.main.config.js'), + target: 'main', }, - }, - clearScreen: false, + ], + renderer: [], }; + const generator = new ViteConfigGenerator(forgeConfig, configRoot, true); + const buildConfig = (await generator.getBuildConfig())[0]; - expect(buildConfig1).deep.equal(buildConfig2); + expect(buildConfig.root).equal(configRoot); + expect(buildConfig.mode).equal('production'); + expect(buildConfig.build?.emptyOutDir).false; + expect(buildConfig.build?.outDir).equal('.vite/build'); + expect(buildConfig.build?.watch).null; + expect(buildConfig.build?.minify).true; + expect(buildConfig.build?.lib && buildConfig.build.lib.entry).equal('src/main.js'); + expect(buildConfig.build?.lib && (buildConfig.build.lib.fileName as () => string)()).equal('[name].js'); + expect(buildConfig.build?.lib && buildConfig.build.lib.formats).deep.equal(['cjs']); + expect(buildConfig.build?.rollupOptions?.external).deep.equal(external); + expect(buildConfig.clearScreen).false; + expect(buildConfig.plugins?.map((plugin) => (plugin as Plugin).name)).deep.equal(['@electron-forge/plugin-vite:hot-restart']); + expect(buildConfig.define).deep.equal({}); + expect(buildConfig.resolve).deep.equal({ + conditions: ['node'], + mainFields: ['module', 'jsnext:main', 'jsnext'], + }); }); - it('getRendererConfig', async () => { - const config = { - build: [{ config: path.join(configRoot, 'vite.renderer.config.mjs') }], + it('getBuildConfig:preload', async () => { + const forgeConfig: VitePluginConfig = { + build: [ + { + entry: 'src/preload.js', + config: path.join(configRoot, 'vite.preload.config.js'), + target: 'preload', + }, + ], renderer: [], - } as VitePluginConfig; - const generator = new ViteConfigGenerator(config, configRoot, true); - const buildConfig1 = (await generator.getBuildConfig())[0]; - const buildConfig2: UserConfig = { - root: configRoot, - mode: 'production', - base: './', - build: { - outDir: 'renderer/main_window', - }, }; + const generator = new ViteConfigGenerator(forgeConfig, configRoot, true); + const buildConfig = (await generator.getBuildConfig())[0]; + + expect(buildConfig.root).equal(configRoot); + expect(buildConfig.mode).equal('production'); + expect(buildConfig.build?.emptyOutDir).false; + expect(buildConfig.build?.outDir).equal('.vite/build'); + expect(buildConfig.build?.watch).null; + expect(buildConfig.build?.minify).true; + expect(buildConfig.build?.rollupOptions?.external).deep.equal(external); + expect(buildConfig.build?.rollupOptions?.input).equal('src/preload.js'); + expect(buildConfig.build?.rollupOptions?.output).deep.equal({ + format: 'cjs', + inlineDynamicImports: true, + entryFileNames: '[name].js', + chunkFileNames: '[name].js', + assetFileNames: '[name].[ext]', + }); + expect(buildConfig.clearScreen).false; + expect(buildConfig.plugins?.map((plugin) => (plugin as Plugin).name)).deep.equal(['@electron-forge/plugin-vite:hot-restart']); + }); + + it('getRendererConfig:renderer', async () => { + const forgeConfig = { + build: [], + renderer: [ + { + name: 'main_window', + config: path.join(configRoot, 'vite.renderer.config.js'), + }, + ], + }; + const generator = new ViteConfigGenerator(forgeConfig, configRoot, true); + const rendererConfig = (await generator.getRendererConfig())[0]; - expect(buildConfig1).deep.equal(buildConfig2); + expect(rendererConfig.root).equal(configRoot); + expect(rendererConfig.mode).equal('production'); + expect(rendererConfig.base).equal('./'); + expect(rendererConfig.build?.outDir).equal('.vite/renderer/main_window'); + expect(rendererConfig.plugins?.map((plugin) => (plugin as Plugin).name)).deep.equal(['@electron-forge/plugin-vite:expose-renderer']); + expect(rendererConfig.resolve).deep.equal({ preserveSymlinks: true }); + expect(rendererConfig.clearScreen).false; }); }); diff --git a/packages/plugin/vite/test/fixture/config/vite.main.config.mjs b/packages/plugin/vite/test/fixture/config/vite.main.config.mjs deleted file mode 100644 index ef5cff2d1a..0000000000 --- a/packages/plugin/vite/test/fixture/config/vite.main.config.mjs +++ /dev/null @@ -1,31 +0,0 @@ -import { builtinModules } from 'node:module'; - -// eslint-disable-next-line import/namespace -import { defineConfig } from 'vite'; - -const builtins = [ - 'electron', - ...builtinModules.map((m) => [m, `node:${m}`]).flat(), -]; - -export default defineConfig((env) => ({ - root: env.root, - mode: env.mode, - build: { - lib: { - entry: 'src/main.js', - fileName: () => '[name].js', - formats: ['cjs'], - }, - // Prevent multiple builds from interfering with each other. - emptyOutDir: false, - // 🚧 Multiple builds may conflict. - outDir: '.vite/build', - minify: env.command === 'build', - watch: env.command === 'serve' ? {} : null, - rollupOptions: { - external: builtins, - }, - }, - clearScreen: false, -})); diff --git a/packages/plugin/vite/test/fixture/config/vite.renderer.config.mjs b/packages/plugin/vite/test/fixture/config/vite.renderer.config.mjs deleted file mode 100644 index a7fcc5f5ba..0000000000 --- a/packages/plugin/vite/test/fixture/config/vite.renderer.config.mjs +++ /dev/null @@ -1,11 +0,0 @@ -// eslint-disable-next-line import/namespace -import { defineConfig } from 'vite'; - -export default defineConfig((env) => ({ - root: env.root, - mode: env.mode, - base: './', - build: { - outDir: 'renderer/main_window', - }, -})); diff --git a/packages/plugin/vite/test/fixture/package/package.json b/packages/plugin/vite/test/fixture/package/package.json deleted file mode 100644 index 5186d39673..0000000000 --- a/packages/plugin/vite/test/fixture/package/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "@electron-forge/plugin-vite-test-util-package", - "version": "0.1.0", - "dependencies": { - "electron-squirrel-startup": "^1.0.0" - } -} diff --git a/packages/plugin/vite/test/fixture/.gitignore b/packages/plugin/vite/test/fixtures/.gitignore similarity index 100% rename from packages/plugin/vite/test/fixture/.gitignore rename to packages/plugin/vite/test/fixtures/.gitignore diff --git a/packages/plugin/vite/test/fixtures/vite-configs/vite.main.config.js b/packages/plugin/vite/test/fixtures/vite-configs/vite.main.config.js new file mode 100644 index 0000000000..daf2fb4630 --- /dev/null +++ b/packages/plugin/vite/test/fixtures/vite-configs/vite.main.config.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +export default {}; diff --git a/packages/plugin/vite/test/fixtures/vite-configs/vite.preload.config.js b/packages/plugin/vite/test/fixtures/vite-configs/vite.preload.config.js new file mode 100644 index 0000000000..daf2fb4630 --- /dev/null +++ b/packages/plugin/vite/test/fixtures/vite-configs/vite.preload.config.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +export default {}; diff --git a/packages/plugin/vite/test/fixtures/vite-configs/vite.renderer.config.js b/packages/plugin/vite/test/fixtures/vite-configs/vite.renderer.config.js new file mode 100644 index 0000000000..daf2fb4630 --- /dev/null +++ b/packages/plugin/vite/test/fixtures/vite-configs/vite.renderer.config.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +export default {}; diff --git a/packages/plugin/vite/test/util/package_spec.ts b/packages/plugin/vite/test/util/package_spec.ts deleted file mode 100644 index 74bc75b1df..0000000000 --- a/packages/plugin/vite/test/util/package_spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { exec } from 'node:child_process'; -import path from 'node:path'; -import { promisify } from 'node:util'; - -import { expect } from 'chai'; - -import { getFlatDependencies } from '../../src/util/package'; - -const execPromise = promisify(exec); -const packageRoot = path.join(__dirname, '../fixture/package'); -const proDeps = ['electron-squirrel-startup', 'debug', 'ms']; - -describe('util/package', () => { - before(async () => { - await execPromise('npm install', { cwd: packageRoot }); - }); - - it('dependencies of package.json is resolved correct', async () => { - const flatDeps = await getFlatDependencies(packageRoot); - expect(proDeps).deep.equal(flatDeps.map((dep) => dep.name)); - }); -}); From da1ba8d01ea8c3087c60839f375cf83394cd842a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Wang=28=E8=8D=89=E9=9E=8B=E6=B2=A1=E5=8F=B7=29?= <308487730@qq.com> Date: Fri, 28 Jun 2024 18:02:26 +0800 Subject: [PATCH 08/12] chore(plugin-vite): test add `vite.base.config.ts` --- .../vite/test/config/vite.base.config_spec.ts | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 packages/plugin/vite/test/config/vite.base.config_spec.ts diff --git a/packages/plugin/vite/test/config/vite.base.config_spec.ts b/packages/plugin/vite/test/config/vite.base.config_spec.ts new file mode 100644 index 0000000000..6faaae5dda --- /dev/null +++ b/packages/plugin/vite/test/config/vite.base.config_spec.ts @@ -0,0 +1,96 @@ +import path from 'node:path'; + +import { expect } from 'chai'; +import { default as vite } from 'vite'; + +import { getBuildDefine, getDefineKeys, pluginExposeRenderer } from '../../src/config/vite.base.config'; + +import type { VitePluginConfig } from '../../src/Config'; + +const configRoot = path.join(__dirname, 'fixtures/vite-configs'); +const forgeConfig: VitePluginConfig = { + build: [ + { + entry: 'src/main.js', + config: path.join(configRoot, 'vite.main.config.js'), + target: 'main', + }, + { + entry: 'src/preload.js', + config: path.join(configRoot, 'vite.preload.config.js'), + target: 'preload', + }, + ], + renderer: [ + { + name: 'main_window', + config: path.join(configRoot, 'vite.renderer.config.js'), + }, + { + name: 'second_window', + config: path.join(configRoot, 'vite.renderer.config.js'), + }, + ], +}; + +describe('vite.base.config', () => { + it('getDefineKeys', () => { + const defineKeys1 = getDefineKeys(forgeConfig.renderer.map(({ name }) => name!)); + const defineKeys2 = { + main_window: { + VITE_DEV_SERVER_URL: 'MAIN_WINDOW_VITE_DEV_SERVER_URL', + VITE_NAME: 'MAIN_WINDOW_VITE_NAME', + }, + second_window: { + VITE_DEV_SERVER_URL: 'SECOND_WINDOW_VITE_DEV_SERVER_URL', + VITE_NAME: 'SECOND_WINDOW_VITE_NAME', + }, + }; + + expect(defineKeys1).deep.equal(defineKeys2); + }); + + it('getBuildDefine:build', () => { + const define1 = getBuildDefine({ + command: 'build', + mode: 'production', + root: configRoot, + forgeConfig, + forgeConfigSelf: forgeConfig.build.find(({ target }) => target === 'main')!, + }); + const define2 = { + MAIN_WINDOW_VITE_DEV_SERVER_URL: undefined, + MAIN_WINDOW_VITE_NAME: '"main_window"', + SECOND_WINDOW_VITE_DEV_SERVER_URL: undefined, + SECOND_WINDOW_VITE_NAME: '"second_window"', + }; + + expect(define1).deep.equal(define2); + }); + + it('getBuildDefine:serve', async () => { + const server = await vite.createServer({ + publicDir: false, + plugins: [pluginExposeRenderer('main_window')], + }); + await server.listen(5173); + + const define1 = getBuildDefine({ + command: 'serve', + mode: 'development', + root: configRoot, + forgeConfig, + forgeConfigSelf: forgeConfig.renderer.find(({ name }) => name === 'main_window')!, + }); + const define2 = { + MAIN_WINDOW_VITE_DEV_SERVER_URL: '"http://localhost:5173"', + MAIN_WINDOW_VITE_NAME: '"main_window"', + SECOND_WINDOW_VITE_DEV_SERVER_URL: undefined, // Only one server has been started here. + SECOND_WINDOW_VITE_NAME: '"second_window"', + }; + + await server.close(); + + expect(define1).deep.equal(define2); + }); +}); From 29d4e0bc17dd1c523a899e49adaa8e525756585f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Wang=28=E8=8D=89=E9=9E=8B=E6=B2=A1=E5=8F=B7=29?= <308487730@qq.com> Date: Sat, 29 Jun 2024 12:34:11 +0800 Subject: [PATCH 09/12] fix(template-vite): remove vite.base.config.ts --- packages/template/vite-typescript/src/ViteTypeScriptTemplate.ts | 1 - .../vite-typescript/test/ViteTypeScriptTemplate_spec_slow.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/template/vite-typescript/src/ViteTypeScriptTemplate.ts b/packages/template/vite-typescript/src/ViteTypeScriptTemplate.ts index a12ed4efe6..78fe789f71 100644 --- a/packages/template/vite-typescript/src/ViteTypeScriptTemplate.ts +++ b/packages/template/vite-typescript/src/ViteTypeScriptTemplate.ts @@ -25,7 +25,6 @@ class ViteTypeScriptTemplate extends BaseTemplate { const filePath = (fileName: string) => path.join(directory, 'src', fileName); // Copy Vite files - await this.copyTemplateFile(directory, 'vite.base.config.ts'); await this.copyTemplateFile(directory, 'vite.main.config.ts'); await this.copyTemplateFile(directory, 'vite.preload.config.ts'); await this.copyTemplateFile(directory, 'vite.renderer.config.ts'); diff --git a/packages/template/vite-typescript/test/ViteTypeScriptTemplate_spec_slow.ts b/packages/template/vite-typescript/test/ViteTypeScriptTemplate_spec_slow.ts index 4ab251c854..0ec0c034e7 100644 --- a/packages/template/vite-typescript/test/ViteTypeScriptTemplate_spec_slow.ts +++ b/packages/template/vite-typescript/test/ViteTypeScriptTemplate_spec_slow.ts @@ -41,7 +41,6 @@ describe('ViteTypeScriptTemplate', () => { '.eslintrc.json', 'forge.env.d.ts', 'forge.config.ts', - 'vite.base.config.ts', 'vite.main.config.ts', 'vite.preload.config.ts', 'vite.renderer.config.ts', From 58807567941170a5bf098a2a71c97c82f6c62596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Wang=28=E8=8D=89=E9=9E=8B=E6=B2=A1=E5=8F=B7=29?= <308487730@qq.com> Date: Mon, 8 Jul 2024 10:23:54 +0800 Subject: [PATCH 10/12] chore(plugin-vite): cleanup code style --- .eslintrc.json | 11 ++++++++ package.json | 1 - packages/plugin/vite/package.json | 1 - packages/plugin/vite/src/Config.ts | 1 - packages/plugin/vite/src/ViteConfig.ts | 27 ++++++++++--------- packages/plugin/vite/src/VitePlugin.ts | 1 - .../vite/src/config/vite.base.config.ts | 1 - .../vite/src/config/vite.main.config.ts | 1 - .../vite/src/config/vite.preload.config.ts | 1 - .../vite/src/config/vite.renderer.config.ts | 1 - packages/plugin/vite/src/util/plugins.ts | 1 - packages/plugin/vite/test/ViteConfig_spec.ts | 6 ++--- .../vite/test/config/vite.base.config_spec.ts | 8 +++--- ...te.main.config.js => vite.main.config.mjs} | 0 ...load.config.js => vite.preload.config.mjs} | 0 ...rer.config.js => vite.renderer.config.mjs} | 0 packages/template/vite/src/ViteTemplate.ts | 6 ++--- .../template/vite/test/ViteTemplate_spec.ts | 6 ++--- packages/template/vite/tmpl/forge.config.js | 6 ++--- ...te.main.config.js => vite.main.config.mjs} | 0 ...load.config.js => vite.preload.config.mjs} | 0 ...rer.config.js => vite.renderer.config.mjs} | 0 22 files changed, 42 insertions(+), 37 deletions(-) rename packages/plugin/vite/test/fixtures/vite-configs/{vite.main.config.js => vite.main.config.mjs} (100%) rename packages/plugin/vite/test/fixtures/vite-configs/{vite.preload.config.js => vite.preload.config.mjs} (100%) rename packages/plugin/vite/test/fixtures/vite-configs/{vite.renderer.config.js => vite.renderer.config.mjs} (100%) rename packages/template/vite/tmpl/{vite.main.config.js => vite.main.config.mjs} (100%) rename packages/template/vite/tmpl/{vite.preload.config.js => vite.preload.config.mjs} (100%) rename packages/template/vite/tmpl/{vite.renderer.config.js => vite.renderer.config.mjs} (100%) diff --git a/.eslintrc.json b/.eslintrc.json index 3460fb1550..4dd028066d 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -129,6 +129,17 @@ "node/no-unpublished-require": "off", "node/shebang": "off" } + }, + { + "files": ["packages/plugin/vite/src/**/*.ts"], + "rules": { + "node/no-unpublished-import": [ + "error", + { + "allowModules": ["vite"] + } + ] + } } ] } diff --git a/package.json b/package.json index 1b8374bbc3..b829274128 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,6 @@ "fast-glob": "^3.2.7", "filenamify": "^4.1.0", "find-up": "^5.0.0", - "flora-colossus": "^2.0.0", "form-data": "^4.0.0", "fs-extra": "^10.0.0", "got": "^11.8.5", diff --git a/packages/plugin/vite/package.json b/packages/plugin/vite/package.json index 88867c5e61..c3f80b91bc 100644 --- a/packages/plugin/vite/package.json +++ b/packages/plugin/vite/package.json @@ -21,7 +21,6 @@ "@electron-forge/web-multi-logger": "7.4.0", "chalk": "^4.0.0", "debug": "^4.3.1", - "flora-colossus": "^2.0.0", "fs-extra": "^10.0.0", "listr2": "^7.0.2" }, diff --git a/packages/plugin/vite/src/Config.ts b/packages/plugin/vite/src/Config.ts index 0665a49444..52dfafd4ff 100644 --- a/packages/plugin/vite/src/Config.ts +++ b/packages/plugin/vite/src/Config.ts @@ -1,4 +1,3 @@ -// eslint-disable-next-line node/no-unpublished-import import type { LibraryOptions } from 'vite'; export interface VitePluginBuildConfig { diff --git a/packages/plugin/vite/src/ViteConfig.ts b/packages/plugin/vite/src/ViteConfig.ts index c3d2cef378..ea0077f81e 100644 --- a/packages/plugin/vite/src/ViteConfig.ts +++ b/packages/plugin/vite/src/ViteConfig.ts @@ -1,5 +1,4 @@ import debug from 'debug'; -// eslint-disable-next-line node/no-unpublished-import import { loadConfigFromFile, mergeConfig } from 'vite'; import { getConfig as getMainViteConfig } from './config/vite.main.config'; @@ -7,17 +6,18 @@ import { getConfig as getPreloadViteConfig } from './config/vite.preload.config' import { getConfig as getRendererViteConfig } from './config/vite.renderer.config'; import type { VitePluginBuildConfig, VitePluginConfig, VitePluginRendererConfig } from './Config'; -// eslint-disable-next-line node/no-unpublished-import import type { ConfigEnv, UserConfig } from 'vite'; const d = debug('@electron-forge/plugin-vite:ViteConfig'); +type Target = NonNullable | 'renderer'; + export default class ViteConfigGenerator { constructor(private readonly pluginConfig: VitePluginConfig, private readonly projectDir: string, private readonly isProd: boolean) { d('Config mode:', this.mode); } - async resolveConfig(buildConfig: VitePluginBuildConfig | VitePluginRendererConfig, target?: VitePluginBuildConfig['target']) { + async resolveConfig(buildConfig: VitePluginBuildConfig | VitePluginRendererConfig, target: Target): Promise { const configEnv: ConfigEnv = { // @see - https://vitejs.dev/config/#conditional-config command: this.isProd ? 'build' : 'serve', @@ -31,14 +31,17 @@ export default class ViteConfigGenerator { }; // `configEnv` is to be passed as an arguments when the user export a function in `vite.config.js`. - const userConfig = (await loadConfigFromFile(configEnv as ConfigEnv, buildConfig.config))?.config ?? {}; - if (target === 'main') { - return mergeConfig(getMainViteConfig(configEnv as ConfigEnv<'build'>), userConfig); - } - if (target === 'preload') { - return mergeConfig(getPreloadViteConfig(configEnv as ConfigEnv<'build'>), userConfig); + const userConfig = (await loadConfigFromFile(configEnv, buildConfig.config))?.config ?? {}; + switch (target) { + case 'main': + return mergeConfig(getMainViteConfig(configEnv as ConfigEnv<'build'>), userConfig); + case 'preload': + return mergeConfig(getPreloadViteConfig(configEnv as ConfigEnv<'build'>), userConfig); + case 'renderer': + return mergeConfig(getRendererViteConfig(configEnv as ConfigEnv<'renderer'>), userConfig); + default: + throw new Error(`Unknown target: ${target}, expected 'main', 'preload' or 'renderer'`); } - return mergeConfig(getRendererViteConfig(configEnv as ConfigEnv<'renderer'>), userConfig); } get mode(): string { @@ -56,7 +59,7 @@ export default class ViteConfigGenerator { const configs = this.pluginConfig.build // Prevent load the default `vite.config.js` file. .filter(({ config }) => config) - .map>((buildConfig) => this.resolveConfig(buildConfig, buildConfig.target ?? 'main')); + .map((buildConfig) => this.resolveConfig(buildConfig, buildConfig.target ?? 'main')); return await Promise.all(configs); } @@ -69,7 +72,7 @@ export default class ViteConfigGenerator { const configs = this.pluginConfig.renderer // Prevent load the default `vite.config.js` file. .filter(({ config }) => config) - .map>((buildConfig) => this.resolveConfig(buildConfig)); + .map((buildConfig) => this.resolveConfig(buildConfig, 'renderer')); return await Promise.all(configs); } diff --git a/packages/plugin/vite/src/VitePlugin.ts b/packages/plugin/vite/src/VitePlugin.ts index 6a6f8a7eee..821e511f61 100644 --- a/packages/plugin/vite/src/VitePlugin.ts +++ b/packages/plugin/vite/src/VitePlugin.ts @@ -5,7 +5,6 @@ import chalk from 'chalk'; import debug from 'debug'; import fs from 'fs-extra'; import { PRESET_TIMER } from 'listr2'; -// eslint-disable-next-line node/no-unpublished-import import { default as vite } from 'vite'; import { onBuildDone } from './util/plugins'; diff --git a/packages/plugin/vite/src/config/vite.base.config.ts b/packages/plugin/vite/src/config/vite.base.config.ts index c480a106f6..727f6614e7 100644 --- a/packages/plugin/vite/src/config/vite.base.config.ts +++ b/packages/plugin/vite/src/config/vite.base.config.ts @@ -1,7 +1,6 @@ import { builtinModules } from 'node:module'; import type { AddressInfo } from 'node:net'; -// eslint-disable-next-line node/no-unpublished-import import type { ConfigEnv, Plugin, UserConfig, ViteDevServer } from 'vite'; export const builtins = ['electron', ...builtinModules.map((m) => [m, `node:${m}`]).flat()]; diff --git a/packages/plugin/vite/src/config/vite.main.config.ts b/packages/plugin/vite/src/config/vite.main.config.ts index 073c6c76ec..ce7ccd1fc3 100644 --- a/packages/plugin/vite/src/config/vite.main.config.ts +++ b/packages/plugin/vite/src/config/vite.main.config.ts @@ -1,4 +1,3 @@ -// eslint-disable-next-line node/no-unpublished-import import { type ConfigEnv, mergeConfig, type UserConfig } from 'vite'; import { external, getBuildConfig, getBuildDefine, pluginHotRestart } from './vite.base.config'; diff --git a/packages/plugin/vite/src/config/vite.preload.config.ts b/packages/plugin/vite/src/config/vite.preload.config.ts index 3629d4a8f7..7f99bd5845 100644 --- a/packages/plugin/vite/src/config/vite.preload.config.ts +++ b/packages/plugin/vite/src/config/vite.preload.config.ts @@ -1,4 +1,3 @@ -// eslint-disable-next-line node/no-unpublished-import import { type ConfigEnv, mergeConfig, type UserConfig } from 'vite'; import { external, getBuildConfig, pluginHotRestart } from './vite.base.config'; diff --git a/packages/plugin/vite/src/config/vite.renderer.config.ts b/packages/plugin/vite/src/config/vite.renderer.config.ts index e8d0f994ac..a5262d8d9d 100644 --- a/packages/plugin/vite/src/config/vite.renderer.config.ts +++ b/packages/plugin/vite/src/config/vite.renderer.config.ts @@ -1,4 +1,3 @@ -// eslint-disable-next-line node/no-unpublished-import import { type ConfigEnv, type UserConfig } from 'vite'; import { pluginExposeRenderer } from './vite.base.config'; diff --git a/packages/plugin/vite/src/util/plugins.ts b/packages/plugin/vite/src/util/plugins.ts index ca7f630bb7..5bb0e0b256 100644 --- a/packages/plugin/vite/src/util/plugins.ts +++ b/packages/plugin/vite/src/util/plugins.ts @@ -1,4 +1,3 @@ -// eslint-disable-next-line node/no-unpublished-import import type { Plugin } from 'vite'; export function onBuildDone(callback: () => void) { diff --git a/packages/plugin/vite/test/ViteConfig_spec.ts b/packages/plugin/vite/test/ViteConfig_spec.ts index 951b081bf7..f0b716e572 100644 --- a/packages/plugin/vite/test/ViteConfig_spec.ts +++ b/packages/plugin/vite/test/ViteConfig_spec.ts @@ -16,7 +16,7 @@ describe('ViteConfigGenerator', () => { build: [ { entry: 'src/main.js', - config: path.join(configRoot, 'vite.main.config.js'), + config: path.join(configRoot, 'vite.main.config.mjs'), target: 'main', }, ], @@ -49,7 +49,7 @@ describe('ViteConfigGenerator', () => { build: [ { entry: 'src/preload.js', - config: path.join(configRoot, 'vite.preload.config.js'), + config: path.join(configRoot, 'vite.preload.config.mjs'), target: 'preload', }, ], @@ -83,7 +83,7 @@ describe('ViteConfigGenerator', () => { renderer: [ { name: 'main_window', - config: path.join(configRoot, 'vite.renderer.config.js'), + config: path.join(configRoot, 'vite.renderer.config.mjs'), }, ], }; diff --git a/packages/plugin/vite/test/config/vite.base.config_spec.ts b/packages/plugin/vite/test/config/vite.base.config_spec.ts index 6faaae5dda..379e66f97f 100644 --- a/packages/plugin/vite/test/config/vite.base.config_spec.ts +++ b/packages/plugin/vite/test/config/vite.base.config_spec.ts @@ -12,23 +12,23 @@ const forgeConfig: VitePluginConfig = { build: [ { entry: 'src/main.js', - config: path.join(configRoot, 'vite.main.config.js'), + config: path.join(configRoot, 'vite.main.config.mjs'), target: 'main', }, { entry: 'src/preload.js', - config: path.join(configRoot, 'vite.preload.config.js'), + config: path.join(configRoot, 'vite.preload.config.mjs'), target: 'preload', }, ], renderer: [ { name: 'main_window', - config: path.join(configRoot, 'vite.renderer.config.js'), + config: path.join(configRoot, 'vite.renderer.config.mjs'), }, { name: 'second_window', - config: path.join(configRoot, 'vite.renderer.config.js'), + config: path.join(configRoot, 'vite.renderer.config.mjs'), }, ], }; diff --git a/packages/plugin/vite/test/fixtures/vite-configs/vite.main.config.js b/packages/plugin/vite/test/fixtures/vite-configs/vite.main.config.mjs similarity index 100% rename from packages/plugin/vite/test/fixtures/vite-configs/vite.main.config.js rename to packages/plugin/vite/test/fixtures/vite-configs/vite.main.config.mjs diff --git a/packages/plugin/vite/test/fixtures/vite-configs/vite.preload.config.js b/packages/plugin/vite/test/fixtures/vite-configs/vite.preload.config.mjs similarity index 100% rename from packages/plugin/vite/test/fixtures/vite-configs/vite.preload.config.js rename to packages/plugin/vite/test/fixtures/vite-configs/vite.preload.config.mjs diff --git a/packages/plugin/vite/test/fixtures/vite-configs/vite.renderer.config.js b/packages/plugin/vite/test/fixtures/vite-configs/vite.renderer.config.mjs similarity index 100% rename from packages/plugin/vite/test/fixtures/vite-configs/vite.renderer.config.js rename to packages/plugin/vite/test/fixtures/vite-configs/vite.renderer.config.mjs diff --git a/packages/template/vite/src/ViteTemplate.ts b/packages/template/vite/src/ViteTemplate.ts index 5a92ab7f2c..ef14ad9544 100644 --- a/packages/template/vite/src/ViteTemplate.ts +++ b/packages/template/vite/src/ViteTemplate.ts @@ -21,9 +21,9 @@ class ViteTemplate extends BaseTemplate { { title: 'Setting up Vite configuration', task: async () => { - await this.copyTemplateFile(directory, 'vite.main.config.js'); - await this.copyTemplateFile(directory, 'vite.preload.config.js'); - await this.copyTemplateFile(directory, 'vite.renderer.config.js'); + await this.copyTemplateFile(directory, 'vite.main.config.mjs'); + await this.copyTemplateFile(directory, 'vite.preload.config.mjs'); + await this.copyTemplateFile(directory, 'vite.renderer.config.mjs'); await this.copyTemplateFile(path.join(directory, 'src'), 'renderer.js'); await this.copyTemplateFile(path.join(directory, 'src'), 'preload.js'); diff --git a/packages/template/vite/test/ViteTemplate_spec.ts b/packages/template/vite/test/ViteTemplate_spec.ts index 34bc50e1d2..b772b962d4 100644 --- a/packages/template/vite/test/ViteTemplate_spec.ts +++ b/packages/template/vite/test/ViteTemplate_spec.ts @@ -30,9 +30,9 @@ describe('ViteTemplate', () => { 'package.json', 'forge.env.d.ts', 'forge.config.js', - 'vite.main.config.js', - 'vite.preload.config.js', - 'vite.renderer.config.js', + 'vite.main.config.mjs', + 'vite.preload.config.mjs', + 'vite.renderer.config.mjs', path.join('src', 'renderer.js'), path.join('src', 'preload.js'), ]; diff --git a/packages/template/vite/tmpl/forge.config.js b/packages/template/vite/tmpl/forge.config.js index 94a6e7d35b..f8d183977a 100644 --- a/packages/template/vite/tmpl/forge.config.js +++ b/packages/template/vite/tmpl/forge.config.js @@ -34,19 +34,19 @@ module.exports = { { // `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`. entry: 'src/main.js', - config: 'vite.main.config.js', + config: 'vite.main.config.mjs', target: 'main', }, { entry: 'src/preload.js', - config: 'vite.preload.config.js', + config: 'vite.preload.config.mjs', target: 'preload', }, ], renderer: [ { name: 'main_window', - config: 'vite.renderer.config.js', + config: 'vite.renderer.config.mjs', }, ], }, diff --git a/packages/template/vite/tmpl/vite.main.config.js b/packages/template/vite/tmpl/vite.main.config.mjs similarity index 100% rename from packages/template/vite/tmpl/vite.main.config.js rename to packages/template/vite/tmpl/vite.main.config.mjs diff --git a/packages/template/vite/tmpl/vite.preload.config.js b/packages/template/vite/tmpl/vite.preload.config.mjs similarity index 100% rename from packages/template/vite/tmpl/vite.preload.config.js rename to packages/template/vite/tmpl/vite.preload.config.mjs diff --git a/packages/template/vite/tmpl/vite.renderer.config.js b/packages/template/vite/tmpl/vite.renderer.config.mjs similarity index 100% rename from packages/template/vite/tmpl/vite.renderer.config.js rename to packages/template/vite/tmpl/vite.renderer.config.mjs From a0148b57cedcc6ac88116183ce90b1886a4dbd7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Wang=28=E8=8D=89=E9=9E=8B=E6=B2=A1=E5=8F=B7=29?= <308487730@qq.com> Date: Mon, 8 Jul 2024 10:28:56 +0800 Subject: [PATCH 11/12] fix(plugin-vite): necessary forge config options --- packages/plugin/vite/src/Config.ts | 4 ++-- packages/plugin/vite/src/config/vite.main.config.ts | 2 +- packages/plugin/vite/src/config/vite.preload.config.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/plugin/vite/src/Config.ts b/packages/plugin/vite/src/Config.ts index 52dfafd4ff..8aba1b9299 100644 --- a/packages/plugin/vite/src/Config.ts +++ b/packages/plugin/vite/src/Config.ts @@ -4,7 +4,7 @@ export interface VitePluginBuildConfig { /** * Alias of `build.lib.entry` in `config`. */ - entry?: LibraryOptions['entry']; + entry: LibraryOptions['entry']; /** * Vite config file path. */ @@ -20,7 +20,7 @@ export interface VitePluginRendererConfig { /** * Human friendly name of your entry point. */ - name?: string; + name: string; /** * Vite config file path. */ diff --git a/packages/plugin/vite/src/config/vite.main.config.ts b/packages/plugin/vite/src/config/vite.main.config.ts index ce7ccd1fc3..137e6ac4ff 100644 --- a/packages/plugin/vite/src/config/vite.main.config.ts +++ b/packages/plugin/vite/src/config/vite.main.config.ts @@ -8,7 +8,7 @@ export function getConfig(forgeEnv: ConfigEnv<'build'>): UserConfig { const config: UserConfig = { build: { lib: { - entry: forgeConfigSelf.entry!, + entry: forgeConfigSelf.entry, fileName: () => '[name].js', formats: ['cjs'], }, diff --git a/packages/plugin/vite/src/config/vite.preload.config.ts b/packages/plugin/vite/src/config/vite.preload.config.ts index 7f99bd5845..03e128d360 100644 --- a/packages/plugin/vite/src/config/vite.preload.config.ts +++ b/packages/plugin/vite/src/config/vite.preload.config.ts @@ -9,7 +9,7 @@ export function getConfig(forgeEnv: ConfigEnv<'build'>): UserConfig { rollupOptions: { external, // Preload scripts may contain Web assets, so use the `build.rollupOptions.input` instead `build.lib.entry`. - input: forgeConfigSelf.entry!, + input: forgeConfigSelf.entry, output: { format: 'cjs', // It should not be split chunks. From 9c6ca786cbd1a78e2be0ee0a2484d53ce842ba20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Wang=28=E8=8D=89=E9=9E=8B=E6=B2=A1=E5=8F=B7=29?= <308487730@qq.com> Date: Mon, 8 Jul 2024 12:44:39 +0800 Subject: [PATCH 12/12] chore(plugin-vite): update test --- .../vite/test/config/vite.base.config_spec.ts | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/packages/plugin/vite/test/config/vite.base.config_spec.ts b/packages/plugin/vite/test/config/vite.base.config_spec.ts index 379e66f97f..34d23df12f 100644 --- a/packages/plugin/vite/test/config/vite.base.config_spec.ts +++ b/packages/plugin/vite/test/config/vite.base.config_spec.ts @@ -35,7 +35,7 @@ const forgeConfig: VitePluginConfig = { describe('vite.base.config', () => { it('getDefineKeys', () => { - const defineKeys1 = getDefineKeys(forgeConfig.renderer.map(({ name }) => name!)); + const defineKeys1 = getDefineKeys(forgeConfig.renderer.map(({ name }) => name)); const defineKeys2 = { main_window: { VITE_DEV_SERVER_URL: 'MAIN_WINDOW_VITE_DEV_SERVER_URL', @@ -56,7 +56,7 @@ describe('vite.base.config', () => { mode: 'production', root: configRoot, forgeConfig, - forgeConfigSelf: forgeConfig.build.find(({ target }) => target === 'main')!, + forgeConfigSelf: forgeConfig.build[0], }); const define2 = { MAIN_WINDOW_VITE_DEV_SERVER_URL: undefined, @@ -69,27 +69,38 @@ describe('vite.base.config', () => { }); it('getBuildDefine:serve', async () => { - const server = await vite.createServer({ - publicDir: false, - plugins: [pluginExposeRenderer('main_window')], - }); - await server.listen(5173); + const servers = await Promise.all( + forgeConfig.renderer.map(({ name }) => + vite.createServer({ + publicDir: false, + plugins: [pluginExposeRenderer(name)], + }) + ) + ); + let port = 5173; + + for (const server of servers) { + await server.listen(port); + port++; + } const define1 = getBuildDefine({ command: 'serve', mode: 'development', root: configRoot, forgeConfig, - forgeConfigSelf: forgeConfig.renderer.find(({ name }) => name === 'main_window')!, + forgeConfigSelf: forgeConfig.build[0], }); const define2 = { MAIN_WINDOW_VITE_DEV_SERVER_URL: '"http://localhost:5173"', MAIN_WINDOW_VITE_NAME: '"main_window"', - SECOND_WINDOW_VITE_DEV_SERVER_URL: undefined, // Only one server has been started here. + SECOND_WINDOW_VITE_DEV_SERVER_URL: '"http://localhost:5174"', SECOND_WINDOW_VITE_NAME: '"second_window"', }; - await server.close(); + for (const server of servers) { + await server.close(); + } expect(define1).deep.equal(define2); });