使用 Electron 应用程序有效地捆绑依赖项以进行分发

Posted

技术标签:

【中文标题】使用 Electron 应用程序有效地捆绑依赖项以进行分发【英文标题】:Efficiently Bundling Dependencies with Electron App for Distribution 【发布时间】:2016-12-06 10:45:43 【问题描述】:

我正在尝试找出一种有效的方法来使用我的 Electron 应用程序捆绑和分发各种依赖项(节点模块和/或“客户端”端脚本和框架,如 Angular)。

虽然npm install module-name --save 的基本方法适用于开发,但最终在最小化您的应用程序大小和在运行时使用最小化资源时并不是那么好。例如,几乎所有的 npm 包(包括节点模块)都带有很多“额外的包袱”,比如自述文件、各种版本的组件(缩小版、未缩小版、ES2015、no-ES2015 等)。虽然这些文件非常适合开发,但所有这些文件绝对不需要包含在您将分发的版本中。

目前似乎有两种解决问题的方法:

Electron Builder 建议使用 2 文件 package.json 系统。 仅在开发期间使用的任何依赖项都应使用 --save-dev 进行 npm 安装,然后在构建应用程序以进行分发时使用修剪。

在这方面我有几个问题:

    如果可以使用 --save-dev 安装仅开发模块/依赖项,然后在实际应用构建/编译期间使用修剪,我不太确定为什么需要 2 文件 package.json 系统? 无论使用上述哪种方法,您的应用程序中仍会包含完整的 npm 包,包括您的应用程序未使用的所有杂项/重复文件。那么如何“修剪” npm 包本身,以便只包含在运行时使用的实际文件(如缩小的脚本)? 将 Bower 用于“客户端”包(如 AngularJS 2、Bootstrap、jQuery 等)并将 npm 用于节点模块(如 fs-extra ) 在关注点分离和以后易于捆绑方面是更好的选择吗? WebPack 是否可以仅用于生成所需的文件,至少对于“cient 端”而言,这样只有真正的节点模块将包含在应用程序中,而其余部分将是 web-pack 编译的文件集的形式吗? 关于如何在实践中认可这种依赖关系和分发捆绑的实用技巧? Gulp 脚本?网络包脚本?项目结构?

谢谢。

【问题讨论】:

【参考方案1】:

我仍处于采用代码部署最佳实践的学习曲线中。但这是我推荐的起始清单。

是的,npm install --save-dev 是隔离开发和构建特定包的第一个最简单的方法。这包括 gulp/grunt/webpack 及其加载器或其他包。这些仅用于构建,而不用于实际运行的代码。应用程序使用的所有包都应使用npm install --save 安装,以便它在项目级别可用。因此,在生产中,您不会在根本不会安装开发包的机器上安装 npm install --production。请参阅What's the difference between dependencies, devDependencies and peerDependencies in npm package.json file? 了解更多信息。 虽然最初的建议是将 bower 用于客户端,将 npm 用于服务器端,但两者都可以使用 npm 安装。毕竟,两者都在管理包和依赖项方面做同样的工作。但是,如果使用 webpack,建议也将 npm 用于客户端依赖项。 package.json 应该被认为只管理依赖包而不是用于构建。为了只构建和选择所需的文件,您需要像 gulp/grunt 这样的任务运行器或像 webpack 这样的捆绑程序。 虽然 gulp/grunt 在构建自动化方面非常流行,其中包括将所有依赖的 javascript 捆绑到文件中并将它们压缩到一个文件中,但 webpack/browserify 是一个更好的选择,因为它支持模块导入。模块导入是在 node js 类型的编码中需要一个模块在另一个模块中的直观方式 var util = require('./myapp/lib/utils.js') 这是在代码中提及所需依赖项的有效方式。 webpack builder 像 gulp 一样作为构建过程运行。但不是通过 html 文件查看所有 js 文件,而是查看启动 js 文件并递归确定 require 语句提到的所有依赖代码并相应地打包。它还缩小了代码。它还将 css 和图像文件加载到一个包中,以减少服务器访问。如果需要,可以将某些模块配置为在运行时动态加载,从而进一步减少页面负载。 NPM vs. Bower vs. Browserify vs. Gulp vs. Grunt vs. Webpack 详细讨论了这个问题。 Webpack 可用于优化捆绑客户端应用程序,而服务器端无需捆绑或缩小,因为无需下载。 在 webpack 中,虽然你可以用 lib 文件路径提及依赖模块,但建议 npm install all dependencies 并提及模块名称。例如,如果你安装了 jquery,而不是像 /libs/jquery.min.js 这样的路径,你可以提到'jquery'。 Webpack 将自动拉取 jquery 库和依赖项并将其最小化。如果它们是通用模块,它也会被分块。因此,最好使用 npm install 依赖包而不是 bower install。 ES2015 在编码期间提供了很多好处,包括类型检查和模块。但是,所有浏览器还没有原生支持该规范。因此,您需要将代码转换为浏览器可以理解的旧版本。这是由像 Babel 这样可以用 gulp 运行的编译器完成的。 Webpack 有内置的 babel 加载器,所以 webpack 理解 ES2015。推荐使用 ES2015 模块系统,因为它很快就会成为事实上的编码方式,并且由于有转译器,所以不用担心 IE8/9 不支持。 对于项目结构,您可以拥有 服务器

客户

包含js文件的src dist 包含生成的 html 和构建文件

webpack.dev.config.js 和 webpack.prod.config.js 可以在根级别。

我发现这个领域是一片汪洋大海和不同的最佳实践流派。这可能是一组最佳实践。随意选择适合您的场景的集合。期待更多的 cmets 添加到这个集合中。

【讨论】:

以上是关于使用 Electron 应用程序有效地捆绑依赖项以进行分发的主要内容,如果未能解决你的问题,请参考以下文章

如何在捆绑电子应用程序之前对其进行编码(对于Mac)?

外部依赖项错误地捆绑在 rollup.js 中?

在 TinyIOC 中注册依赖项以在 NancyFX 中使用

在 ec2 上安装 playwright 依赖项以在 Java 中使用它

捆绑 Quasar/Express/Electron 应用程序进行生产 - Express-server 无法启动

如何将第三方二进制文件与 Electron 捆绑在一起?