深入浅出Electron:原理、工程与实践
上QQ阅读APP看书,第一时间看更新

3.5 为生产环境安装依赖

electron-builder会检查业务目录下是否存在node_modules目录,如果存在,则它就不再为开发者安装依赖包了,所以在打包好我们的业务代码后,可以在业务目录下创建一个node_modules空目录,以此来规避electron-builder的默认行为。

如果没有这个目录,electron-builder就会为开发者安装package.json中配置的依赖包。electron-builder安装依赖包的代码如下所示:

function installDependencies(appDir: string, options: RebuildOptions): Promise <any> {
  const platform = options.platform || process.platform
  const arch = options.arch || process.arch
  const additionalArgs = options.additionalArgs
  let execPath = process.env.npm_execpath || process.env.NPM_CLI_JS
  const execArgs = ["install"]
  const npmUserAgent = process.env["npm_config_user_agent"]
  const isYarn2 = npmUserAgent != null && npmUserAgent.startsWith("yarn/2.")
  if (!isYarn2) {
    if (process.env.NPM_NO_BIN_LINKS === "true") {
      execArgs.push("--no-bin-links")
    }
    execArgs.push("--production")
  }
  if (!isRunningYarn(execPath)) {
    execArgs.push("--cache-min", "999999999")
  }
  if (execPath == null) {
    execPath = getPackageToolPath()
  }
  else if (!isYarn2) {
    execArgs.unshift(execPath)
    execPath = process.env.npm_node_execpath || process.env.NODE_EXE || "node"
  }
  if (additionalArgs != null) {
    execArgs.push(...additionalArgs)
  }
  return spawn(execPath, execArgs, {
    cwd: appDir,
    env: getGypEnv(options.frameworkInfo, platform, arch, options.buildFrom Source === true),
  })
}

如你所见,electron-builder依然是使用Node.js的子进程控制API来调用npm或yarn的命令行工具安装依赖包。

也就是说在应用输出目录下执行了一次npm install --production命令。--production指令指示npm工具不要安装devDependencies配置节里配置的依赖包。

虽然electron-builder支持编译并安装原生模块,但不推荐你使用它的这个能力。建议你使用electron-rebuild工具(https://github.com/electron/electron-rebuild)先把原生模块编译好,再通过extraResources的方式把编译好的addon文件配置到你的安装包内。这里涉及的内容后面还会有详细的解释。

electron-rebuild工具会自动帮你检查所打包的Electron在使用什么版本的Node.js,并根据这个版本的Node.js来编译你的原生模块,兼容性更好。