问题描述
我有一个要求,我们需要根据它是在生产环境中还是在开发环境中执行来设置 dll 路径.所以我决定将该值放在环境变量中,并尝试使用 webpack.DefinePlugin({}) 来实现.
I have a requirement where we need to set dll path based upon whether it is executing in production or in development environment. So I decided to place that value in environment variable and tried to achieve that using webpack.DefinePlugin({}).
方法一:
webpack.config.json
plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV' : JSON.stringify('production') })
然后我尝试在电子的主进程中获取该值,在我的例子中是 elec.js
And then I tried to get that value in electron's main process, In my case elec.js
elec.js
const Electron = require("electron"); const app = require("electron"); var dllPath = ""; function createWindow() { let win = new BrowserWindow({ width: 800, height: 600, title: "Test", icon: "Test.ico" }); win.setMenu(null); win.loadURL( url.format({ pathname: path.join(__dirname, "../renderer/index.html"), protocol: "file:", slashes: true }) ); if (process.env.NODE_ENV ==='production') { dllPath = path.join( __dirname, "./../../dll/test.dll" ); } else { dllPath = path.join( __dirname, "./../../../dll/test.dll" ); } } app.on("ready", createWindow);
但问题是,当我尝试在 createWindow() 函数中访问该值时,它是未定义的,因此流程总是转到 else 块.
But problem is that when I try to access that value in createWindow() function it is undefined so flow always goes to else block.
我有什么遗漏吗?
方法二:
我尝试使用跨环境节点包来实现相同的目标,但没有运气.请在下面找到我尝试使用 cross-env 的代码块.
I tried to achieve the same using cross-env node package, but no luck. Please find below code block which I tried using cross-env.
package.json
"scripts": { "build": "cross-env process.env.NODE_ENV=production && rimraf ./dist/ && webpack --progress && node-sass ./src/renderer/scss/ -o ./dist/renderer/ && rimraf ./dist/renderer/includes/" }
推荐答案
iva2k 提供的洞察力使我能够为同样的问题找到解决方案.
The insight provided by iva2k is what allowed me to come to a solution for this same problem.
使用 dotenv 为我的配置创建一个 .env 文件我到了我想去的地方的一半(设置一些环境变量以在生产环境中使用).然后问题就变成了 Electron 默认没有将那些从 Main 进程传递到 Renderer 进程.
Using dotenv to create a .env file for my config got me halfway to where I wanted to be (setting up a few environment variables for use in a production setting). The problem then became that Electron wasn't passing those from the Main process down to the Renderer process by default.
解决方法很简单:使用 Electron 自己的 ipcMain 和 ipcRenderer 模块在两者之间传递 dotenv 对象.
The work-around is simple: use Electron's own ipcMain and ipcRenderer modules to pass the dotenv object between the two.
在您的主文件(例如您的 elec.js 文件)中,在需要模块后放置一个 ipcMain 事件监听器:
In your main file (e.g. your elec.js file), place an ipcMain event listener after requiring the module:
const config = require('dotenv').config(); const electron = require('electron'); const { app, BrowserWindow, ipcMain } = electron; ... ipcMain.on('get-env', (event) => { event.sender.send('get-env-reply', config); });
在应用程序的渲染端,将其放置在任何需要的地方:
Elsewhere, in your application's rendering-side, place this anywhere necessary:
async function getConfig() { const { ipcRenderer } = window.require('electron'); let config = null; ipcRenderer.on('get-env-reply', (event, arg) => { // The dotenv config object should return an object with // another object inside caled "parsed". Change this if need be. config = arg.parsed; }); ipcRenderer.send('get-env'); return config; }
这基本上允许我在主进程文件中声明一个事件,然后在我想要的任何进程端文件中重新使用它,从而允许我在与构建一起的文件中混淆配置变量,但不是如果不打开开发工具,最终用户将无法访问.
This basically allowed me to declare one event in the Main process file, and then re-use it in any process-side file I wanted, thus allowing me to obfuscate config variables in a file that goes with the build, but isn't accessible to end-users without opening up the dev-tools.