Socket
Socket
Sign inDemoInstall

vite-plugin-electron-renderer

Package Overview
Dependencies
Maintainers
1
Versions
65
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vite-plugin-electron-renderer - npm Package Compare versions

Comparing version 0.1.4 to 0.2.0

41

index.d.ts

@@ -1,2 +0,2 @@

import { Plugin, UserConfig } from 'vite';
import { Plugin } from 'vite';

@@ -6,41 +6,4 @@ declare const electronRenderer: VitePluginElectronRenderer;

export interface Resolve {
[filename: string]: string | (() => string);
}
export interface VitePluginElectronRenderer {
(options?: {
/**
* @example
* {
* resolve: {
* 'electron-store': 'const Store=require("electron-store"); export { Store as default }',
* }
* }
*/
resolve?: Resolve;
}): Plugin;
(): Plugin[];
}
export interface GenerateESModule {
(cacheDir: string, resolve: Resolve): void;
}
export interface ModifyAlias {
(
config: UserConfig,
aliaList: { [moduleId: string]: string; }[],
): void;
}
export interface ModifyOptimizeDepsExclude {
(config: UserConfig, exclude: string[]): void;
}
export interface ModifyRollupExternal {
(config: UserConfig): void;
}
export interface ModifyOptionsForElectron {
(config: UserConfig): void;
}

232

index.js

@@ -1,186 +0,78 @@

