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.5.3 to 0.5.4

12

CHANGELOG.md
## [2022-07-10] v0.5.4
- 75b60c2 docs: v0.5.4
- 1b933d2 refactor(๐ŸŒฑ): better logic
## [2022-07-07] v0.5.3
- 69eb531 docs: v0.5.3
- cc98ed9 feat: `ResolveModules['options']` optional
- db03a72 chore: remove `useNodeJs.default = useNodeJs`
- c30dc1b fix(๐Ÿž): add `electron` to ` builtins
## [2022-07-07] v0.5.2

@@ -3,0 +15,0 @@

2

package.json
{
"name": "vite-plugin-electron-renderer",
"version": "0.5.3",
"version": "0.5.4",
"description": "Support use Node.js API in Electron-Renderer",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -9,2 +9,6 @@ const fs = require('fs');

function useNodeJs(options = {}) {
/**
* @type {import('vite').ConfigEnv}
*/
let env;
const builtins = [];

@@ -14,4 +18,38 @@ const dependencies = [];

const CJS_modules = []; // builtins + dependencies
const moduleCache = new Map();
const moduleCache = new Map([
['electron', `
/**
* All exports module see https://www.electronjs.org -> API -> Renderer Process Modules
*/
const electron = require("electron");
const {
clipboard,
nativeImage,
shell,
contextBridge,
crashReporter,
ipcRenderer,
webFrame,
desktopCapturer,
deprecate,
} = electron;
export {
electron as default,
clipboard,
nativeImage,
shell,
contextBridge,
crashReporter,
ipcRenderer,
webFrame,
desktopCapturer,
deprecate,
}`],
]);
// When `electron` files or folders exist in the root directory, it will cause Vite to incorrectly splicing the `/@fs/` prefix.
// Here, use `\0` prefix avoid this behavior
const prefix = '\0';
return {

@@ -22,27 +60,17 @@ name: 'vite-plugin-electron-renderer:use-node.js',

// ๐Ÿšง Must be use config hook
config(config, env) {
config(config, _env) {
env = _env;
if (env.command === 'serve') {
// Vite ---- resolve.alias ----
if (!config.resolve) config.resolve = {};
// TODO: Compatible ESM module
// If the package is ESM module, like node-fetch
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 = [];
if (!config.optimizeDeps.exclude.includes('electron')) config.optimizeDeps.exclude.push('electron');
config.optimizeDeps.exclude.push('electron');
return config;
}
} else if (env.command === 'build') {
if (env.command === 'build') {
// Rollup ---- init ----

@@ -55,3 +83,2 @@ if (!config.build) config.build = {};

let external = config.build.rollupOptions.external;
const electronBuiltins = CJS_modules.concat('electron');
if (

@@ -62,7 +89,7 @@ Array.isArray(external) ||

) {
external = electronBuiltins.concat(external);
external = CJS_modules.concat(external);
} else if (typeof external === 'function') {
const original = external;
external = function (source, importer, isResolved) {
if (electronBuiltins.includes(source)) {
if (CJS_modules.includes(source)) {
return true;

@@ -73,6 +100,4 @@ }

} else {
external = electronBuiltins;
external = CJS_modules;
}
// make builtin modules & electron external when rollup
config.build.rollupOptions.external = external;

@@ -88,9 +113,13 @@

// external modules such as `electron`, `fs`
// they can only be loaded normally under CommonJs
// they can only be loaded normally on CommonJs
if (output.format === undefined) output.format = 'cjs';
}
return config;
}
},
configResolved(config) {
const resolved = resolveModules(config, options);
builtins.push(...resolved.builtins);

@@ -102,68 +131,61 @@ dependencies.push(...resolved.dependencies);

resolveId(source) {
// TODO: Identify ESM
const id = source.replace('node:', '');
if (CJS_modules.includes(id)) return id;
if (env.command === 'serve') {
if (ESM_deps.includes(source)) return; // by vite-plugin-esmodule
if (CJS_modules.includes(source)) return prefix + source;
}
},
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 (env.command === 'serve') {
/**
* ```
* ๐ŸŽฏ Using Node.js packages(CJS) in Electron-Renderer(vite serve)
*
* โ”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ”“ โ”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ”“
* โ”‚ import { readFile } from 'fs' โ”‚ โ”‚ Vite dev server โ”‚
* โ”—โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ”› โ”—โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ”›
* โ”‚ โ”‚
* โ”‚ 1. HTTP(Request): fs module โ”‚
* โ”‚ โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”> โ”‚
* โ”‚ โ”‚
* โ”‚ โ”‚
* โ”‚ 2. Intercept in load-hook(vite-plugin-electron-renderer) โ”‚
* โ”‚ 3. Generate a virtual module(fs) โ”‚
* โ”‚ โ†“ โ”‚
* โ”‚ const _M_ = require('fs') โ”‚
* โ”‚ export const readFile = _M_.readFile โ”‚
* โ”‚ โ”‚
* โ”‚ โ”‚
* โ”‚ 4. HTTP(Response): fs module โ”‚
* โ”‚ <โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” โ”‚
* โ”‚ โ”‚
* โ”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ”“ โ”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ”“
* โ”‚ import { readFile } from 'fs' โ”‚ โ”‚ Vite dev server โ”‚
* โ”—โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ”› โ”—โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ”›
*
* ```
*/
if (CJS_modules.includes(id)) {
const cache = moduleCache.get(id);
if (cache) return cache;
id = id.replace(prefix, '')
if (CJS_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();
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;
moduleCache.set(id, nodeModuleCodeSnippet);
return nodeModuleCodeSnippet;
}
}
},

@@ -189,6 +211,6 @@ };

const pkg = require(pkgId);
for (const package of Object.keys(pkg.dependencies || {})) {
for (const npmPkg of Object.keys(pkg.dependencies || {})) {
const _pkgId = lookupFile(
'package.json',
[root, cwd].map(r => `${r}/node_modules/${package}`),
[root, cwd].map(r => `${r}/node_modules/${npmPkg}`),
);

@@ -198,3 +220,3 @@ if (_pkgId) {

if (_pkg.type === 'module') {
ESM_deps.push(package);
ESM_deps.push(npmPkg);
continue;

@@ -205,3 +227,3 @@ }

// TODO: Nested package name, but you can explicity include it by `options.resolve`
dependencies.push(package);
dependencies.push(npmPkg);
}

@@ -232,2 +254,4 @@ }

useNodeJs.resolveModules = resolveModules;
// useNodeJs.default = useNodeJs;
// โ†“
// Function {

@@ -240,3 +264,2 @@ // default: <ref *1> [Function: useNodeJs] {

// }
// useNodeJs.default = useNodeJs;
module.exports = useNodeJs;

@@ -69,2 +69,3 @@ # vite-plugin-electron-renderer

<!--
###### Electron-Main

@@ -74,7 +75,6 @@

import { readFile } from 'fs'
import { ipcRenderer } from 'electron'
โ†“
const { readFile } = require('fs')
const { ipcRenderer } = require('electron')
```
-->

