运行时提示*.node
文件加载失败?
打包遇到如下关于 .node 文件加载问题:
1. Cannot open xxx/@xylink/xy-electron-sdk.node: Error: The specified module cloud not be found
2. dlopen(xxx/@xylink/xy-electron-sdk.node, 1): image not found
或者:
Uncaught Error: Cannot open /xxx/node_modules/electron/dist/Electron.app/Contents/Resources/electron.asar/renderer/xy-electron-sdk.node:
Error: Invalid package /xxx/node_modules/electron/dist/Electron.app/Contents/Resources/electron.asar
at eval (xy-electron-sdk.node:1:163)
at ./node_modules/@xylink/xy-electron-sdk/build/Release/xy-electron-sdk.node (index.js:127:1)
出现类似上述的信息,说明 xy-electron-sdk.node
模块没有被正确的打包到程序中,或者没有被正确的加载到项目中;
问题原因
这里,需要解释一下工作路径的概念: 在 Electron 应用运行时,调用 global.process.cwd()
函数,得到的结果 “/” 即为运行时的工作路径,当在运行时加载文件时,使用的第一个 "/" 其实都是从当前的工作路径开始的。
我们在编写构建配置的时候,很自然的会把 "/" 当成 应用路径 来用,然而在运行时 “/” 却代表的是 工作路径,工作路径 和 应用路径的不一致,是造成文件加载失败的根本原因,下面罗列出了这两种路径在不同平台下运行时的关系:
- Mac 环境:
/
指向的是 [应用路径]/Contents/Frameworks
- Windows 环境:
/
指向的是 [应用路径]
所以,我们构建不同平台的代码时,也需要告诉程序:到不同的目录中去加载文件。 此外,还需要注意这两个问题:
-
xy-electron-sdk.node
是 .node
模块,需要借助 native-ext-loader
插件、 node-loader
或其它类似功能的插件来打包。 - Windows环境:
xy_electron_sdk.node
还依赖同目录下的 .dll 和 .lib 文件,需要一同打包,如下图:
解决方法
步骤一:安装 native-ext-loader
步骤二:修改 webpack 配置,添加以下处理 .node 文件的 loader 加载器,配置:
module: {
rules: [
{
test: /\.node$/,
loader: 'native-ext-loader',
options: {
// 此处的配置参见下方备注,路径可能需要根据环境做不同的配置
rewritePath: './resources',
},
},
];
- 使用
vue-cli
创建的项目,webpack 配置存放在 vue.config.js
文件中的 chainWebpack
选项中。 - 使用
create-react-app
创建的项目,webpack 配置文件为 [项目目录]/node_modules/react-scripts/config/webpack.config.js
步骤三:配置 packages.json 文件,添加打包配置和构建脚本:
"build": {
"win": {
"extraFiles": [
{
"from": "./models",
"to": "./models",
"filter": [
"**/*"
]
},
{
"from": "node_modules/@xylink/xy-electron-sdk/dll",
"to": "./dll",
"filter": [
"**/*"
]
},
{
"from": "node_modules/@xylink/xy-electron-sdk/dll/I420ToARGB.cso",
"to": "./",
"filter": [
"**/*"
]
},
{
"from": "node_modules/@xylink/xy-electron-sdk/build/Release/",
"to": "./resources",
"filter": [
"**/*"
]
}
]
},
"mac": {
"extraFiles": [
{
"from": "./models",
"to": "./Resources",
"filter": [
"**/*"
]
},
{
"from": "node_modules/@xylink/xy-electron-sdk/dll",
"to": "./Frameworks",
"filter": [
"**/*"
]
},
{
"from": "node_modules/@xylink/xy-electron-sdk/build/Release/",
"to": "./resources",
"filter": [
"**/*"
]
}
]
}
}
添加Scripts构建;
备注
在步骤二配置 node-loader 加载器时,可能会根据当前运行环境有不同的配置,例如,在开发环境,会 localhost 的加载路径,那么需要使用 __dirname 以绝对路径的引用 .node 文件,在 打包应用时,是以 electron 的 file 协议加载文件,需要使用相对路径,即 windows 是以 resources 资源路径为静态资源根目录,mac 是以 Resources 为静态资源跟路径,所以配置可能为下面这种方式:
// dev
{
test: /\.node$/,
loader: 'native-ext-loader',
options: {
name: '[name].[ext]',
// 此处路径需要根据项目路径重新设置,具体参见报错信息关于引用.node文件路径进行重写
rewritePath: path.resolve(__dirname, './node_modules/@xylink/xy-electron-sdk/build/Release/'),
},
},
// prduction
{
test: /\.node$/,
loader: 'native-ext-loader',
options: {
name: '[name].[ext]',
rewritePath: './resources',
},
}