Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

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.3.3 to 0.4.0

CHANGELOG.md

10

index.d.ts

@@ -6,4 +6,12 @@ import { Plugin } from 'vite';

export interface Options {
/**
* Explicitly include/exclude some CJS modules
* `modules` includes `dependencies` of package.json, Node.js's `builtinModules` and `electron`
*/
resolve?: (modules: string[]) => typeof modules | undefined
}
export interface VitePluginElectronRenderer {
(): Plugin[];
(options?: Options): Plugin[];
}

250

index.js

@@ -0,4 +1,4 @@

const fs = require('fs');
const path = require('path');
const { builtinModules } = require('module');
const optimizer = require('vite-plugin-optimizer');

@@ -8,14 +8,130 @@ /**

*/
module.exports = function () {
module.exports = function renderer(options = {}) {
const name = 'vite-plugin-electron-renderer';
const plugin = optimizer(
builtinModulesExport(builtinModules.filter(e => !e.startsWith('_'))),
{ dir: `.${name}` },
);
plugin.name = name;
const builtins = builtinModules.filter(e => !e.startsWith('_')).map(e => [e, `node:${e}`]).flat();
// dependencies of package.json
const dependencies = [];
let modules = [];
const moduleCache = new Map();
/**
* @type {import('vite').ResolvedConfig}
*/
let config;
return [
{
name: `${name}:config`,
name: `${name}:node.js`,
enforce: 'pre',
configResolved(config) {
// Resolve package.json dependencies
const pkgId = path.join(config.root, 'package.json');
if (fs.existsSync(pkgId)) {
const pkg = require(pkgId);
// TODO: Nested package name
dependencies.push(...Object.keys(pkg.dependencies || {}));
}
modules = builtins.concat(dependencies);
if (options.resolve) {
const tmp = options.resolve(modules);
if (tmp) modules = tmp;
}
},
resolveId(source) {
const id = source.replace('node:', '');
if (modules.includes(id)) return id;
},
load(id) {
/**
* ## 🎯 Using Node.js package in Electron-Renderer
*
* Many times, many people want to use the Node.js package in Electron-Renderer, but it may not work correctly in Vite by default.
* 有很多时候很多人想在 Electron-Renderer 中使用 Node.js 模块,但这在 Vite 可能无法正常的构建。
*
* e.g.
* Let's use `serialport` as an example.
* 让我们使用 `serialport` 举个例子 🌰。
*
* ```js
* // ❌ May not work correctly in Vite by default.
* import serialport, { SerialPort, SerialPortMock } from 'serialport';
* ```
*
* At this time, we need to use load-hook to convert `serialport` to ensure that it works normally.
* 这时候我们需要使用 load-hook 转换 `serialport`,以确保它能正常工作。
*
* e.g.
*
* ```js
* // serialport
* const _M_ = require('serialport');
* const _D_ = _M_.default || _M_;
* export { _D_ as default };
* export const SerialPort = _M_.SerialPort;
* export const SerialPortMock = _M_.SerialPortMock;
* ```
*
* Try to use again.
*
* ```js
* // ✅ This looks like nothing has changed, but it works normally after the load-hook converted.
* import serialport, { SerialPort, SerialPortMock } from 'serialport';
* ```
*
* 🚧 It should be noted that the Node.js package, as a dependency of the project, should be placed in `dependencies`; Unless you konw how to build them with Vite.
* 需要注意的一点是,Node.js 模块作为项目的依赖,应该放到 `dependencies` 中;除非你知道如何使用 Vite 构建他们。
*/
if (modules.includes(id)) {
const cache = moduleCache.get(id);
if (cache) return cache;
const nodeModule = require(id);
const requireModule = `const _M_ = require("${id}");`;
const exportDefault = `const _D_ = _M_.default || _M_;\nexport { _D_ as default };`;
const exportMembers = Object
.keys(nodeModule)
.filter(n => n !== 'default')
.map(attr => `export const ${attr} = _M_.${attr};`).join('\n')
const nodeModuleCodeSnippet = `
${requireModule}
${exportDefault}
${exportMembers}
`.trim();
moduleCache.set(id, nodeModuleCodeSnippet);
return nodeModuleCodeSnippet;
}
},
},
{
name: `${name}:serve`,
apply: 'serve',
// 🚧 Must be use config hook
config(config) {
// Vite ---- resolve.alias ----
if (!config.resolve) config.resolve = {};
// TODO: Compatible ESM module
// If the package is ESM module, like node-fetch, execa
if (!config.resolve.conditions) config.resolve.conditions = ['node'];
if (!config.resolve.alias) config.resolve.alias = [];
const electronjs = path.join(__dirname, 'electron-renderer.js');
if (Array.isArray(config.resolve.alias)) {
config.resolve.alias.push({ find: 'electron', replacement: electronjs });
} else {
config.resolve.alias['electron'] = electronjs;
}
// Vite ---- optimizeDeps.exclude ----
if (!config.optimizeDeps) config.optimizeDeps = {};
if (!config.optimizeDeps.exclude) config.optimizeDeps.exclude = [];
config.optimizeDeps.exclude.push('electron');
},
},
{
name: `${name}:build`,
apply: 'build',
config(config) {
// make sure that Electron can be loaded into the local file using `loadFile` after packaging

@@ -25,80 +141,76 @@ if (!config.base) config.base = './';

if (!config.build) config.build = {};
// TODO: Init `config.build.target`
// ensure that static resources are loaded normally
if (!config.build.assetsDir) config.build.assetsDir = '';
if (config.build.assetsDir === undefined) config.build.assetsDir = '';
// https://github.com/electron-vite/electron-vite-vue/issues/107
if (config.build.cssCodeSplit === undefined) config.build.cssCodeSplit = false;
// Rollup ---- init ----
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';
// Rollup ---- external ----
let external = config.build.rollupOptions.external;
const electronBuiltins = modules.concat('electron');
if (
Array.isArray(external) ||
typeof external === 'string' ||
external instanceof RegExp
) {
external = electronBuiltins.concat(external);
} else if (typeof external === 'function') {
const original = external;
external = function (source, importer, isResolved) {
if (electronBuiltins.includes(source)) {
return true;
}
});
return original(source, importer, isResolved);
};
} else {
if (!config.build.rollupOptions.output.format) {
// the packaged Electron app should use "cjs"
config.build.rollupOptions.output.format = 'cjs';
}
external = electronBuiltins;
}
// ----------------------------------------
// make builtin modules & electron external when rollup
config.build.rollupOptions.external = external;
if (!config.resolve) config.resolve = {};
if (!config.resolve.conditions) config.resolve.conditions = ['node'];
if (!config.resolve.alias) config.resolve.alias = [];
const electronjs = path.join(__dirname, 'modules/electron-renderer.js');
if (Array.isArray(config.resolve.alias)) {
config.resolve.alias.push({
find: 'electron',
replacement: electronjs,
});
// Rollup ---- output.format ----
const output = config.build.rollupOptions.output;
if (Array.isArray(output)) {
for (const o of output) {
if (o.format === undefined) o.format = 'cjs';
}
} else {
config.resolve.alias['electron'] = electronjs;
// external modules such as `electron`, `fs`
// they can only be loaded normally under CommonJs
if (output.format === undefined) output.format = 'cjs';
}
},
},
{
name: `${name}:polyfill-exports`,
configResolved(_config) {
config = _config;
},
transformIndexHtml(html) {
const output = config.build.rollupOptions.output;
if (!output) return;
// ----------------------------------------
const formats = ['cjs', 'commonjs'];
if (!config.optimizeDeps) config.optimizeDeps = {};
if (!config.optimizeDeps.exclude) config.optimizeDeps.exclude = [];
config.optimizeDeps.exclude.push('electron');
// https://github.com/electron-vite/vite-plugin-electron/issues/6
// https://github.com/electron-vite/vite-plugin-electron/commit/e6decf42164bc1e3801e27984322c41b9c2724b7#r75138942
if (
Array.isArray(output)
// Once an `output.format` is CJS, it is considered as CommonJs
? output.find(o => formats.includes(o.format))
: formats.includes(output.format)
) {
// fix(🐞): exports is not defined
const polyfill = `<script>var exports = typeof module !== 'undefined' ? module.exports : {};</script>`;
return html.replace(/(<\/[\s]*?head[\s]*?>)/, polyfill + '\n$1');
}
},
},
plugin,
];
};
/**
* @typedef {Record<string, import('vite-plugin-optimizer').ResultDescription>} ExportCollected
* @type {(modules: string[]) => ExportCollected}
*/
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}
`
/**
* @type {ExportCollected}
*/
const collect = {
//
[moduleId]: {
alias: { find: new RegExp(`^(node:)?${moduleId}$`) },
code: nodeModuleCode,
},
};
return collect;
}).reduce((memo, item) => Object.assign(memo, item), {})
}
{
"name": "vite-plugin-electron-renderer",
"version": "0.3.3",
"description": "Use Electron and NodeJs API in Renderer-process",
"version": "0.4.0",
"description": "Support use Node.js API in Electron-Renderer",
"main": "index.js",
"repository": "https://github.com/caoxiemeihao/vite-plugins/tree/main/packages/electron-renderer",
"readme": "https://github.com/caoxiemeihao/vite-plugins/tree/main/packages/electron-renderer#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/electron-vite/vite-plugin-electron-renderer.git"
},
"author": "草鞋没号 <308487730@qq.com>",
"license": "MIT",
"dependencies": {
"vite-plugin-optimizer": "^1.3.2"
},
"scripts": {},
"dependencies": {},
"devDependencies": {
"vite": "^2.x"
"vite": "^2.9.9"
},

@@ -16,0 +17,0 @@ "keywords": [

# vite-plugin-electron-renderer
> 🚧 The package has deprecated. Please use [vite-plugin-electron](https://www.npmjs.com/package/vite-plugin-electron)
Support use Node.js API in Electron-Renderer
```js
import electron from 'vite-plugin-electron/renderer'
```
---
[![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)
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)
**Example 👉 [electron-vite-vue](https://github.com/caoxiemeihao/electron-vite-vue)**
![GitHub stars](https://img.shields.io/github/stars/caoxiemeihao/electron-vite-vue?color=fa6470)
## Install
```bash
```sh
npm i vite-plugin-electron-renderer -D

@@ -29,16 +16,15 @@ ```

