提交 15bc6b84 作者: 方治民

test: electron-vite

上级 aec3375b
node_modules
.DS_Store
dist
out
.npmrc
.cache
......
......@@ -8,6 +8,17 @@
"url": "http://localhost:3100",
"webRoot": "${workspaceFolder}/src",
"sourceMaps": true
},
{
"name": "Debug Main Process",
"type": "node",
"request": "launch",
"cwd": "${workspaceRoot}",
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-vite",
"windows": {
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-vite.cmd"
},
"runtimeArgs": ["--sourcemap"]
}
]
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
</dict>
</plist>
const { notarize } = require('@electron/notarize')
module.exports = async (context) => {
if (process.platform !== 'darwin') return
console.log('aftersign hook triggered, start to notarize app.')
if (!process.env.CI) {
console.log(`skipping notarizing, not in CI.`)
return
}
if (!('APPLE_ID' in process.env && 'APPLE_ID_PASS' in process.env)) {
console.warn('skipping notarizing, APPLE_ID and APPLE_ID_PASS env variables must be set.')
return
}
const appId = 'com.yiring.basic.electron.app'
const { appOutDir } = context
const appName = context.packager.appInfo.productFilename
try {
await notarize({
appBundleId: appId,
appPath: `${appOutDir}/${appName}.app`,
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLEIDPASS,
})
} catch (error) {
console.error(error)
}
console.log(`done notarizing ${appId}.`)
}
import { generateAntColors, primaryColor } from '../config/themeConfig'
import { resolve } from 'node:path'
import { getThemeVariables } from 'ant-design-vue/dist/theme'
import { resolve } from 'path'
import { generateAntColors, primaryColor } from '../config/themeConfig'
/**
* less global variable
......@@ -28,7 +28,7 @@ export function generateModifyVars(dark = false) {
'success-color': '#55D187', // Success color
'error-color': '#ED6F6F', // False color
'warning-color': '#EFBD47', // Warning color
//'border-color-base': '#EEEEEE',
// 'border-color-base': '#EEEEEE',
'font-size-base': '14px', // Main font size
'border-radius-base': '2px', // Component/float fillet
'link-color': primary, // Link color
......
import path from 'path'
import path from 'node:path'
import fs from 'fs-extra'
import inquirer from 'inquirer'
import colors from 'picocolors'
......@@ -30,7 +30,7 @@ async function generateIcon() {
{
type: 'list',
name: 'iconSet',
choices: choices,
choices,
message: 'Select the icon set that needs to be generated?',
},
{
......@@ -51,25 +51,17 @@ async function generateIcon() {
if (data) {
const { prefix } = data
const isLocal = useType === 'local'
const icons = Object.keys(data.icons).map(
(item) => `${isLocal ? prefix + ':' : ''}${item}`,
)
const icons = Object.keys(data.icons).map((item) => `${isLocal ? `${prefix}:` : ''}${item}`)
await fs.writeFileSync(
path.join(output, `icons.data.ts`),
`export default ${
isLocal ? JSON.stringify(icons) : JSON.stringify({ prefix, icons })
}`,
`export default ${isLocal ? JSON.stringify(icons) : JSON.stringify({ prefix, icons })}`,
)
prefixSet.push(prefix)
}
}
fs.emptyDir(path.join(process.cwd(), 'node_modules/.vite'))
console.log(
`✨ ${colors.cyan(`[${pkg.name}]`)}` +
' - Icon generated successfully:' +
`[${prefixSet}]`,
)
console.log(`✨ ${colors.cyan(`[${pkg.name}]`)}` + ' - Icon generated successfully:' + `[${prefixSet}]`)
})
}
......
/**
* Generate additional configuration files when used for packaging. The file can be configured with some global variables, so that it can be changed directly externally without repackaging
*/
import { GLOB_CONFIG_FILE_NAME, OUTPUT_DIR } from '../constant'
import fs, { writeFileSync } from 'fs-extra'
import colors from 'picocolors'
import { GLOB_CONFIG_FILE_NAME, OUTPUT_DIR } from '../constant'
import { getEnvConfig, getRootPath } from '../utils'
import { getConfigFileName } from '../getConfigFileName'
......@@ -33,10 +33,10 @@ function createConfig(params: CreateConfigParams) {
fs.mkdirp(getRootPath(OUTPUT_DIR))
writeFileSync(getRootPath(`${OUTPUT_DIR}/${configFileName}`), configStr)
console.log(colors.cyan(`✨ [${pkg.name}]`) + ` - configuration file is build successfully:`)
console.log(colors.gray(OUTPUT_DIR + '/' + colors.green(configFileName)) + '\n')
console.log(`${colors.cyan(`✨ [${pkg.name}]`)} - configuration file is build successfully:`)
console.log(`${colors.gray(`${OUTPUT_DIR}/${colors.green(configFileName)}`)}\n`)
} catch (error) {
console.log(colors.red('configuration file configuration file failed to package:\n' + error))
console.log(colors.red(`configuration file configuration file failed to package:\n${error}`))
}
}
......
// #!/usr/bin/env node
import { runBuildConfig } from './buildConf'
import colors from 'picocolors'
import pkg from '../../package.json'
import { runBuildConfig } from './buildConf'
export const runBuild = async () => {
try {
......@@ -16,7 +16,7 @@ export const runBuild = async () => {
console.log(`✨ ${colors.cyan(`[${pkg.name}]`)}` + ' - build successfully!')
} catch (error) {
console.log(colors.red('vite build error:\n' + error))
console.log(colors.red(`vite build error:\n${error}`))
process.exit(1)
}
}
......
import fs from 'fs'
import path from 'path'
import fs from 'node:fs'
import path from 'node:path'
import dotenv from 'dotenv'
export function isDevFn(mode: string): boolean {
......@@ -50,7 +50,7 @@ export function wrapperEnv(envConf: Recordable): ViteEnv {
*/
function getConfFiles() {
const script = process.env.npm_lifecycle_script
const reg = new RegExp('--mode ([a-z_\\d]+)')
const reg = /--mode ([a-z_\d]+)/
const result = reg.exec(script as string) as any
if (result) {
const mode = result[1] as string
......
import { PluginOption } from 'vite'
import type { PluginOption } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import legacy from '@vitejs/plugin-legacy'
......
......@@ -70,7 +70,7 @@ export function configStyleImportPlugin(_isBuild: boolean) {
return ignoreList.includes(name)
? ''
: replaceList.hasOwnProperty(name)
: Object.prototype.hasOwnProperty.call(replaceList, name)
? `ant-design-vue/es/${replaceList[name]}/style/index`
: `ant-design-vue/es/${name}/style/index`
},
......
......@@ -3,8 +3,8 @@
* https://github.com/anncwb/vite-plugin-svg-icons
*/
import path from 'node:path'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import path from 'path'
export function configSvgIconsPlugin(isBuild: boolean) {
const svgIconsPlugin = createSvgIconsPlugin({
......
......@@ -2,16 +2,10 @@
* Vite plugin for website theme color switching
* https://github.com/anncwb/vite-plugin-theme
*/
import path from 'node:path'
import type { PluginOption } from 'vite'
import path from 'path'
import {
viteThemePlugin,
antdDarkThemePlugin,
mixLighten,
mixDarken,
tinycolor,
} from 'vite-plugin-theme'
import { getThemeColors, generateColors } from '../../config/themeConfig'
import { antdDarkThemePlugin, mixDarken, mixLighten, tinycolor, viteThemePlugin } from 'vite-plugin-theme'
import { generateColors, getThemeColors } from '../../config/themeConfig'
import { generateModifyVars } from '../../generate/generateModifyVars'
export function configThemePlugin(isBuild: boolean): PluginOption[] {
......@@ -48,7 +42,7 @@ export function configThemePlugin(isBuild: boolean): PluginOption[] {
antdDarkThemePlugin({
preloadFiles: [
path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/antd.less'),
//path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/antd.dark.less'),
// path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/antd.dark.less'),
path.resolve(process.cwd(), 'src/design/index.less'),
],
filter: (id) => (isBuild ? !id.endsWith('antd.less') : true),
......
appId: com.yiring.basic.electron.app
productName: Basic Electron App
directories:
buildResources: build
files:
- '!**/.vscode/*'
- '!src/*'
- '!electron/*'
- '!tests/*'
- '!types/*'
- '!mock/*'
- '!electron.vite.config.{js,ts,mjs,cjs}'
- '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}'
- '!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}'
asarUnpack:
- '**/*.{node,dll}'
afterSign: build/electron/notarize.js
win:
executableName: basic-electron-app
nsis:
artifactName: ${name}-${version}-setup.${ext}
shortcutName: ${productName}
uninstallDisplayName: ${productName}
createDesktopShortcut: always
mac:
entitlementsInherit: build/electron/entitlements.mac.plist
extendInfo:
- NSCameraUsageDescription: Application requests access to the device's camera.
- NSMicrophoneUsageDescription: Application requests access to the device's microphone.
- NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder.
- NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder.
dmg:
artifactName: ${name}-${version}.${ext}
linux:
target:
- AppImage
- snap
- deb
maintainer: electronjs.org
category: Utility
appImage:
artifactName: ${name}-${version}.${ext}
npmRebuild: false
publish:
provider: generic
url: https://example.com/auto-updates
import { resolve } from 'node:path'
import { merge } from 'lodash-es'
import { defineConfig, defineViteConfig, externalizeDepsPlugin } from 'electron-vite'
export default defineConfig({
main: {
plugins: [externalizeDepsPlugin()],
build: {
rollupOptions: {
input: {
index: resolve(__dirname, 'electron/main/index.ts'),
},
},
},
},
preload: {
plugins: [externalizeDepsPlugin()],
build: {
rollupOptions: {
input: {
index: resolve(__dirname, 'electron/preload/index.ts'),
},
},
},
},
renderer: defineViteConfig(async (env) => {
const renderConfig = (await import('./vite.config')).default
const config = renderConfig(env)
return merge(config, {
build: {
target: 'chrome80',
rollupOptions: {
input: {
index: resolve(__dirname, 'index.html'),
},
},
},
})
}),
})
import * as path from 'node:path'
import { BrowserWindow, app, shell } from 'electron'
import { electronApp, is, optimizer } from '@electron-toolkit/utils'
function createWindow(): void {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 900,
height: 670,
show: false,
autoHideMenuBar: true,
...(process.platform === 'linux'
? {
icon: path.join(__dirname, '../../build/electron/icon.png'),
}
: {}),
webPreferences: {
preload: path.join(__dirname, '../preload/index.js'),
sandbox: false,
},
})
mainWindow.on('ready-to-show', () => {
mainWindow.show()
})
mainWindow.webContents.setWindowOpenHandler((details) => {
shell.openExternal(details.url)
return { action: 'deny' }
})
// HMR for renderer base on electron-vite cli.
// Load the remote URL for development or the local html file for production.
if (is.dev && process.env.ELECTRON_RENDERER_URL) {
mainWindow.loadURL(process.env.ELECTRON_RENDERER_URL)
} else {
mainWindow.loadFile(path.join(__dirname, '../../index.html'))
}
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
// Set app user model id for windows
electronApp.setAppUserModelId('com.electron')
// Default open or close DevTools by F12 in development
// and ignore CommandOrControl + R in production.
// see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
app.on('browser-window-created', (_, window) => {
optimizer.watchWindowShortcuts(window)
})
createWindow()
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
// In this file you can include the rest of your app"s specific main process
// code. You can also put them in separate files and require them here.
import { ElectronAPI } from '@electron-toolkit/preload'
declare global {
interface Window {
electron: ElectronAPI
api: unknown
}
}
import { contextBridge } from 'electron'
import { electronAPI } from '@electron-toolkit/preload'
// Custom APIs for renderer
const api = {}
// Use `contextBridge` APIs to expose Electron APIs to
// renderer only if context isolation is enabled, otherwise
// just add to the DOM global.
if (process.contextIsolated) {
try {
contextBridge.exposeInMainWorld('electron', electronAPI)
contextBridge.exposeInMainWorld('api', api)
} catch (error) {
console.error(error)
}
} else {
// @ts-expect-error (define in dts)
window.electron = electronAPI
// @ts-expect-error (define in dts)
window.api = api
}
......@@ -8,14 +8,14 @@
name="viewport"
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0"
/>
<title><%= title %></title>
<title></title>
<link rel="icon" href="/favicon.ico" />
</head>
<body>
<script>
;(() => {
var htmlRoot = document.getElementById('htmlRoot')
var theme = window.localStorage.getItem('__APP__DARK__MODE__')
let htmlRoot = document.getElementById('htmlRoot')
let theme = window.localStorage.getItem('__APP__DARK__MODE__')
if (htmlRoot && theme) {
htmlRoot.setAttribute('data-theme', theme)
theme = htmlRoot = null
......@@ -150,7 +150,7 @@
<div class="app-loading-dots">
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
</div>
<div class="app-loading-title"><%= title %></div>
<div class="app-loading-title"></div>
</div>
</div>
</div>
......
......@@ -20,11 +20,13 @@
"email": "developer@yiring.com",
"url": "https://yiring.com"
},
"main": "./out/main/index.js",
"scripts": {
"commit": "czg",
"bootstrap": "pnpm install",
"serve": "npm run dev",
"dev": "vite",
"dev:app": "electron-vite dev",
"build": "cross-env NODE_ENV=production vite build && esno ./build/script/postBuild.ts",
"build:test": "cross-env vite build --mode test && esno ./build/script/postBuild.ts",
"build:preview": "cross-env vite build --mode preview && esno ./build/script/postBuild.ts",
......@@ -56,6 +58,8 @@
"dependencies": {
"@ant-design/colors": "^7.0.0",
"@ant-design/icons-vue": "^6.1.0",
"@electron-toolkit/preload": "^1.0.3",
"@electron-toolkit/utils": "^1.0.2",
"@iconify/iconify": "^3.1.0",
"@logicflow/core": "^1.2.1",
"@logicflow/extension": "^1.2.1",
......@@ -102,6 +106,8 @@
"@antfu/eslint-config": "^0.37.0",
"@commitlint/cli": "^17.5.0",
"@commitlint/config-conventional": "^17.4.4",
"@electron-toolkit/tsconfig": "^1.0.1",
"@electron/notarize": "^1.2.3",
"@iconify/json": "^2.2.40",
"@purge-icons/generated": "^0.9.0",
"@types/codemirror": "^5.60.7",
......@@ -136,6 +142,9 @@
"cz-git": "^1.6.1",
"czg": "^1.6.1",
"dotenv": "^16.0.3",
"electron": "^23.2.0",
"electron-builder": "^23.6.0",
"electron-vite": "^1.0.21",
"eslint": "^8.36.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
......
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"noLib": false,
"forceConsistentCasingInFileNames": true,
"allowSyntheticDefaultImports": true,
"strictFunctionTypes": false,
"jsx": "preserve",
"baseUrl": ".",
"allowJs": true,
"sourceMap": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"experimentalDecorators": true,
"lib": ["dom", "esnext"],
"noImplicitAny": false,
"skipLibCheck": true,
"strictNullChecks": false,
"strictPropertyInitialization": false,
"types": ["vite/client"],
"removeComments": true,
"paths": {
"@/*": ["src/*"],
"/@/*": ["src/*"],
"/#/*": ["types/*"]
}
"esModuleInterop": true
},
"include": [
"tests/**/*.ts",
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
"types/**/*.d.ts",
"types/**/*.ts",
"build/**/*.ts",
"build/**/*.d.ts",
"mock/**/*.ts",
"vite.config.ts"
],
"exclude": ["node_modules", "tests/server/**/*.ts", "dist", "**/*.js"]
"files": [],
"references": [{ "path": "./tsconfig.web.json" }, { "path": "./tsconfig.node.json" }]
}
{
"extends": "@electron-toolkit/tsconfig/tsconfig.node.json",
"compilerOptions": {
"composite": true,
"baseUrl": ".",
"paths": {
"/#/*": ["types/*"]
}
},
"include": ["package.json", "electron", "build", "vite.config.*", "electron.vite.config.*", "node_modules"]
}
{
"extends": "@electron-toolkit/tsconfig/tsconfig.web.json",
"compilerOptions": {
"composite": true,
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"noLib": false,
"forceConsistentCasingInFileNames": true,
"allowSyntheticDefaultImports": true,
"strictFunctionTypes": false,
"jsx": "preserve",
"baseUrl": ".",
"allowJs": true,
"sourceMap": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"experimentalDecorators": true,
"lib": ["dom", "esnext"],
"noImplicitAny": false,
"skipLibCheck": true,
"strictNullChecks": false,
"strictPropertyInitialization": false,
"types": ["vite/client"],
"removeComments": true,
"paths": {
"@/*": ["src/*"],
"/@/*": ["src/*"],
"/#/*": ["types/*"]
}
},
"include": [
"tests/**/*.ts",
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
"types/**/*.d.ts",
"types/**/*.ts",
"build/**/*.ts",
"build/**/*.d.ts",
"mock/**/*.ts",
"vite.config.ts"
],
"exclude": ["node_modules", "tests/server/**/*.ts", "dist", "**/*.js"]
}
import type { UserConfig, ConfigEnv } from 'vite'
import pkg from './package.json'
import dayjs from 'dayjs'
import { resolve } from 'node:path'
import type { ConfigEnv, UserConfig } from 'vite'
import { loadEnv } from 'vite'
import { resolve } from 'path'
import dayjs from 'dayjs'
import pkg from './package.json'
import { generateModifyVars } from './build/generate/generateModifyVars'
import { createProxy } from './build/vite/proxy'
import { wrapperEnv } from './build/utils'
......@@ -43,12 +43,12 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
// /@/xxxx => src/xxxx
{
find: /\/?@\//,
replacement: pathResolve('src') + '/',
replacement: `${pathResolve('src')}/`,
},
// /#/xxxx => types/xxxx
{
find: /\/#\//,
replacement: pathResolve('types') + '/',
replacement: `${pathResolve('types')}/`,
},
],
},
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论