From dc73cde5c0ab32377cc454e0bc9bf1e87b22e55b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8D=89=E9=9E=8B=E6=B2=A1=E5=8F=B7?= <308487730@qq.com> Date: Fri, 3 Mar 2023 20:40:29 +0800 Subject: [PATCH] feat(template): add vite-typescript template --- .../template/vite-typescript/.eslintignore | 1 + .../template/vite-typescript/package.json | 31 +++++++++ .../src/ViteTypeScriptTemplate.ts | 67 +++++++++++++++++++ .../vite-typescript/tmpl/.eslintrc.json | 16 +++++ .../vite-typescript/tmpl/forge.config.ts | 37 ++++++++++ .../template/vite-typescript/tmpl/main.ts | 58 ++++++++++++++++ .../vite-typescript/tmpl/package.json | 7 ++ .../template/vite-typescript/tmpl/preload.ts | 2 + .../template/vite-typescript/tmpl/renderer.ts | 31 +++++++++ .../vite-typescript/tmpl/tsconfig.json | 19 ++++++ .../vite-typescript/tmpl/vite.main.config.ts | 4 ++ .../tmpl/vite.preload.config.ts | 4 ++ .../tmpl/vite.renderer.config.ts | 4 ++ 13 files changed, 281 insertions(+) create mode 100644 packages/template/vite-typescript/.eslintignore create mode 100644 packages/template/vite-typescript/package.json create mode 100644 packages/template/vite-typescript/src/ViteTypeScriptTemplate.ts create mode 100644 packages/template/vite-typescript/tmpl/.eslintrc.json create mode 100644 packages/template/vite-typescript/tmpl/forge.config.ts create mode 100644 packages/template/vite-typescript/tmpl/main.ts create mode 100644 packages/template/vite-typescript/tmpl/package.json create mode 100644 packages/template/vite-typescript/tmpl/preload.ts create mode 100644 packages/template/vite-typescript/tmpl/renderer.ts create mode 100644 packages/template/vite-typescript/tmpl/tsconfig.json create mode 100644 packages/template/vite-typescript/tmpl/vite.main.config.ts create mode 100644 packages/template/vite-typescript/tmpl/vite.preload.config.ts create mode 100644 packages/template/vite-typescript/tmpl/vite.renderer.config.ts diff --git a/packages/template/vite-typescript/.eslintignore b/packages/template/vite-typescript/.eslintignore new file mode 100644 index 0000000000..14e485a5bc --- /dev/null +++ b/packages/template/vite-typescript/.eslintignore @@ -0,0 +1 @@ +tmpl diff --git a/packages/template/vite-typescript/package.json b/packages/template/vite-typescript/package.json new file mode 100644 index 0000000000..a9a2041430 --- /dev/null +++ b/packages/template/vite-typescript/package.json @@ -0,0 +1,31 @@ +{ + "name": "@electron-forge/template-vite-typescript", + "version": "6.1.0", + "description": "Vite-TypeScript template for Electron Forge, gets you started with Vite really quickly", + "repository": { + "type": "git", + "url": "https://github.com/electron/forge", + "directory": "packages/template/vite-typescript" + }, + "author": "caoxiemeihao", + "license": "MIT", + "main": "dist/ViteTypeScriptTemplate.js", + "typings": "dist/ViteTypeScriptTemplate.d.ts", + "scripts": { + "test": "mocha --config ../../../.mocharc.js test/**/*_spec_slow.ts" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "dependencies": { + "@electron-forge/shared-types": "6.0.5", + "@electron-forge/template-base": "6.0.5", + "fs-extra": "^10.0.0" + }, + "devDependencies": { + "@electron-forge/core-utils": "6.0.5", + "@electron-forge/test-utils": "6.0.5", + "chai": "^4.3.3", + "fast-glob": "^3.2.7" + } +} diff --git a/packages/template/vite-typescript/src/ViteTypeScriptTemplate.ts b/packages/template/vite-typescript/src/ViteTypeScriptTemplate.ts new file mode 100644 index 0000000000..09870da2b5 --- /dev/null +++ b/packages/template/vite-typescript/src/ViteTypeScriptTemplate.ts @@ -0,0 +1,67 @@ +import path from 'path'; + +import { ForgeListrTaskDefinition, InitTemplateOptions } from '@electron-forge/shared-types'; +import { BaseTemplate } from '@electron-forge/template-base'; +import fs from 'fs-extra'; + +class ViteTypeScriptTemplate extends BaseTemplate { + public templateDir = path.resolve(__dirname, '..', 'tmpl'); + + public async initializeTemplate(directory: string, options: InitTemplateOptions): Promise { + const superTasks = await super.initializeTemplate(directory, options); + return [ + ...superTasks, + { + title: 'Setting up Forge configuration', + task: async () => { + await this.copyTemplateFile(directory, 'forge.config.ts'); + await fs.remove(path.resolve(directory, 'forge.config.js')); + }, + }, + { + title: 'Setting up Vite configuration', + task: async () => { + // Copy Vite files + await this.copyTemplateFile(directory, 'vite.main.config.ts'); + await this.copyTemplateFile(directory, 'vite.renderer.config.ts'); + await this.copyTemplateFile(directory, 'vite.preload.config.ts'); + + // Copy tsconfig with a small set of presets + await this.copyTemplateFile(directory, 'tsconfig.json'); + + // Copy eslint config with recommended settings + await this.copyTemplateFile(directory, '.eslintrc.json'); + + // Remove index.js and replace with index.ts + await fs.remove(path.join(directory, 'src', 'index.js')); + await this.copyTemplateFile(path.join(directory, 'src'), 'main.ts'); + + await this.copyTemplateFile(path.join(directory, 'src'), 'renderer.ts'); + + // Remove preload.js and replace with preload.ts + await fs.remove(path.join(directory, 'src', 'preload.js')); + await this.copyTemplateFile(path.join(directory, 'src'), 'preload.ts'); + + // TODO: Compatible with any path entry. + // Vite uses index.html under the root path as the entry point. + fs.moveSync(path.join(directory, 'src', 'index.html'), path.join(directory, 'index.html')); + await this.updateFileByLine(path.join(directory, 'index.html'), (line) => { + if (line.includes('link rel="stylesheet"')) return ''; + if (line.includes('')) return ' \n '; + return line; + }); + + // update package.json entry point + const pjPath = path.resolve(directory, 'package.json'); + const currentPJ = await fs.readJson(pjPath); + currentPJ.main = '.vite/build/main.js'; + await fs.writeJson(pjPath, currentPJ, { + spaces: 2, + }); + }, + }, + ]; + } +} + +export default new ViteTypeScriptTemplate(); diff --git a/packages/template/vite-typescript/tmpl/.eslintrc.json b/packages/template/vite-typescript/tmpl/.eslintrc.json new file mode 100644 index 0000000000..2d7aa60744 --- /dev/null +++ b/packages/template/vite-typescript/tmpl/.eslintrc.json @@ -0,0 +1,16 @@ +{ + "env": { + "browser": true, + "es6": true, + "node": true + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:import/recommended", + "plugin:import/electron", + "plugin:import/typescript" + ], + "parser": "@typescript-eslint/parser" +} diff --git a/packages/template/vite-typescript/tmpl/forge.config.ts b/packages/template/vite-typescript/tmpl/forge.config.ts new file mode 100644 index 0000000000..ec2b06b858 --- /dev/null +++ b/packages/template/vite-typescript/tmpl/forge.config.ts @@ -0,0 +1,37 @@ +import type { ForgeConfig } from '@electron-forge/shared-types'; +import { MakerSquirrel } from '@electron-forge/maker-squirrel'; +import { MakerZIP } from '@electron-forge/maker-zip'; +import { MakerDeb } from '@electron-forge/maker-deb'; +import { MakerRpm } from '@electron-forge/maker-rpm'; +import { VitePlugin } from '@electron-forge/plugin-vite'; + +const config: ForgeConfig = { + packagerConfig: {}, + rebuildConfig: {}, + makers: [new MakerSquirrel({}), new MakerZIP({}, ['darwin']), new MakerRpm({}), new MakerDeb({})], + plugins: [ + new VitePlugin({ + // `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.ts', + config: 'vite.main.config.ts', + }, + { + entry: 'src/preload.ts', + config: 'vite.preload.config.ts', + }, + ], + renderer: [ + { + name: 'main_window', + config: 'vite.renderer.config.ts', + }, + ], + }), + ], +}; + +export default config; diff --git a/packages/template/vite-typescript/tmpl/main.ts b/packages/template/vite-typescript/tmpl/main.ts new file mode 100644 index 0000000000..2110ba0ff8 --- /dev/null +++ b/packages/template/vite-typescript/tmpl/main.ts @@ -0,0 +1,58 @@ +import { app, BrowserWindow } from 'electron'; +import path from 'path'; +// 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). +declare const MAIN_WINDOW_VITE_DEV_SERVER_URL: string; +declare const MAIN_WINDOW_VITE_NAME: string; + +// Handle creating/removing shortcuts on Windows when installing/uninstalling. +if (require('electron-squirrel-startup')) { + app.quit(); +} + +const createWindow = () => { + // Create the browser window. + const mainWindow = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + preload: path.join(__dirname, 'preload.js'), + }, + }); + + // and load the index.html of the app. + if (MAIN_WINDOW_VITE_DEV_SERVER_URL) { + mainWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL); + } else { + mainWindow.loadFile(path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`)); + } + + // Open the DevTools. + mainWindow.webContents.openDevTools(); +}; + +// 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.on('ready', 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(); + } +}); + +app.on('activate', () => { + // On OS X 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(); + } +}); + +// 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 import them here. diff --git a/packages/template/vite-typescript/tmpl/package.json b/packages/template/vite-typescript/tmpl/package.json new file mode 100644 index 0000000000..a3723d7136 --- /dev/null +++ b/packages/template/vite-typescript/tmpl/package.json @@ -0,0 +1,7 @@ +{ + "devDependencies": { + "@electron-forge/plugin-vite": "ELECTRON_FORGE/VERSION", + "ts-node": "^10.0.0", + "typescript": "~4.5.4" + } +} diff --git a/packages/template/vite-typescript/tmpl/preload.ts b/packages/template/vite-typescript/tmpl/preload.ts new file mode 100644 index 0000000000..5e9d369cc9 --- /dev/null +++ b/packages/template/vite-typescript/tmpl/preload.ts @@ -0,0 +1,2 @@ +// See the Electron documentation for details on how to use preload scripts: +// https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts diff --git a/packages/template/vite-typescript/tmpl/renderer.ts b/packages/template/vite-typescript/tmpl/renderer.ts new file mode 100644 index 0000000000..d75993cde8 --- /dev/null +++ b/packages/template/vite-typescript/tmpl/renderer.ts @@ -0,0 +1,31 @@ +/** + * This file will automatically be loaded by vite and run in the "renderer" context. + * To learn more about the differences between the "main" and the "renderer" context in + * Electron, visit: + * + * https://electronjs.org/docs/tutorial/application-architecture#main-and-renderer-processes + * + * By default, Node.js integration in this file is disabled. When enabling Node.js integration + * in a renderer process, please be aware of potential security implications. You can read + * more about security risks here: + * + * https://electronjs.org/docs/tutorial/security + * + * To enable Node.js integration in this file, open up `main.ts` and enable the `nodeIntegration` + * flag: + * + * ``` + * // Create the browser window. + * mainWindow = new BrowserWindow({ + * width: 800, + * height: 600, + * webPreferences: { + * nodeIntegration: true + * } + * }); + * ``` + */ + +import './index.css'; + +console.log('👋 This message is being logged by "renderer.ts", included via Vite'); diff --git a/packages/template/vite-typescript/tmpl/tsconfig.json b/packages/template/vite-typescript/tmpl/tsconfig.json new file mode 100644 index 0000000000..92db0d6da1 --- /dev/null +++ b/packages/template/vite-typescript/tmpl/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ES6", + "allowJs": true, + "module": "commonjs", + "skipLibCheck": true, + "esModuleInterop": true, + "noImplicitAny": true, + "sourceMap": true, + "baseUrl": ".", + "outDir": "dist", + "moduleResolution": "node", + "resolveJsonModule": true, + "paths": { + "*": ["node_modules/*"] + } + }, + "include": ["src/**/*"] +} diff --git a/packages/template/vite-typescript/tmpl/vite.main.config.ts b/packages/template/vite-typescript/tmpl/vite.main.config.ts new file mode 100644 index 0000000000..690be5b1a9 --- /dev/null +++ b/packages/template/vite-typescript/tmpl/vite.main.config.ts @@ -0,0 +1,4 @@ +import { defineConfig } from 'vite'; + +// https://vitejs.dev/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 new file mode 100644 index 0000000000..690be5b1a9 --- /dev/null +++ b/packages/template/vite-typescript/tmpl/vite.preload.config.ts @@ -0,0 +1,4 @@ +import { defineConfig } from 'vite'; + +// https://vitejs.dev/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 new file mode 100644 index 0000000000..690be5b1a9 --- /dev/null +++ b/packages/template/vite-typescript/tmpl/vite.renderer.config.ts @@ -0,0 +1,4 @@ +import { defineConfig } from 'vite'; + +// https://vitejs.dev/config +export default defineConfig({});