**vite.config.ts**
vite.config.ts
```ts
import { defineConfig } from 'vite'
import electron from 'vite-plugin-electron-renderer'
```js
import renderer from 'vite-plugin-electron-renderer'
export default defineConfig({
export default {
plugins: [
electron(),
renderer(/* options */),
],
})
}
```
**renderer.js**
renderer.js

@@ -53,34 +39,44 @@ ```ts

## How to work
## API
- Using Electron API in Renderer-process
`renderer(options: Options)`
```js
import { ipcRenderer } from 'electron'
```ts
export interface Options {
/**
* Explicitly include/exclude some CJS modules
* `modules` includes `dependencies` of package.json, Node.js's `builtinModules` and `electron`
*/
resolve?: (modules: string[]) => typeof modules | undefined
}
```
Actually redirect to "[node_modules/vite-plugin-electron-renderer/modules/electron-renderer.js](modules/electron-renderer.js)" by `resolve.alias`
## How to work
- Using Node.js API in Renderer-process
Using Electron API in Electron-Renderer
```js
import { readFile } from 'fs'
import { ipcRenderer } from 'electron'
// Actually will redirect by `resolve.alias`
import { ipcRenderer } from 'vite-plugin-electron-renderer/electron-renderer.js'
```
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)
[Using Node.js API and package in Electron-Renderer 👉](https://github.com/electron-vite/vite-plugin-electron-renderer/blob/4a2620d9ff9b3696cf55c1c5d4f2acdcf1ff806a/index.js#L37)
#### Config presets
## 🚧 Some additional instructions
1. Fist, the plugin will configuration something.
*If you do not configure the following options, the plugin will modify their default values*
> If you do not configure the following options, the plugin will modify their default values
* `base = './'`
* `build.assetsDir = ''` -> *TODO: Automatic splicing "build.assetsDir"*
* `build.assetsDir = ''` -> *TODO: Automatic splicing `build.assetsDir`*
* `build.emptyOutDir = false`
* `build.cssCodeSplit = false`
* `build.rollupOptions.output.format = 'cjs'`
* `resolve.conditions = ['node']`
* Always insert the `electron` module into `optimizeDeps.exclude`
2. The plugin transform Electron and Node.js built-in modules to ESModule format in "vite serve" phase.
2. The plugin transform Electron and Node.js built-in modules to ESModule format in `vite serve` phase.
3. Add Electron and Node.js built-in modules to Rollup "output.external" option in the "vite build" phase.
3. Add Electron and Node.js built-in modules to Rollup `output.external` option in the `vite build` phase.
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