-
-
Notifications
You must be signed in to change notification settings - Fork 531
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(template): add vite template #3071
Merged
Merged
Changes from 21 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
f8b8863
feat(template): add vite template
caoxiemeihao f344601
refactor: better `CLIOptions` type define
caoxiemeihao 381cfba
feat: semantic Renderer config
caoxiemeihao 7a3bd0a
feat!:support multiple renderer
caoxiemeihao 386f499
chore: cleanup
caoxiemeihao 3c391f6
feat: add ViteConfig test
caoxiemeihao 67ab9b8
chore: format code
caoxiemeihao fc2e585
feat: add util/plugins test
caoxiemeihao a654219
fix(test): compatible Windows OS
caoxiemeihao d8317a8
Update packages/plugin/vite/src/ViteConfig.ts
caoxiemeihao afe9e2a
Update packages/plugin/vite/src/util/plugins.ts
caoxiemeihao 13e1cf7
Update packages/template/vite/.eslintignore
caoxiemeihao 9d4a084
Update packages/plugin/vite/src/ViteConfig.ts
caoxiemeihao ac9262a
fix: typo
caoxiemeihao 26d9376
Update packages/plugin/vite/README.md
caoxiemeihao 0cb2d09
Update packages/plugin/vite/src/VitePlugin.ts
caoxiemeihao f523cf4
Update packages/plugin/vite/src/VitePlugin.ts
caoxiemeihao 0d2956f
Update packages/plugin/vite/src/VitePlugin.ts
caoxiemeihao a1ee377
Update packages/plugin/vite/src/VitePlugin.ts
caoxiemeihao 6835f64
chore: format code
caoxiemeihao ec48dd6
chore: update version
caoxiemeihao b026eea
Merge branch 'main' into caoxie-vite
erickzhao b465708
chore: update version numbers
erickzhao 696bd62
Merge pull request #1 from electron/caoxie-vite
caoxiemeihao 094bb64
chore: update lockfile
erickzhao 89a63ac
Merge pull request #2 from electron/caoxie-vite
caoxiemeihao File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
## plugin-vite | ||
|
||
This plugin makes it easy to set up standard vite tooling to compile both your main process code and your renderer process code, with built-in support for Hot Module Replacement (HMR) in the renderer process and support for multiple renderers. | ||
|
||
```javascript | ||
// forge.config.js | ||
|
||
module.exports = { | ||
plugins: [ | ||
{ | ||
name: '@electron-forge/plugin-vite', | ||
config: { | ||
// `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc. | ||
// If you are familiar with Vite configuration, it will look really familiar. | ||
build: [ | ||
{ | ||
// `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`. | ||
entry: 'src/main.js', | ||
config: 'vite.main.config.mjs', | ||
}, | ||
{ | ||
entry: 'src/preload.js', | ||
config: 'vite.preload.config.mjs', | ||
}, | ||
], | ||
renderer: [ | ||
{ | ||
name: 'main_window', | ||
config: 'vite.renderer.config.mjs', | ||
}, | ||
], | ||
}, | ||
}, | ||
], | ||
}; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
{ | ||
"name": "@electron-forge/plugin-vite", | ||
"version": "6.1.0", | ||
"description": "Vite plugin for Electron Forge, lets you use Vite directly in your tooling", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/electron/forge", | ||
"directory": "packages/plugin/vite" | ||
}, | ||
"author": "caoxiemeihao", | ||
"license": "MIT", | ||
"main": "dist/VitePlugin.js", | ||
"typings": "dist/VitePlugin.d.ts", | ||
"scripts": { | ||
"test": "xvfb-maybe mocha --config ../../../.mocharc.js test/**/*_spec.ts" | ||
}, | ||
"devDependencies": { | ||
"@malept/cross-spawn-promise": "^2.0.0", | ||
"@types/node": "^18.0.3", | ||
"chai": "^4.3.3", | ||
"fs-extra": "^10.0.0", | ||
"mocha": "^9.0.1", | ||
"which": "^2.0.2", | ||
"xvfb-maybe": "^0.2.1" | ||
}, | ||
"engines": { | ||
"node": "^14.18.0 || >=16.0.0" | ||
}, | ||
"dependencies": { | ||
"@electron-forge/core-utils": "6.0.4", | ||
"@electron-forge/plugin-base": "6.0.4", | ||
"@electron-forge/shared-types": "6.0.4", | ||
"@electron-forge/web-multi-logger": "6.0.4", | ||
"chalk": "^4.0.0", | ||
"debug": "^4.3.1", | ||
"vite": "^4.1.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import type { LibraryOptions } from 'vite'; | ||
|
||
export interface VitePluginBuildConfig { | ||
/** | ||
* Alias of `build.lib.entry` in `config`. | ||
*/ | ||
entry?: LibraryOptions['entry']; | ||
/** | ||
* Vite config file path. | ||
*/ | ||
config?: string; | ||
} | ||
|
||
export interface VitePluginRendererConfig { | ||
/** | ||
* Human friendly name of your entry point | ||
*/ | ||
name: string; | ||
/** | ||
* Vite config file path. | ||
*/ | ||
config: string; | ||
} | ||
|
||
export interface VitePluginConfig { | ||
/** | ||
* Build anything such as Main process, Preload scripts and Worker process, etc. | ||
*/ | ||
build: VitePluginBuildConfig[]; | ||
/** | ||
* Renderer process. | ||
*/ | ||
renderer: VitePluginRendererConfig[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
import path from 'node:path'; | ||
|
||
import debug from 'debug'; | ||
import { ConfigEnv, loadConfigFromFile, mergeConfig, UserConfig } from 'vite'; | ||
|
||
import { VitePluginConfig } from './Config'; | ||
import { externalBuiltins } from './util/plugins'; | ||
|
||
const d = debug('electron-forge:plugin:vite:viteconfig'); | ||
|
||
/** | ||
* Vite allows zero-config runs, if the user does not provide `vite.config.js`, | ||
* then the value of `LoadResult` will become `null`. | ||
*/ | ||
export type LoadResult = Awaited<ReturnType<typeof loadConfigFromFile>>; | ||
|
||
export default class ViteConfigGenerator { | ||
private readonly baseDir: string; | ||
|
||
private rendererConfigCache!: Promise<UserConfig>[]; | ||
|
||
constructor(private readonly pluginConfig: VitePluginConfig, private readonly projectDir: string, private readonly isProd: boolean) { | ||
this.baseDir = path.join(projectDir, '.vite'); | ||
d('Config mode:', this.mode); | ||
} | ||
|
||
resolveConfig(config: string, configEnv: Partial<ConfigEnv> = {}) { | ||
// `command` is to be passed as an arguments when the user export a function in `vite.config.js`. | ||
// @see - https://vitejs.dev/config/#conditional-config | ||
configEnv.command ??= this.isProd ? 'build' : 'serve'; | ||
// `mode` affects `.env.[mode]` file loading. | ||
configEnv.mode ??= this.mode; | ||
return loadConfigFromFile(configEnv as ConfigEnv, config); | ||
} | ||
|
||
get mode(): string { | ||
// Vite's `mode` can be passed in via command. | ||
// Since we are currently using the JavaScript API, we are opinionated defining two default values for mode here. | ||
// The `mode` set by the end user in `vite.config.js` has a higher priority. | ||
return this.isProd ? 'production' : 'development'; | ||
} | ||
|
||
async getDefines(): Promise<Record<string, string>> { | ||
const defines: Record<string, any> = {}; | ||
const rendererConfigs = await this.getRendererConfig(); | ||
for (const [index, userConfig] of rendererConfigs.entries()) { | ||
const name = this.pluginConfig.renderer[index].name; | ||
if (!name) { | ||
continue; | ||
} | ||
const NAME = name.toUpperCase().replace(/ /g, '_'); | ||
// There is no guarantee that `port` will always be available, because it may auto increment. | ||
// https://github.com/vitejs/vite/blob/v4.0.4/packages/vite/src/node/http.ts#L170 | ||
defines[`${NAME}_VITE_DEV_SERVER_URL`] = this.isProd | ||
? undefined | ||
: userConfig?.server?.port && JSON.stringify(`http://localhost:${userConfig.server.port}`); | ||
defines[`${NAME}_VITE_NAME`] = JSON.stringify(name); | ||
} | ||
return defines; | ||
} | ||
|
||
async getBuildConfig(watch = false): Promise<UserConfig[]> { | ||
if (!Array.isArray(this.pluginConfig.build)) { | ||
throw new Error('"config.build" must be an Array'); | ||
} | ||
|
||
const define = await this.getDefines(); | ||
const plugins = [externalBuiltins()]; | ||
const configs = this.pluginConfig.build | ||
.filter(({ entry, config }) => entry || config) | ||
.map<Promise<UserConfig>>(async ({ entry, config }) => { | ||
const defaultConfig: UserConfig = { | ||
// Ensure that each build config loads the .env file correctly. | ||
mode: this.mode, | ||
build: { | ||
lib: entry | ||
? { | ||
entry, | ||
// Electron can only support cjs. | ||
formats: ['cjs'], | ||
fileName: () => '[name].js', | ||
} | ||
: undefined, | ||
// Prevent multiple builds from interfering with each other. | ||
emptyOutDir: false, | ||
// 🚧 Multiple builds may conflict. | ||
outDir: path.join(this.baseDir, 'build'), | ||
watch: watch ? {} : undefined, | ||
erickzhao marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
clearScreen: false, | ||
define, | ||
plugins, | ||
}; | ||
if (config) { | ||
const loadResult = await this.resolveConfig(config); | ||
return mergeConfig(defaultConfig, loadResult?.config ?? {}); | ||
} | ||
return defaultConfig; | ||
}); | ||
|
||
return await Promise.all(configs); | ||
} | ||
|
||
async getRendererConfig(): Promise<UserConfig[]> { | ||
if (!Array.isArray(this.pluginConfig.renderer)) { | ||
throw new Error('"config.renderer" must be an Array'); | ||
} | ||
|
||
let port = 5173; | ||
const configs = (this.rendererConfigCache ??= this.pluginConfig.renderer.map(async ({ name, config }) => { | ||
const defaultConfig: UserConfig = { | ||
// Ensure that each build config loads the .env file correctly. | ||
mode: this.mode, | ||
// Make sure that Electron can be loaded into the local file using `loadFile` after packaging. | ||
base: './', | ||
build: { | ||
outDir: path.join(this.baseDir, 'renderer', name), | ||
}, | ||
clearScreen: false, | ||
}; | ||
const loadResult = (await this.resolveConfig(config)) ?? { path: '', config: {}, dependencies: [] }; | ||
loadResult.config.server ??= {}; | ||
loadResult.config.server.port ??= port++; | ||
return mergeConfig(defaultConfig, loadResult.config); | ||
})); | ||
|
||
return await Promise.all(configs); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
todo: replace this text with one specific for the vite plugin