const fs = require('fs');
const path = require('path');
const { builtinModules } = require('module');
const optimizer = require('vite-plugin-optimizer');
/** @type {import('.').VitePluginElectronRenderer} */
module.exports = function (options = {}) {
const { resolve } = options;
let root = process.cwd();
/**
* @type {import('.').VitePluginElectronRenderer}
*/
module.exports = function () {
const name = 'vite-plugin-electron-renderer';
const browserExternalId = '__vite-browser-external'
const ElectronRendererModule = path.join(__dirname, 'modules/electron-renderer.js');
const plugin = optimizer(builtinModulesExport(builtinModules), { dir: `.${name}` });
plugin.name = name;
return {
name,
config(config, env) {
if (config.root && path.isAbsolute(config.root)) {
// TODO: config.root is relative path
root = config.root;
}
return [
{
name: `${name}:config`,
config(config) {
// make sure that Electron can be loaded into the local file using `loadFile` after packaging
if (!config.base) config.base = './';
modifyOptionsForElectron(config);
modifyOptimizeDepsExclude(config, ['electron', ...(resolve ? Object.keys(resolve) : [])]);
if (!config.build) config.build = {};
// in 'vite serve' phase ensure the 'electron' and NodeJs built-in modules are loaded correctly by `resolve.alias`
if (env.command === 'serve') {
modifyAlias(config, [{ electron: ElectronRendererModule }]);
}
// in 'vite build' phase insert 'electron' and NodeJs built-in modules into Rollup `output.external`
else if (env.command === 'build') {
modifyRollupExternal(config);
}
// ensure that static resources are loaded normally
if (!config.build.assetsDir) config.build.assetsDir = '';
// generate resolve-module file to `node_modules/.vite-plugin-electron-renderer`
// point resolve-module to this path by `resolve.alias`
if (resolve) {
const cacheDir = path.join(node_modules(root), `.${name}`);
generateESModule(cacheDir, resolve);
modifyAlias(
config,
Object.keys(resolve).map(moduleId => ({ [moduleId]: path.join(cacheDir, moduleId) })),
);
}
},
configureServer(server) {
// intercept node built-in modules require, convert to ESModule respond
server.middlewares.use((req, res, next) => {
if ((req.url || '').includes(browserExternalId)) {
const builtinId = req.url.split(`${browserExternalId}:`, 2)[1];
if (builtinModules.includes(builtinId)) {
const builtinModule = require(builtinId);
const members = Object.keys(builtinModule);
const code = `
const _M = require("${builtinId}");
const {
${members.join(',\n ')}
} = _M;
export { _M as default, ${members.join(', ')} }
`;
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Content-Type', 'application/javascript');
res.setHeader('Cache-Control', 'max-age=3600'); // an hour of cache
res.end(code);
return;
if (!config.build.rollupOptions) config.build.rollupOptions = {};
if (!config.build.rollupOptions.output) config.build.rollupOptions.output = {};
if (Array.isArray(config.build.rollupOptions.output)) {
config.build.rollupOptions.output.forEach(output => {
if (!output.format) {
// the packaged Electron app should use "cjs"
output.format = 'cjs';
}
});
} else {
if (!config.build.rollupOptions.output.format) {
// the packaged Electron app should use "cjs"
config.build.rollupOptions.output.format = 'cjs';
}
}
next();
});
},
};
}
/** @type {import('.').GenerateESModule} */
function generateESModule(cacheDir, resolve) {
// generate custom-resolve module file
for (const [module, strOrFn] of Object.entries(resolve)) {
const moduleId = path.join(cacheDir, module + '.js');
const moduleContent = typeof strOrFn === 'function' ? strOrFn() : strOrFn;
// ----------------------------------------
// supported nest module ('@scope/name')
ensureDir(path.parse(moduleId).dir);
// write custom-resolve
fs.writeFileSync(moduleId, moduleContent);
}
}
if (!config.resolve) config.resolve = {};
if (!config.resolve.alias) config.resolve.alias = [];
const electronjs = path.join(__dirname, 'modules/electron-renderer.js');
/** @type {import('.').ModifyAlias} */
function modifyAlias(config, aliaList) {
if (!config.resolve) config.resolve = {};
if (Array.isArray(config.resolve.alias)) {
config.resolve.alias.push({
find: 'electron',
replacement: electronjs,
});
} else {
config.resolve.alias['electron'] = electronjs;
}
},
},
plugin,
];
};
let alias = config.resolve.alias || [];
if (!Array.isArray(alias)) {
// keep the the original alias
alias = Object.entries(alias).map(([k, v]) => ({ find: k, replacement: v }));
}
alias.push(...aliaList.map(item => {
const [find, replacement] = Object.entries(item)[0];
return { find, replacement };
}));
/**
* @type {(modules: string[]) => Record<string, string>}
*/
function builtinModulesExport(modules) {
return modules.map((moduleId) => {
const nodeModule = require(moduleId)
const requireModule = `const M = require("${moduleId}");`
const exportDefault = `export default M;`
const exportMembers = Object.keys(nodeModule).map(attr => `export const ${attr} = M.${attr}`).join(';\n') + ';'
const nodeModuleCode = `
${requireModule}
${exportDefault}
${exportMembers}
`
config.resolve.alias = alias;
return { [moduleId]: nodeModuleCode }
}).reduce((memo, item) => Object.assign(memo, item), {})
}
/** @type {import('.').ModifyOptimizeDepsExclude} */
function modifyOptimizeDepsExclude(config, exclude) {
if (!config.optimizeDeps) config.optimizeDeps = {};
if (!config.optimizeDeps.exclude) config.optimizeDeps.exclude = [];
config.optimizeDeps.exclude.push(...exclude);
}
/** @type {import('.').ModifyRollupExternal} */
function modifyRollupExternal(config) {
if (!config.build) config.build = {};
if (!config.build.rollupOptions) config.build.rollupOptions = {};
if (!config.build.rollupOptions.external) config.build.rollupOptions.external = [];
let external = config.build.rollupOptions.external;
if (Array.isArray(external)) {
external = ['electron', ...builtinModules, ...external];
} else if (external instanceof RegExp) {
external = ['electron', ...builtinModules, external];
} else if (typeof external === 'string') {
external = ['electron', ...builtinModules, external];
} else if (typeof external === 'function') {
const fn = external;
external = (source, importer, isResolved) => {
if (source === 'electron' || builtinModules.includes(source)) {
return true;
}
return fn.call(fn, source, importer, isResolved);
}
}
config.build.rollupOptions.external = external;
}
/** @type {import('.').ModifyOptionsForElectron} */
function modifyOptionsForElectron(config) {
// electron use `loadFile` load Renderer-process file
if (!config.base) config.base = './';
if (!config.build) config.build = {};
// ensure `require('file-paht')` corre
if (!config.build.assetsDir) config.build.assetsDir = '';
if (!config.build.rollupOptions) config.build.rollupOptions = {};
if (!config.build.rollupOptions.output) config.build.rollupOptions.output = {};
if (Array.isArray(config.build.rollupOptions.output)) {
config.build.rollupOptions.output.forEach(output => {
if (!output.format) {
// the packaged "electron app" should use "cjs"
output.format = 'cjs';
}
});
} else {
if (!config.build.rollupOptions.output.format) {
// the packaged "electron app" should use "cjs"
config.build.rollupOptions.output.format = 'cjs';
}
}
}
// --------- utils ---------
function ensureDir(dir) {
if (!(fs.existsSync(dir) && fs.statSync(dir).isDirectory())) {
fs.mkdirSync(dir, { recursive: true });
}
return dir;
}
function node_modules(root, count = 0) {
if (node_modules.p) {
return node_modules.p;
}
const p = path.join(root, 'node_modules');
if (fs.existsSync(p)) {
return node_modules.p = p;
}
if (count >= 19) {
throw new Error('Can not found node_modules directory.');
}
return node_modules(path.join(root, '..'), count + 1);
}
{
"name": "vite-plugin-electron-renderer",
"version": "0.1.4",
"version": "0.2.0",
"description": "Use Electron and NodeJs API in Renderer-process",

@@ -10,4 +10,6 @@ "main": "index.js",

"license": "MIT",
"dependencies": {
"vite-plugin-optimizer": "^1.1.4"
},
"devDependencies": {
"@types/node": "^16.x",
"vite": "^2.x"

@@ -14,0 +16,0 @@ },

@@ -0,13 +1,22 @@

# vite-plugin-electron-renderer
[![npm package](https://nodei.co/npm/vite-plugin-electron-renderer.png?downloads=true&downloadRank=true&stars=true)](https://www.npmjs.com/package/vite-plugin-electron-renderer)
# Use Electron and NodeJs API in Renderer-process | [简体中文](https://github.com/caoxiemeihao/vite-plugins/blob/main/packages/electron-renderer/README.zh-CN.md)
<br/>
[![NPM version](https://img.shields.io/npm/v/vite-plugin-electron-renderer.svg?style=flat)](https://npmjs.org/package/vite-plugin-electron-renderer)
[![NPM Downloads](https://img.shields.io/npm/dm/vite-plugin-electron-renderer.svg?style=flat)](https://npmjs.org/package/vite-plugin-electron-renderer)
### Example 👉 [electron-vite-boilerplate](https://github.com/caoxiemeihao/electron-vite-boilerplate)
Use Electron and Node.js API in Renderer-process
English | [简体中文](https://github.com/caoxiemeihao/vite-plugins/blob/main/packages/electron-renderer/README.zh-CN.md)
### Usage
## Example 👉 [electron-vite-boilerplate](https://github.com/caoxiemeihao/electron-vite-boilerplate)
## Install
```bash
npm i vite-plugin-electron-renderer -D
```
## Usage
**vite.config.ts**

@@ -26,53 +35,14 @@

**vrenderer/foo.ts**
**renderer.js**
```ts
import { readFile } from 'fs'
import { ipcRenderer } from 'electron'
ipcRenderer.on('event-name', () => {
// somethine code...
})
readFile(/* something code... */)
ipcRenderer.on('event-name', () => {/* something code... */})
```
---
## How to work
### Options.resolve
In some cases, you just want "vite" to load a module like NodeJs.
You can custom-resolve the module **eg:**
**vite.config.ts**
```ts
import { defineConfig } from 'vite'
import electron from 'vite-plugin-electron-renderer'
export default defineConfig({
plugins: [
electron({
resolve: {
// In 'vite serve' phase 'electron-store' will generate file to `node_modules/.vite-plugin-electron-renderer/electron-store.js`
// Then point 'electron-store' to this path through 'resolve.alias'
'electron-store': `const Store=require('electron-store'); export default Store;`;
sqlite3: () => {
// dynamic calculate module exported members
const sqlite3 = require('sqlite3');
const members = Object.keys(sqlite3);
const code = `
const sqlite3 = require("sqlite3");
const { ${members.join(', ')} } = sqlite3;
export { ${members.join(', ')}, sqlite3 as default }
`;
return code;
},
},
}),
],
})
```
---
### How to work
1. Fist, the plugin will configuration something.

@@ -83,25 +53,15 @@

* `base = './'`
* `build.assetsDir = ''`
* `build.assetsDir = ''` -> *TODO: Automatic splicing "build.assetsDir"*
* `build.rollupOptions.output.format = 'cjs'`
- Add "electron", NodeJs built-in modules and "options.resolve" to "optimizeDeps.exclude"
2. The plugin transform Electron and Node.js built-in modules to ESModule format in "vite serve" phase.
```js
{
optimizeDeps: {
exclude: [
'electron',
...'built-in modules',
...Object.keys(options.resolve),
],
},
}
```
3. Add Electron and Node.js built-in modules to Rollup "output.external" option in the "vite build" phase.
2. The plugin transform "electron" and NodeJs built-in modules to ESModule format in "vite serve" phase.
**Using Electron API in Renderer-process** `import { ipcRenderer } from 'electron`
3. Add "electron" and NodeJs built-in modules to Rollup "output.external" option in the "vite build" phase.
Actually redirect to "[node_modules/vite-plugin-electron-renderer/modules/electron-renderer.js](modules/electron-renderer.js)" by `resolve.alias`
**Using electron in Renderer-process** `import { ipcRenderer } from 'electron`
**Using Node.js API in Renderer-process** `import { readFile } from 'fs'`
Actually redirect to "[node_modules/vite-plugin-electron-renderer/modules/electron-renderer.js](modules/electron-renderer.js)" through "resolve.alias".
All Node.js API will be built into the `node_modules/.vite-plugin-electron-renderer` directory by [vite-plugin-optimizer](https://www.npmjs.com/package/vite-plugin-optimizer)

@@ -0,12 +1,21 @@

# vite-plugin-electron-renderer
[![npm package](https://nodei.co/npm/vite-plugin-electron-renderer.png?downloads=true&downloadRank=true&stars=true)](https://www.npmjs.com/package/vite-plugin-electron-renderer)
# 支持在渲染进程中使用 Electron and NodeJs API | [English](https://github.com/caoxiemeihao/vite-plugins/tree/main/packages/electron-renderer#readme)
<br/>
[![NPM version](https://img.shields.io/npm/v/vite-plugin-electron-renderer.svg?style=flat)](https://npmjs.org/package/vite-plugin-electron-renderer)
[![NPM Downloads](https://img.shields.io/npm/dm/vite-plugin-electron-renderer.svg?style=flat)](https://npmjs.org/package/vite-plugin-electron-renderer)
支持在渲染进程中使用 Electron and Node.Js API
[English](https://github.com/caoxiemeihao/vite-plugins/tree/main/packages/electron-renderer#readme) | 简体中文
## 示例 👉 [electron-vite-boilerplate](https://github.com/caoxiemeihao/electron-vite-boilerplate)
### 使用
## 安装
```bash
npm i
## 使用
**vite.config.ts**

@@ -25,53 +34,14 @@

**vrenderer/foo.ts**
**renderer.js**
```ts
import { readFile } from 'fs'
import { ipcRenderer } from 'electron'
ipcRenderer.on('event-name', () => {
// somethine code...
})
readFile(/* something code... */)
ipcRenderer.on('event-name', () => {/* something code... */})
```
---
## 工作原理
### Options.resolve
很多时候, 你只想在 Vite 中用 NodeJs 的方式加载模块
通过 "resolve" 配置实现 **例如:**
**vite.config.ts**
```ts
import { defineConfig } from 'vite'
import electron from 'vite-plugin-electron-renderer'
export default defineConfig({
plugins: [
electron({
resolve: {
// 在 'vite serve' 阶段 'electron-store' 会生成到 `node_modules/.vite-plugin-electron-renderer/electron-store.js` 中
// 然后配置 `resolve.alias` 指向这个路径
'electron-store': `const Store=require('electron-store'); export default Store;`;
sqlite3: () => {
// 动态计算出模块中导出的成员
const sqlite3 = require('sqlite3');
const members = Object.keys(sqlite3);
const code = `
const sqlite3 = require("sqlite3");
const { ${members.join(', ')} } = sqlite3;
export { ${members.join(', ')}, sqlite3 as default }
`;
return code;
},
},
}),
],
})
```
---
### 工作原理
1. 首先,插件会修改一些配置

@@ -85,10 +55,15 @@

- 将 'electron',NodeJs 内置模块和 `options.resolve` 插入到 "optimizeDeps.exclude" 中
- 将 Electron,Node.Js 内置模块和 `options.resolve` 插入到 "optimizeDeps.exclude" 中
2. 开发阶段(`vite serve`) 将 Electron 和 NodeJs 内置模块转换成 ESModule 格式
2. 开发阶段(`vite serve`) 将 Electron 和 Node.Js 内置模块转换成 ESModule 格式
3. 打包阶段(`vite build`) 将 "electron" 和 NodeJs 内置模块插入到 Rollup 的 "output.external" 中
3. 打包阶段(`vite build`) 将 Electron 和 Node.Js 内置模块插入到 Rollup 的 `output.external` 中
**在想染进程中使用 electron** `import { ipcRenderer } from 'electron`
**在染进程中使用 electron** `import { ipcRenderer } from 'electron`
实际上通过 "resolve.alias" 重定向到 "[node_modules/vite-plugin-electron-renderer/modules/electron-renderer.js](modules/electron-renderer.js)"
实际上通过 `resolve.alias` 重定向到 "[node_modules/vite-plugin-electron-renderer/modules/electron-renderer.js](modules/electron-renderer.js)"
**在染进程中使用 Node.js API** `import { readFile } from 'fs'`
所有的 Node.js API 将会通过 [vite-plugin-optimizer](https://www.npmjs.com/package/vite-plugin-optimizer) 构建到 `node_modules/.vite-plugin-electron-renderer` 目录
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc