环境变量在电子中未定义,即使它已在webpack.DefinePlugin中设置
我有一个要求,我们需要根据它是在生产环境还是在开发环境中执行来设置dll路径。所以我决定将该值放在环境变量中并尝试使用webpack.DefinePlugin({})来实现。
方法1:
webpack.config.json
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV' : JSON.stringify('production')
})
然后我试图在电子主过程中得到这个值,在我的情况下是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()函数中访问该值时,它是未定义的,因此flow始终转到else块。
有什么我想念的吗?
方法2:
我尝试使用cross-env节点包实现相同,但没有运气。请在下面找到我尝试使用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/"
}
回答如下:
问题是多方面的。
首先,在加载应用程序之前,您的elec.js由Electron执行。 Electron运行elec.js,它创建浏览器窗口(let win = new BrowserWindow(...)
)并在浏览器进程中加载HTML文件(win.loadURL(...)
),然后HTML加载你的webpack'ed js。因此,elec.js中没有任何webpacked js代码。 webpack的代码也在运行于elec.js之外的另一个进程中。
另外需要注意的是webpack插件不会为它指向的变量创建任何赋值。它通过简单的文本搜索和替换来完成,在您的示例中,process.env.NODE_ENV的所有实例将被替换为webpack的源代码中的“production”字符串。这不是太明显,但会弄乱预期的结果。
最后一件事 - webpack插件不会更改elec.js文件中的任何代码,因为该文件不是webpack的。
所以这一切都使得build / webpack时间的process.env.NODE_ENV在elec.js代码中不可用。
一旦机制明确,解决问题的方法很少,我会给出一般性的想法,因为每个都有很多讨论,根据情况和期望的用例,有些比其他更好:
- 在构建期间基于环境变量生成具有必要赋值的js文件(例如,复制env-prod.js / env-dev.js - > env.js中的一个),将其复制到elec.js旁边,并引用它(
require(env.js)
) )在elec.js. - 从命令行传递环境变量(例如
NODE_ENV=1 electron .
) - 它将到达elec.js. - 根据环境变量将文件包含到webpack中(例如,复制env-prod.js / env-dev.js - > env.js中的一个)并查看来自elec.js的webpacked'文件,例如:使用
asar
命令。 - 在package.json中使用不同的版本,具体取决于构建(例如版本:“1.0.0-DEBUG”用于调试),并通过调用elec.js中的app.getVersion()来解析它。这很棘手,因为package.json应该是单个文件,但是可以使用OS命令(例如在“脚本”中)来复制一个准备好的package.json文件,然后再调用npm。
以下是一些可能有用的链接:
Electron issue #7714 - 关于Electron相关特征的讨论
electron-is-dev - 模块检查它是否在dev中
Electron boilerplate - 使用config / env-prod / dev文件的示例样板文件
环境变量在电子中未定义,即使它已在webpack.DefinePlugin中设置
我有一个要求,我们需要根据它是在生产环境还是在开发环境中执行来设置dll路径。所以我决定将该值放在环境变量中并尝试使用webpack.DefinePlugin({})来实现。
方法1:
webpack.config.json
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV' : JSON.stringify('production')
})
然后我试图在电子主过程中得到这个值,在我的情况下是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()函数中访问该值时,它是未定义的,因此flow始终转到else块。
有什么我想念的吗?
方法2:
我尝试使用cross-env节点包实现相同,但没有运气。请在下面找到我尝试使用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/"
}
回答如下:
问题是多方面的。
首先,在加载应用程序之前,您的elec.js由Electron执行。 Electron运行elec.js,它创建浏览器窗口(let win = new BrowserWindow(...)
)并在浏览器进程中加载HTML文件(win.loadURL(...)
),然后HTML加载你的webpack'ed js。因此,elec.js中没有任何webpacked js代码。 webpack的代码也在运行于elec.js之外的另一个进程中。
另外需要注意的是webpack插件不会为它指向的变量创建任何赋值。它通过简单的文本搜索和替换来完成,在您的示例中,process.env.NODE_ENV的所有实例将被替换为webpack的源代码中的“production”字符串。这不是太明显,但会弄乱预期的结果。
最后一件事 - webpack插件不会更改elec.js文件中的任何代码,因为该文件不是webpack的。
所以这一切都使得build / webpack时间的process.env.NODE_ENV在elec.js代码中不可用。
一旦机制明确,解决问题的方法很少,我会给出一般性的想法,因为每个都有很多讨论,根据情况和期望的用例,有些比其他更好:
- 在构建期间基于环境变量生成具有必要赋值的js文件(例如,复制env-prod.js / env-dev.js - > env.js中的一个),将其复制到elec.js旁边,并引用它(
require(env.js)
) )在elec.js. - 从命令行传递环境变量(例如
NODE_ENV=1 electron .
) - 它将到达elec.js. - 根据环境变量将文件包含到webpack中(例如,复制env-prod.js / env-dev.js - > env.js中的一个)并查看来自elec.js的webpacked'文件,例如:使用
asar
命令。 - 在package.json中使用不同的版本,具体取决于构建(例如版本:“1.0.0-DEBUG”用于调试),并通过调用elec.js中的app.getVersion()来解析它。这很棘手,因为package.json应该是单个文件,但是可以使用OS命令(例如在“脚本”中)来复制一个准备好的package.json文件,然后再调用npm。
以下是一些可能有用的链接:
Electron issue #7714 - 关于Electron相关特征的讨论
electron-is-dev - 模块检查它是否在dev中
Electron boilerplate - 使用config / env-prod / dev文件的示例样板文件