@@ -85,6 +85,4 @@ ###### Electron-Renderer(vite build)

import { readFile } from 'fs'
import { ipcRenderer } from 'electron'
โ†“
const { readFile } = require('fs')
const { ipcRenderer } = require('electron')
```

@@ -118,29 +116,13 @@

[๐Ÿ‘‰ See Vite loading Node.js package source code.](https://github.com/electron-vite/vite-plugin-electron-renderer/blob/2bb38a1dbd50b462d33cbc314bb5db71119b52cf/plugins/use-node.js/index.js#L91)
## ๐Ÿšจ Node.js ESM packages
```js
import { ipcRenderer } from 'electron'
โ†“
// Actually redirect via `resolve.alias`
import { ipcRenderer } from 'vite-plugin-electron-renderer/plugins/use-node.js/electron-renderer.js'
```
**e.g.** `node-fetch` `execa` `got` ...
## ๐Ÿšจ ESM packages
In general, Node.js ESM packages only need to be converted if they are used in Electron-Renderer, but not in Electron-Main.
**e.g.** `node-fetch` `execa` `got` ...others
*้€šๅธธ็š„๏ผŒๅชๆœ‰ๅœจ Electron-Renderer ไธญไฝฟ็”จ็š„ๆƒ…ๅ†ตไธ‹ๆ‰้œ€่ฆ่ฝฌๆข Node.js ESM ๆจกๅ—๏ผŒ่€Œๅœจ Electron-Main ไธญไฝฟ็”จๅˆ™ไธๅฟ…่ฝฌๆขใ€‚*
1. `npm i vite-plugin-esmodule -D`
2. Configure in vite.config.ts
1. Use [vite-plugin-esmodule](https://github.com/vite-plugin/vite-plugin-esmodule) to load ESM packages
2. It is recommended to put the ESM packages in the `devDependencies`
```ts
import esmodule from 'vite-plugin-esmodule'
export default {
plugins: [
esmodule(['got', 'execa', 'node-fetch']),
],
}
```
[๐Ÿ‘‰ See electron-renderer.js](https://github.com/electron-vite/vite-plugin-electron-renderer/blob/main/plugins/use-node.js/electron-renderer.js)
## How to work

@@ -150,17 +132,12 @@

###### Config presets
## Config presets
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.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.
3. Add Electron and Node.js built-in modules to Rollup `output.external` option in the `vite build` phase.
- `base = './'`
- `build.assetsDir = ''` -> *TODO: Support nested dir*
- `build.emptyOutDir = false`
- `build.cssCodeSplit = false`
- `build.rollupOptions.output.format = 'cjs'`
- `resolve.conditions = ['node']`
- `optimizeDeps.exclude = ['electron']` - always
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