我正在构建一个使用Electron和React的应用程序,在这个应用程序中我需要一个dotenv
文件。在代码中,我使用process.env.variable
来调用我的变量,在开发过程中这很有效。
然而,一旦使用electron-builder
进行分发,dotenv variables
就不再起作用(变成了undefined
)。
我现在的问题是,是否有可能做到这一点,如果可以,怎么做?我试图在互联网上找到解决方案,但似乎人们并没有真正面对这个问题。
我正在构建一个使用Electron和React的应用程序,在这个应用程序中我需要一个dotenv
文件。在代码中,我使用process.env.variable
来调用我的变量,在开发过程中这很有效。
然而,一旦使用electron-builder
进行分发,dotenv variables
就不再起作用(变成了undefined
)。
我现在的问题是,是否有可能做到这一点,如果可以,怎么做?我试图在互联网上找到解决方案,但似乎人们并没有真正面对这个问题。
不确定这个问题是否仍然有效,但以下是我得到的答案,以防有人有同样的问题。如果您正在使用electron-builder
,目前它不支持此功能。
在分发版本中,ENVS不会被加载,因为electron-builder是一个打包工具,而不是一个捆绑工具。 ENVS只会在配置打包步骤时加载。 (来自eletron-builder合作者)
https://github.com/electron-userland/electron-builder/issues/7143
但这并不意味着没有其他方法可以解决,以下是我的一种“不太优雅”的解决方式,我创建了一个脚本来替换用于 electron-builder build --publish
的环境占位符。
我正在使用React样板文件,您的框架可能会有所不同。因此,我创建了一个脚本,在webpack完成将我的TS转译为JS文件时,替换了app/dist/main/main.js
中的env,应该在执行eletron-builder
bash命令之前进行。
以下是我所做的详细内容:
文件夹结构
app
scripts(self-created)
packageEnv.js
...
package.json
:
"scripts": {
"build": "concurrently \"npm run build:main\" \"npm run build:renderer\"",
"package:env": "node ./scripts/packageEnv.js",
"build:main": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.main.prod.ts",
"build:renderer": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.prod.ts",
"package": "ts-node ./.erb/scripts/clean.js dist && npm run build && npm run package:env && electron-builder build --publish never",
"rebuild": "electron-rebuild --parallel --types prod,dev,optional --module-dir release/app",
},
packageEnv.js
的代码(非常混乱,建议阅读并重构)。还在那里放了一些TODO
。
const fs = require('fs');
const splitLineIntoPairs = (line) => {
const firstEqualSymbolPosition = line.search('=');
const key = line.slice(0, firstEqualSymbolPosition).replaceAll(' ', '');
const values = line
.slice(firstEqualSymbolPosition + 1, line.length)
.replaceAll(' ', '');
return {
key,
values,
};
};
const createEnvObj = (envByLines) => {
return envByLines.map((line) => {
const { key, values } = splitLineIntoPairs(line);
return {
key,
values,
};
});
};
const writeEnvToDistApp = ({ path, env }) => {
// TODO: Should make it so that the code read by chunks instead of loading entire file, may encounter memory shortage if file too big atm
let mainJs = fs.readFileSync(path).toString();
env.forEach(({ key, values }) => {
// TODO: Replace with your env variable template
mainJs = mainJs.replace(`process.env.${key}`, `"${values}"`);
});
fs.writeFileSync(path, mainJs);
};
const packageEnv = () => {
const envFileContent = fs.readFileSync('./.env').toString();
const envByLines = envFileContent.split('\n').filter((line) => {
return line !== '';
});
const envObj = createEnvObj(envByLines);
writeEnvToDistApp({
// TODO: Replace with your release app structure
path: './release/app/dist/main/main.js',
env: envObj,
});
};
packageEnv();