vite-plugin-electron-renderer
Advanced tools
Comparing version 0.4.1 to 0.5.0
## [2022-06-28] v0.5.0 | ||
- 6f3d745 fix(🐞): `require('fs')` | ||
- 53845da feat: `config.build.emptyOutDir=false` | ||
- 7cf9deb electron-renderer.js -> plugins/use-node.js/electron-renderer.js | ||
- 7d537d5 docs: v0.5.0 | ||
- 2966399 refactor: standalone plugins | ||
- ac356f2 feat: `vite-plugin-electron-renderer:use-node.js` | ||
- 9798acd feat: `vite-plugin-electron-renderer:polyfill-exports` | ||
- 0948df9 feat: `vite-plugin-electron-renderer:build-config` | ||
- 9fb0e03 docs: update | ||
- b6ec453 Update README.md | ||
- 32acf9a docs: update | ||
- d277390 docs: update | ||
## [2022-06-27] v0.4.1 | ||
- a7a41a4 docs: v0.4.1 | ||
- 62b7584 feat: try resolve `package.json` from `process.cwd()` | ||
## [2022-06-26] v0.4.0 | ||
@@ -3,0 +23,0 @@ |
import { Plugin } from 'vite'; | ||
import { Options as UseNodeJsOptions } from './plugins/use-node.js'; | ||
@@ -6,9 +7,3 @@ declare const electronRenderer: VitePluginElectronRenderer; | ||
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 Options extends UseNodeJsOptions { } | ||
@@ -15,0 +10,0 @@ export interface VitePluginElectronRenderer { |
215
index.js
@@ -1,4 +0,4 @@ | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const { builtinModules } = require('module'); | ||
const buildConfig = require('./plugins/build-config'); | ||
const polyfillExports = require('./plugins/polyfill-exports'); | ||
const useNodeJs = require('./plugins/use-node.js'); | ||
@@ -9,210 +9,7 @@ /** | ||
module.exports = function renderer(options = {}) { | ||
const name = 'vite-plugin-electron-renderer'; | ||
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}:node.js`, | ||
enforce: 'pre', | ||
configResolved(config) { | ||
// Resolve package.json dependencies | ||
let pkgId = path.join(config.root, 'package.json'); | ||
if (!fs.existsSync(pkgId)) { | ||
pkgId = path.join(process.cwd(), '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 | ||
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 === 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 = {}; | ||
// 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 { | ||
external = electronBuiltins; | ||
} | ||
// make builtin modules & electron external when rollup | ||
config.build.rollupOptions.external = external; | ||
// 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 { | ||
// 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']; | ||
// 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'); | ||
} | ||
}, | ||
}, | ||
buildConfig(), | ||
polyfillExports(), | ||
useNodeJs(options), | ||
]; | ||
}; |
{ | ||
"name": "vite-plugin-electron-renderer", | ||
"version": "0.4.1", | ||
"version": "0.5.0", | ||
"description": "Support use Node.js API in Electron-Renderer", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -52,13 +52,13 @@ # vite-plugin-electron-renderer | ||
## dependencies vs devDependencies | ||
## `dependencies` vs `devDependencies` | ||
The simplest way | ||
**The easiest way** | ||
- Node.js package in `dependencies` of `package.josn` | ||
- Web package in `devDependencies` of `package.josn` | ||
- Put Node.js packages in `dependencies` | ||
- Put Web packages in `devDependencies` | ||
In general, Vite may not be able to correctly build Node.js packages, especially C/C++ native modules, but Vite can load them as external packages. | ||
*通常的,Vite 可能不能正确的构建 Node.js 的包,尤其是 C/C++ 原生模块,但是 Vite 可以将它们以外部包的形式加载。* | ||
In general, Vite may not correctly build Node.js packages, especially C/C++ native modules, but Vite can load them as external packages. So, put your Node.js package in `dependencies`. Unless you know how to properly build them with Vite. | ||
*通常的,Vite 可能不能正确的构建 Node.js 的包,尤其是 C/C++ 原生模块,但是 Vite 可以将它们以外部包的形式加载。所以,请将 Node.js 包放到 `dependencies` 中。除非你知道如何用 Vite 正确的构建它们。* | ||
e.g. | ||
**e.g.** | ||
@@ -78,3 +78,3 @@ Electron-Main | ||
↓ | ||
// Generate a virtual module by vite-plugin-reaolve | ||
// Generate a virtual module by load-hook | ||
const electron = require('electron') | ||
@@ -88,2 +88,4 @@ export const ipcRenderer = electron.ipcRenderer | ||
[See more about Vite loading Node.js package 👉](https://github.com/electron-vite/vite-plugin-electron-renderer/blob/32acf9a0ed2143a4f05cbbce351b26c01f488490/index.js#L45) | ||
## How to work | ||
@@ -109,3 +111,3 @@ | ||
* `build.assetsDir = ''` -> *TODO: Automatic splicing `build.assetsDir`* | ||
* `build.emptyOutDir = false` | ||
* ~~`build.emptyOutDir = false`~~ | ||
* `build.cssCodeSplit = false` | ||
@@ -112,0 +114,0 @@ * `build.rollupOptions.output.format = 'cjs'` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
16473
13
294
117
1