Coder Social home page Coder Social logo

vite-electron-plugin's Introduction

vite-electron-plugin

High-performance, esbuild-based Vite Electron plugin

NPM version NPM Downloads

  • 🚀 High-performance (Not Bundle, based on esbuild)
  • 🎯 Support Plugin (Like Vite's plugin)
  • 🌱 What you see is what you get
  • 🔥 Hot restart

Quick Setup

  1. Add dependency to project
npm i -D vite-electron-plugin
  1. Add vite-electron-plugin into vite.config.ts
import electron from 'vite-electron-plugin'

export default {
  plugins: [
    electron({
      include: [
        // The Electron source codes directory
        'electron',
      ],
    }),
  ],
}
  1. Create electron/main.ts and type the following code
import { app, BrowserWindow } from 'electron'

app.whenReady().then(() => {
  const win = new BrowserWindow()

  if (process.env.VITE_DEV_SERVER_URL) {
    win.loadURL(process.env.VITE_DEV_SERVER_URL)
  } else {
    win.loadFile('dist/index.html')
  }
})
  1. Add entry into package.json
{
+ "main": "dist-electron/main.js"
}

Recommend Structure

Let's use the official template-vanilla-ts created based on create vite as an example

+ ├─┬ electron
+ │ └── main.ts
  ├─┬ src
  │ ├── main.ts
  │ ├── style.css
  │ └── vite-env.d.ts
  ├── .gitignore
  ├── favicon.svg
  ├── index.html
  ├── package.json
  ├── tsconfig.json
+ └── vite.config.ts

Conventions

  • Any file ending with reload.ext (e.g. foo.reload.js, preload.ts) after an update,
    will trigger a reload of the Electron-Renderer process, instead of an entire Electron App restart.
    Which is useful when updating Preload-Scripts.

Configuration

electron(config: Configuration)
Key Type Description Required Default
include Array directory or filename or glob Array.
Must be a relative path, which will be calculated based on the root.
If it is an absolute path, it can only be a subpath of root.
Otherwise it will cause the output file path to be calculated incorrectly.
root string process.cwd()
outDir string Output Directory. dist-electron
api Record<string, any> Useful if you want to pass some payload to the plugin.
plugins Plugin[] See the Plugin API.
logger { [type: string], (...message: string[]) => void } Custom log. If logger is passed, all logs will be input this option
transformOptions import('esbuild').TransformOptions Options of esbuild.transform()
watch import('chokidar').WatchOptions Options of chokidar.watch()

Plugin API

The design of plugin is similar to Vite's plugin. But simpler, only 4 hooks in total.

configResolved

  • Type: (config: ResolvedConfig) => void | Promise<void>
  • Kind: async, sequential

You can freely modify the config argument in ths hooks or use.

onwatch serve only

  • Type: (envet: 'add' | 'change' | 'addDir' | 'unlink' | 'unlinkDir', path: string) => void
  • Kind: async, parallel

Triggered by include file changes. You can emit some files in this hooks. Even restart the Electron App.

transform

  • Type: (args: { filename: string, code: string, done: () => void }) => string | import('esbuild').TransformResult | void | Promise<string | import('esbuild').TransformResult | void>
  • Kind: async, sequential

Triggered by changes in extensions files in include.

ondone

  • Type: (args: { filename: string, distname: string }) => void
  • Kind: async, parallel

Triggered when transform() ends or a file in extensions is removed.

Builtin Plugin

import path from 'node:path'
import electron from 'vite-electron-plugin'
import {
  alias,
  copy,
  dest,
  esmodule,
  customStart,
  loadViteEnv,
} from 'vite-electron-plugin/plugin'

export default {
  plugins: [
    electron({
      plugins: [
        alias([
          // `replacement` is recommented to use absolute path, 
          // it will be automatically calculated as relative path.
          { find: '@', replacement: path.join(__dirname, 'src') },
        ]),

        copy([
          // filename, glob
          { from: 'foo/*.ext', to: 'dest' },
        ]),

        // Dynamic change the build dist path.
        dest((_from, to) => to?.replace('dist-electron', 'dist-other')),

        customStart(({ startup }) => {
          // If you want to control the launch of Electron App yourself.
          startup()
        }),

        // Support use ESM npm-package in Electron-Main.  
        esmodule({
          // e.g. `execa`, `node-fetch`, `got`, etc.
          include: ['execa', 'node-fetch', 'got'],
        }),

        // https://vitejs.dev/guide/env-and-mode.html#env-files
        // Support use `import.meta.env.VITE_SOME_KEY` in Electron-Main
        loadViteEnv(),
      ],
    }),
  ],
}

JavaScript API

import {
  type Configuration,
  type ResolvedConfig,
  type Plugin,
  build,
  watch,
  startup,
  defineConfig,
  default as electron,
} from 'vite-electron-plugin'

Example

// dev
watch({
  include: [
    // The Electron source codes directory
    'electron',
  ],
  plugins: [
    {
      name: 'plugin-electron-startup',
      ondone() {
        // Startup Electron App
        startup()
      },
    },
  ],
})

// build
build({
  include: ['electron'],
})

vite-electron-plugin's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

vite-electron-plugin's Issues

从渲染进程调用ipcRenderer

image
image

从渲染进程import ipcRenderer就无法启动工程和编译工程, 之前的插件我记得有一个选项, 这个插件没有导出可配置的选项吗

resolveConfig outDir path wrong

resolvedRoot :
D:/downloads/front/tailwindcss/react/my-react-app

defaultOutDir :
dist-electron

path.posix.resolve(resolvedRoot, defaultOutDir) :
/downloads/front/tailwindcss/react/my-react-app/D:/downloads/front/tailwindcss/react/my-react-app/dist-electron

So, I suggest replace the "resolve" to "join"
in config.ts line 99.
outDir: path.posix.resolve(resolvedRoot, defaultOutDir),

Error not a directory app.asar/out/main/node_modules/langchain when open the application after built

Thank you for making this plugin for using ESM modules!

After applying the fix you mentioned here, I am getting runtime error ENOTDIR: not a directory, stat '/Applications/electron-app.app/Contents/Resources/app.asar/out/main/node_modules/langchain'

Looks like its not reading the node_modules path correctly?

vite config

import { resolve } from 'path'
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
import react from '@vitejs/plugin-react'
import electron from 'vite-electron-plugin'
import { esmodule } from 'vite-electron-plugin/plugin'

export default defineConfig({
  main: {
    plugins: [externalizeDepsPlugin(), electron({
  include: ['electron'],
  plugins: [
    esmodule({
      include: ['langchain/llms/llama_cpp', 'node-llama-cpp']
    })
  ]
})]
  },
  preload: {
    plugins: [externalizeDepsPlugin()]
  },
  renderer: {
    resolve: {
      alias: {
        '@renderer': resolve('src/renderer/src')
      }
    },
    plugins: [react()]
  }
})

TypeScript Decorators Not Compiling Correctly Despite experimentalDecorators Enabled

First and foremost, thanks for developing this plugin. It has been incredibly useful in the development of personal applications. I truly appreciate the effort and dedication that has gone into making it.

I had an issue where TypeScript decorators were not being compiled correctly, leading to runtime errors. ExperimentalDecorators was enabled in my tsconfig.json but the problem persisted.

When trying to use a decorator named beforeAllDecorator The application threw an uncaught exception as follows:

Uncaught Exception:
@(0, import_utils.beforeAllDecorator)()
^

Workaround:
As a temporary solution, I added a custom transformOptions in vite.config.ts:

electron({
        include: ["electron"],

        transformOptions: {
          sourcemap,
          target: "ESNext",
          tsconfigRaw: {
            compilerOptions: {
              experimentalDecorators: true,
            },
          },
        },
     ........
 }

This change successfully resolved the compilation issue.

Question:
Does the plugin/compiler ignore the settings specified in the tsconfig.json file? I'm trying to understand why my initial configuration did not take effect and if there's a better way to address this issue.

建议npm包的`package.json` 里的 `types` 不要使用 `src` 目录

建议 npm 包的 package.json 里的 types 不要使用 src 目录。

否则用户使用了更严格的tsconfig 时,当 tsc 检查到 import 了此 npm 包的文件,还会检查进此包的 src 目录,从而导致 tsc 失败;且无法排除出去,使用 excludeskipLibCheck 都不起效。

alias插件替换路径错误

如果import的文件存在位置是在同级目录下或者是同级目录文件,就会错误。
如:
/electron/main/index.ts
需要引用来自
/electron/main/win/window.ts
配置为

alias([{
  find: '@M',
  replacement: path.join(__dirname, 'electron/main'),
}]),

在index.ts中,我是这样写
import { test } from "@M/win/windows";
最终转换后得到path /test/windows
实际需要得到的path ./test/windows
缺少一个点

我debug代码后发现是
/plugin/index.ts文件中第49行:
replacement = path.posix.relative(path.dirname(importer), replacement)
这个代码如果是我这种引用同级目录下文件,或者引用同级文件,得到的值都是空字符串。

因为我主业是Java,略懂前端,所以也不知道咋改合适。

Building does not bundle dependencies

Hey, thanks for making this plugin.
During development, it works fine. However, when building, the resulting code did not bundle the dependencies thus, I was getting module not found error. Is it doing that by design? How would I go about solving this issue?
One note is: I was using dynamic imports in my code.

build失败entry file does not exist

npm run dev正常,但是buildb报错,并且没有生成dist-electron目录

• electron-builder  version=23.6.0 os=10.0.19044
  • loaded configuration  file=D:\project\vite-electron-test\electron-vite-vue\electron-builder.json5
  • writing effective config  file=release\2.1.0\builder-effective-config.yaml
  • packaging       platform=win32 arch=x64 electron=21.2.0 appOutDir=release\2.1.0\win-unpacked
  ⨯ Application entry file "dist-electron\main\index.js" in the "D:\project\vite-electron-test\electron-vite-vue\release\2.1.0\win-unpacked\resources\app.asar" does not exist. Seems like a wrong configuration.  failedTask=build stackTrace=Error: Application entry file "dist-electron\main\index.js" in the "D:\project\vite-electron-test\electron-vite-vue\release\2.1.0\win-unpacked\resources\app.asar" does not exist. Seems like a wrong configuration.

environment variables not exposed

image

My setup is:

Electron main in: src/main/main.ts

Config is: include: ["src/main"]

App loads fine, but the environment variables are not exposed. env in import.meta is not typed and doesn't work, only resolve and url

How can I expose environment variables in main.ts and maybe in src/main.tsx?

环境变量获取不到

我在项目根目录下配置了环境变量
1666936165028
1666936329445

但是在electron目录下的代码里用以下两种方式均无法获取
import.meta.env.VITE_SERVER_BASE_API
process.env.VITE_SERVER_BASE_API

Uncaught ReferenceError: module is not defined

I'm a newbee for vite.
Sorry for that I cannot provide full source code to reproduce the issue. Any ideas about the error when startup package which is built by npm run build ?

Uncaught ReferenceError: module is not defined

Missing package after building

Hi,

I have added "electron-devtools-installer": "^3.2.0", to my devDependencies.
At application launch I've got an application error telling electron-devtools-installer is missing.
If I build with electron-devtools-installer added to dependencies instead of devDependencies, it works.

Is there a way to keep the package in the devDependencies and have it working ?
Do I need to do some plugin config for that ?

I have tried : include: ['electron', 'node_modules/electron-devtools-installer'], but it fails

window环境下plugin-alias错误

问题已经解决了一部分,路径解析已经正确了,但是还有问题
我的代码目录如下:
1666925372751
vite配置:
1666925580475
弄完后我提交个pr

How to change location of electron main process code?

I would like to put my main/index.ts under src/, so that I have src/main/index.ts. I tried

  plugins: [
    electron({
-      include: ["electron"],
+      include: ["src/main"] 

and in package.json,

-  "main": "dist-electron/main/index.js",
+  "main": "dist-electron/index.js",

But then electron-dist is not even created.

Can you see what I'm doing wrong? Thanks.

[help] 设置alias后找不到ts模块

alias样例中,我将common/foo.js修改为common/foo.ts,运行后报错:Error: Cannot find module ../common/foo'

想请教一下如何修改配置?是需要在electron启动前把common中的ts编译成js吗?

foo.ts

export const foo = '@common/foo.ts'

main.ts

- import foo from '@common/foo'
+ import { foo } from '@common/foo'

imported method (main process) is undefined

Thanks for the reply in #17!

I have an Electron app and want to define the implementation for an IPC api in another file besides main/index.ts. I defined some functions i.e.

export function helloWorld() {
}

in another file electron/main/ipc/hello-world.ts and import this in main/index.ts (import { helloWorld } from 'electron/main/ipc/hello-world) but the function is undefined at runtime.

Is there any config to support including other code as ESM using this plugin?

this is what my vite config looks like:

plugins: [
    react(),
    electron({
      include: [
        'electron',
      ],
      transformOptions: {
        sourcemap: !!process.env.VSCODE_DEBUG,
      },
      // Will start Electron via VSCode Debug
      plugins: process.env.VSCODE_DEBUG
        ? [customStart(debounce(() => console.log(/* For `.vscode/.debug.script.mjs` */'[startup] Electron App')))]
        : undefined,
    }),
    renderer({
      nodeIntegration: false,
    }),
  ],

feature request: be able to bundle preload script

For security reasons, require is not defined in the special context in which preload scripts run, but it would be useful for preload scripts to be able to share constants (i.e., method names) between preload scripts and IPC implementations for the APIs exposed in preload scripts.

This feature request is to suggest being able to build the preload scripts with esbuild --bundle option so there is no need for require at runtime.

Cannot use import statement outside a module

  • Node v16.17.1
  • NPM v8.15.0
  • OS window

This is the error i get after ff the instructions on the readme file for a quick start example:

(node:24176) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension. (Usenode --trace-warnings ...` to show where the warning was created)

failed to load config from C:\Users\xxxx\Projects\Desktop\svelvitron\vite.config.ts
error when starting dev server:
C:\Users\xxxx\Projects\Desktop\svelvitron\node_modules\vite-electron-plugin\index.js:1
import fs from "fs";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:360:18)
    at wrapSafe (node:internal/modules/cjs/loader:1055:15)
    at Module._compile (node:internal/modules/cjs/loader:1090:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1180:10)
    at Module.load (node:internal/modules/cjs/loader:1004:32)
    at Function.Module._load (node:internal/modules/cjs/loader:839:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:170:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:533:24)

`

Did this plugin change to vite-plugin-electron?

I have this as my current dependency, however it feels like this package got left behind and you started working on a new name one called

vite-plugin-electron
vs
vite-electron-plugin

If that is the case it would be great if you could update the README and point to the new repo with a warning.

Change in acorn package now causes syntax errors when using the alias plugin

First, I really like this plugin so thank you for making it available.

I'm not sure what the underlying cause of this is, but it appears a change in the acorn package will now result in a "Syntax Error" whenever a Class declares a Class Member. For example, declaring the follow class

class Foo {
bar: string;
}

Will now throw this unhelpful error message:

file:///C:/Users/Chris/Documents/test1/node_modules/acorn/dist/acorn.mjs:3554
var err = new SyntaxError(message);
^
SyntaxError: Unexpected token (39:8)
at pp$4.raise (file:///C:/Users/Chris/Documents/test1/node_modules/acorn/dist/acorn.mjs:3554:13)
at pp$9.unexpected (file:///C:/Users/Chris/Documents/test1/node_modules/acorn/dist/acorn.mjs:762:8)
at pp$9.expect (file:///C:/Users/Chris/Documents/test1/node_modules/acorn/dist/acorn.mjs:756:26)
at pp$5.parseMethod (file:///C:/Users/Chris/Documents/test1/node_modules/acorn/dist/acorn.mjs:3309:8)
at pp$8.parseClassMethod (file:///C:/Users/Chris/Documents/test1/node_modules/acorn/dist/acorn.mjs:1523:35)
at pp$8.parseClassElement (file:///C:/Users/Chris/Documents/test1/node_modules/acorn/dist/acorn.mjs:1481:10)
at pp$8.parseClass (file:///C:/Users/Chris/Documents/test1/node_modules/acorn/dist/acorn.mjs:1399:24)
at pp$8.parseStatement (file:///C:/Users/Chris/Documents/test1/node_modules/acorn/dist/acorn.mjs:908:17)
at pp$8.parseTopLevel (file:///C:/Users/Chris/Documents/test1/node_modules/acorn/dist/acorn.mjs:819:21)
at Parser.parse (file:///C:/Users/Chris/Documents/test1/node_modules/acorn/dist/acorn.mjs:591:15) {
pos: 1664,
loc: Position { line: 39, column: 8 },
raisedAt: 1665
}

I found the "alias" plugin uses acorn to parse out the "requires" and "imports" statements, and hardcodes the emcaVersion to 2020. This worked on previous versions of the acorn package but doesn't anymore. I replaced the line
const ast = acorn.parse(code, { ecmaVersion: 2020 });
with
const ast = acorn.parse(code, { ecmaVersion: "latest" });

And the error goes away. It's not a long term solution but at least I can continue development. Hope this saves someone else a day of debugging.

Chris

Application entry file "dist-electron\main\index.js" in the "D:\PhpstormProjects\vite-electron-plugin\release\0.0.0\win-unpacked\resources\app.asar" does not exist.

vite-electron-plugin/examples/quick-start/

error on build

⨯ Application entry file "dist-electron\main\index.js" in the "D:\PhpstormProjects\vite-electron-plugin\release\0.0.0\win-unpacked\resources\app.asar" does not exist. Seems like a wrong configuration.
  failedTask=build stackTrace=Error: Application entry file "dist-electron\main\index.js" in the "D:\PhpstormProjects\vite-electron-plugin\release\0.0.0\win-unpacked\resources\app.asar" does not exist. 
Seems like a wrong configuration.
    at error (D:\PhpstormProjects\vite-electron-plugin\node_modules\app-builder-lib\src\asar\asarFileChecker.ts:7:12)
    at Object.checkFileInArchive (D:\PhpstormProjects\vite-electron-plugin\node_modules\app-builder-lib\src\asar\asarFileChecker.ts:31:11)
    at WinPackager.checkFileInPackage (D:\PhpstormProjects\vite-electron-plugin\node_modules\app-builder-lib\src\platformPackager.ts:503:7)
    at WinPackager.sanityCheckPackage (D:\PhpstormProjects\vite-electron-plugin\node_modules\app-builder-lib\src\platformPackager.ts:551:5)
    at WinPackager.doPack (D:\PhpstormProjects\vite-electron-plugin\node_modules\app-builder-lib\src\platformPackager.ts:312:5)
    at WinPackager.pack (D:\PhpstormProjects\vite-electron-plugin\node_modules\app-builder-lib\src\platformPackager.ts:136:5)
    at Packager.doBuild (D:\PhpstormProjects\vite-electron-plugin\node_modules\app-builder-lib\src\packager.ts:441:9)
    at Object.executeFinally (D:\PhpstormProjects\vite-electron-plugin\node_modules\builder-util\src\promise.ts:12:14)
    at Packager._build (D:\PhpstormProjects\vite-electron-plugin\node_modules\app-builder-lib\src\packager.ts:376:31)
    at Packager.build (D:\PhpstormProjects\vite-electron-plugin\node_modules\app-builder-lib\src\packager.ts:337:12)
    at Object.executeFinally (D:\PhpstormProjects\vite-electron-plugin\node_modules\builder-util\src\promise.ts:12:14)

incorrect config path in `electron-env.d.ts ` causes emitDeclaration to fail

Error

When referencing electron-env.d.ts like so:

/// <reference types="vite-electron-plugin/electron-env" />

Running npx tsc (with or without --emitDeclarationOnly)

node_modules/vite-electron-plugin/electron-env.d.ts:10:30 
- error TS2307: Cannot find module './src/config' or its corresponding type declarations.

10     _resolved_config: import('./src/config').ResolvedConfig

Working fixes:

--  _resolved_config: import('./src/config').ResolvedConfig
++  _resolved_config: import('./types/config').ResolvedConfig

deleting line 10 also works, with no side effects yet

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.