本文共 38512 字,大约阅读时间需要 128 分钟。
github桌面应用下载慢
GitHub's framework (formerly known as Atom Shell) lets you write cross platform desktop application using HTML, CSS and JavaScript. It's a variant of run-time which is focused on desktop applications instead of web servers.
GitHub的框架(以前称为Atom Shell)使您可以使用HTML,CSS和JavaScript编写跨平台的桌面应用程序 。 它是运行时的一种变体,它专注于桌面应用程序而不是Web服务器。
Electron's rich native APIs enables us to access native things directly from our pages with JavaScript.
Electron丰富的本机API使我们能够直接使用JavaScript从页面访问本机内容。
This tutorial shows us how to build a desktop application with Angular and Electron. The steps for this tutorial are as follows:
本教程向我们展示了如何使用Angular和Electron构建桌面应用程序。 本教程的步骤如下:
To get started, install if you don't have it in your system already. Our application should be structured as follows:
首先,如果系统中尚未安装 ,请安装它。 我们的应用程序的结构应如下:
There are two package.json
files in this project.
这个项目中有两个package.json
文件。
For development
The package.json
directly inside the project root contains the configurations, dependiencies for your development environment and build scripts. These dependencies and package.json
file will not be included inside the production build.
为了发展
直接在项目根目录下的package.json
包含配置,开发环境和构建脚本的依赖关系。 这些依赖项和package.json
文件不会包含在生产版本中。
For your application
The package.json inside app folder is the manifest file for your application. So whenever you need to install npm dependencies to be used in your application directly, you should install it against this package.json
为您的应用
app文件夹中的package.json是您的应用程序的清单文件。 因此,每当需要安装直接在应用程序中使用的npm依赖项时,都应针对此package.json
安装它
The format of package.json
is exactly same as that of Node's module. Your application’s startup script should be specified in main property inside your app/package.json.
package.json
的格式与Node模块的格式完全相同。 应用程序的启动脚本应在app / package.json内部的main属性中指定。
app/package.json
might look like this:
app/package.json
可能看起来像这样:
{ name: "AngularElectron", version: "0.0.0", main: "main.js" }
You can create both package.json
files either by entering the npm init
command. You can also manually create these files. Install npm dependencies that are required for packaging the application by entering following command in your command line prompt:
您可以通过输入npm init
命令来创建两个package.json
文件。 您也可以手动创建这些文件。 通过在命令行提示符下输入以下命令来安装打包应用程序所需的npm依赖项:
npm install --save-dev electron-prebuilt fs-jetpack asar rcedit Q
app/main.js is the entry point of our application. This script is responsible for creating the main window and handling the system events. main.js should look like the following:
app / main.js是我们应用程序的入口。 该脚本负责创建主窗口并处理系统事件。 main.js应该如下所示:
// app/main.js// Module to control application life.var app = require('app'); // Module to create native browser window.var BrowserWindow = require('browser-window');var mainWindow = null;// Quit when all windows are closed.app.on('window-all-closed', function () { if (process.platform != 'darwin') { app.quit(); }});// This method will be called when Electron has finished// initialization and is ready to create browser windows.app.on('ready', function () { // Create the browser window. mainWindow = new BrowserWindow({ width: 800, height: 600 }); // and load the index.html of the app. mainWindow.loadUrl('file://' + __dirname + '/index.html'); // Open the devtools. // mainWindow.openDevTools(); // Emitted when the window is closed. mainWindow.on('closed', function () { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. mainWindow = null; });});
As I mentioned above, Electron enables you to access local npm modules and native APIs directly from your web pages. Create your app/index.html
file as follows:
如上所述,Electron使您可以直接从网页访问本地npm模块和本机API。 创建您的app/index.html
文件,如下所示:
Hello World!
We are using Electron on
app/index.html is a simple HTML page. Here it reads your package.json
using Node's (file system) module and writes the content into the document body.
app / index.html是一个简单HTML页面。 在这里,它使用Node的 (文件系统)模块读取package.json
并将内容写入文档主体。
Once you have created the project structure, app/index.html
, app/main.js
, app/package.json
, you'll probably want to try running your initial Electron application to test it and make sure it's working as expected.
一旦创建了项目结构app/index.html
, app/main.js
, app/package.json
,您可能想要尝试运行初始的Electron应用程序以对其进行测试,并确保其按预期运行。
If you've installed electron-prebuilt
globally in your system, you can run our application with following command:
如果您已在系统中全局安装了electron-prebuilt
,则可以使用以下命令运行我们的应用程序:
electron app
Here electron
is the command to run electron shell and app
is our application folder name. If you don't want to install Electron into your global npm modules, then run with your local modules installed into npm_modules
folder as follows in your command line prompt:
这里的electron
是运行电子外壳的命令,而app
是我们的应用程序文件夹名称。 如果您不想将Electron安装到全局npm模块中,请在命令行提示符下将本地模块安装到npm_modules
文件夹中运行:
"node_modules/.bin/electron" "./app"
While you could do it that way, I recommend you create a to run your application in your gulpfile.js
, so that you can integrate your task into Visual Studio Code Editor which we will check in next section.
尽管可以这样做,但我建议您创建一个gulpfile.js
以在gulpfile.js
运行您的应用程序,以便将您的任务集成到Visual Studio Code Editor中,我们将在下一部分中进行检查。
// get the dependenciesvar gulp = require('gulp'), childProcess = require('child_process'), electron = require('electron-prebuilt');// create the gulp taskgulp.task('run', function () { childProcess.spawn(electron, ['./app'], { stdio: 'inherit' }); });
Run your gulp task: gulp run
Our application might looks like this:
运行您的gulp任务: gulp run
我们的应用程序可能如下所示:
Visual Studio Code is a cross platform code editor from Microsoft. Behind the scene of VS Code is Electron and Microsoft's proprietary monaco code editor. You can download Visual Studio Code .
Visual Studio Code是Microsoft的跨平台代码编辑器。 VS Code的背后是Electron和微软专有的monaco代码编辑器。 您可以下载Visual Studio Code。
Open your electron application in VS Code.
在VS Code中打开您的电子应用程序。
Lots of tools exist to automate our tasks like building, packaging or testing our application. Mostly we run these tools from the command line. VS Code's built in task runner enables you to integrate your custom tasks into your project. You can run your grunt, gulp, MsBuild or any other tasks directly from within your project without moving to the command line.
存在许多工具可以自动化我们的任务,例如构建,打包或测试我们的应用程序。 通常,我们从命令行运行这些工具。 VS Code的内置任务运行器使您可以将自定义任务集成到项目中。 您可以直接在项目中运行grunt,gulp,MsBuild或任何其他任务,而无需移至命令行。
VS Code can detect your grunt and gulp tasks automaticaly. Press ctrl + shift + p
then type Run Task
followed by Enter
.
VS Code可以自动检测您的咕unt声和吞咽任务。 按ctrl + shift + p
然后键入Run Task
然后按Enter
。
You will get all available tasks from your gulpfile.js
or gruntfile.js
.
您将从gulpfile.js
或gruntfile.js
获得所有可用任务。
Note that, you should have your
gulpfile.js
in root directory of your application.请注意,您应该在应用程序的根目录中包含
gulpfile.js
。
ctrl + shift + b
will execute build
task from your task runner. You can override this intergration using the task.json
file. Press ctrl + shift + p
then type Configure Task
followed by Enter
. This will create .setting
folder and a task.json in your project . You need to configure the tasks in tasks.json if you want to do more than simply run the task. For example you might want to run the application when you press the Ctrl + Shift + B
. To do this edit the task.json file as follows:
ctrl + shift + b
将从任务运行器执行build
任务。 您可以使用task.json
文件覆盖此task.json
。 按ctrl + shift + p
然后键入Configure Task
然后按Enter
。 这将在您的项目中创建.setting
文件夹和task.json。 如果您想做的不仅仅是运行任务,还需要在task.json中配置任务。 例如,当您按Ctrl + Shift + B
时,可能要运行该应用程序。 为此,如下编辑task.json文件:
{ "version": "0.1.0", "command": "gulp", "isShellCommand": true, "args": [ "--no-color" ], "tasks": [ { "taskName": "run", "args": [], "isBuildCommand": true } ] }
Root section says that the command is gulp
. You can have more tasks inside tasks
section as you want. Setting isBuildCommand
true for a task will bind the Ctrl + Shift + B
to that task. Currently VS Code supports one top level task only.
根节说该命令是gulp
。 您可以根据需要在“ tasks
部分中包含更多任务。 为任务设置isBuildCommand
true会将Ctrl + Shift + B
绑定到该任务。 当前,VS Code仅支持一项顶级任务。
Now if you press Ctrl + Shift + B
, gulp run
will be executed.
现在,如果您按Ctrl + Shift + B
,则将执行gulp run
。
You can read more about visual studio code tasks
您可以阅读有关Visual Studio代码任务的更多信息
Open the debug panel and click configure button which will create a launch.json
file inside .settings
folder with debug configuration.
打开调试面板,然后单击配置按钮,这将在.settings
文件夹中创建带有调试配置的launch.json
文件。
We don't need launch app.js configuration, so remove it.
我们不需要启动app.js配置,因此将其删除。
Now your launch.json
should be as follows:
现在,您的launch.json
应该如下所示:
{ "version": "0.1.0", // List of configurations. Add new configurations or edit existing ones. // ONLY "node" and "mono" are supported, change "type" to switch. "configurations": [ { "name": "Attach", "type": "node", // TCP/IP address. Default is "localhost". "address": "localhost", // Port to attach to. "port": 5858, "sourceMaps": false } ] }
Change your gulp run
task that we created before as follows, so that our electron will start in debug mode and will listen to port 5858:
如下更改您之前创建的gulp run
任务,以使我们的电子设备以调试模式启动并侦听端口5858:
gulp.task('run', function () { childProcess.spawn(electron, ['--debug=5858','./app'], { stdio: 'inherit' }); });
In the debug panel choose "Attach" configuration and click run or press F5. After few seconds you should see the debug command panel in the top.
在调试面板中,选择“附加”配置,然后单击“运行”或按F5。 几秒钟后,您应该在顶部看到调试命令面板。
New to AngularJS? Check out the official website or some of the .
AngularJS的新手? 查看官方网站或一些 。
This section explains how to create a simple Customer Manager application using AngularJS with a MySQL database as the backend. The goal of this application is not to highlight the core concepts of AngularJS but to demonstrate how to use the AngularJS and NodeJS together with MySQL backend inside GitHub Electron.
本节说明如何使用以MySQL数据库为后端的AngularJS创建简单的Customer Manager应用程序。 该应用程序的目的不是突出AngularJS的核心概念,而是演示如何在GitHub Electron中将AngularJS和NodeJS与MySQL后端一起使用。
Our Customer Manager application is as simple as the following:
我们的客户经理应用程序很简单,如下所示:
Our application is located inside app folder, and the structure of the application is shown below.
我们的应用程序位于app文件夹内,其结构如下所示。
The home page is the app/index.html
file. The app/scripts
folder contains all the key scripts and views used in this application. There are several techniques that can be used for organizing application files.
主页是app/index.html
文件。 app/scripts
文件夹包含此应用程序中使用的所有关键脚本和视图。 有几种技术可用于组织应用程序文件。
Here I prefer scripts organized by features. Each feature has its own folder with templates and controllers inside the same folder. For more info on folder structure, read:
在这里,我更喜欢按功能组织的脚本。 每个功能都有其自己的文件夹,并且同一文件夹中包含模板和控制器。 有关文件夹结构的更多信息,请阅读:
Before get started with the AngularJS application, we're going to install client side dependencies using . Install if you don't have it already. Change the current working directory to the root of the application in your terminal then install dependencies as follows from your command line prompt :
在开始使用AngularJS应用程序之前,我们将使用安装客户端依赖项。 如果尚未安装 ,请安装它。 将当前工作目录更改为终端中应用程序的根目录,然后在命令行提示符下按如下所示安装依赖项:
bower install angular angular-route angular-material --save
For this demo I'll be using a database called customer-manager
and a table called customers
. Here is the dump of database so that you can get up and run quickly.
在本演示中,我将使用一个名为customer-manager
的数据库和一个名为customers
的表。 这是数据库的转储,因此您可以快速启动并运行。
CREATE TABLE `customer_manager`.`customers` ( `customer_id` INT NOT NULL AUTO_INCREMENT, `name` VARCHAR(45) NOT NULL, `address` VARCHAR(450) NULL, `city` VARCHAR(45) NULL, `country` VARCHAR(45) NULL, `phone` VARCHAR(45) NULL, `remarks` VARCHAR(500) NULL, PRIMARY KEY (`customer_id`) );
Once you have your database and table ready, let's create an AngularJS service to access the data directly from this database. The service connects to database using node-mysql
npm module - a NodeJs driver for MySql written in JavaScript. Install node-mysql
module in your app/ folder where your Angular application resides.
准备好数据库和表后,让我们创建一个AngularJS服务以直接从该数据库访问数据。 该服务使用node-mysql
npm模块连接到数据库,该模块是用JavaScript编写的MySql的NodeJs驱动程序。 在Angular应用程序所在的app /文件夹中安装node-mysql
模块。
Note , we install node-mysql module inside app folder, not in the application root, as we need to include this module inside the final distribution.
注意,我们将node-mysql模块安装在app文件夹中,而不是在应用程序根目录中,因为我们需要将此模块包含在最终发行版中。
Change the current working directory to app folder in your command prompt install using following command.
使用以下命令在命令提示符安装中将当前工作目录更改为app文件夹。
npm install --save mysql
Our angular service - app/scripts/customer/customerService.js, should looks like following:
我们的角度服务-app / scripts / customer / customerService.js如下所示:
(function () { 'use strict'; var mysql = require('mysql'); // Creates MySql database connection var connection = mysql.createConnection({ host: "localhost", user: "root", password: "password", database: "customer_manager" }); angular.module('app') .service('customerService', ['$q', CustomerService]); function CustomerService($q) { return { getCustomers: getCustomers, getById: getCustomerById, getByName: getCustomerByName, create: createCustomer, destroy: deleteCustomer, update: updateCustomer }; function getCustomers() { var deferred = $q.defer(); var query = "SELECT * FROM customers"; connection.query(query, function (err, rows) { if (err) deferred.reject(err); deferred.resolve(rows); }); return deferred.promise; } function getCustomerById(id) { var deferred = $q.defer(); var query = "SELECT * FROM customers WHERE customer_id = ?"; connection.query(query, [id], function (err, rows) { if (err) deferred.reject(err); deferred.resolve(rows); }); return deferred.promise; } function getCustomerByName(name) { var deferred = $q.defer(); var query = "SELECT * FROM customers WHERE name LIKE '" + name + "%'"; connection.query(query, [name], function (err, rows) { if (err) deferred.reject(err); deferred.resolve(rows); }); return deferred.promise; } function createCustomer(customer) { var deferred = $q.defer(); var query = "INSERT INTO customers SET ?"; connection.query(query, customer, function (err, res) if (err) deferred.reject(err); deferred.resolve(res.insertId); }); return deferred.promise; } function deleteCustomer(id) { var deferred = $q.defer(); var query = "DELETE FROM customers WHERE customer_id = ?"; connection.query(query, [id], function (err, res) { if (err) deferred.reject(err); deferred.resolve(res.affectedRows); }); return deferred.promise; } function updateCustomer(customer) { var deferred = $q.defer(); var query = "UPDATE customers SET name = ? WHERE customer_id = ?"; connection.query(query, [customer.name, customer.customer_id], function (err, res) { if (err) deferred.reject(err); deferred.resolve(res); }); return deferred.promise; } }})();
customerService
is a simple custom angular service that provides basic CRUD operations on customers
table . It uses node's mysql
module directly inside the service. If you already have a remote data service, you can use it instead.
customerService
是一个简单的自定义角度服务,可在customers
表上提供基本的CRUD操作。 它直接在服务内部使用节点的mysql
模块。 如果您已经拥有远程数据服务,则可以改用它。
OurcustomerController
insideapp/scripts/customer/customerController is as follows:
app / scripts / customer / customerController
内部的customerController如下:
(function () { 'use strict'; angular.module('app') .controller('customerController', ['customerService', '$q', '$mdDialog', CustomerController]); function CustomerController(customerService, $q, $mdDialog) { var self = this; self.selected = null; self.customers = []; self.selectedIndex = 0; self.filterText = null; self.selectCustomer = selectCustomer; self.deleteCustomer = deleteCustomer; self.saveCustomer = saveCustomer; self.createCustomer = createCustomer; self.filter = filterCustomer; // Load initial data getAllCustomers(); //---------------------- // Internal functions //---------------------- function selectCustomer(customer, index) { self.selected = angular.isNumber(customer) ? self.customers[customer] : customer; self.selectedIndex = angular.isNumber(customer) ? customer: index; } function deleteCustomer($event) { var confirm = $mdDialog.confirm() .title('Are you sure?') .content('Are you sure want to delete this customer?') .ok('Yes') .cancel('No') .targetEvent($event); $mdDialog.show(confirm).then(function () { customerService.destroy(self.selected.customer_id).then(function (affectedRows) { self.customers.splice(self.selectedIndex, 1); }); }, function () { }); } function saveCustomer($event) { if (self.selected != null && self.selected.customer_id != null) { customerService.update(self.selected).then(function (affectedRows) { $mdDialog.show( $mdDialog .alert() .clickOutsideToClose(true) .title('Success') .content('Data Updated Successfully!') .ok('Ok') .targetEvent($event) ); }); } else { //self.selected.customer_id = new Date().getSeconds(); customerService.create(self.selected).then(function (affectedRows) { $mdDialog.show( $mdDialog .alert() .clickOutsideToClose(true) .title('Success') .content('Data Added Successfully!') .ok('Ok') .targetEvent($event) ); }); } } function createCustomer() { self.selected = {}; self.selectedIndex = null; } function getAllCustomers() { customerService.getCustomers().then(function (customers) { self.customers = [].concat(customers); self.selected = customers[0]; }); } function filterCustomer() { if (self.filterText == null || self.filterText == "") { getAllCustomers(); } else { customerService.getByName(self.filterText).then(function (customers) { self.customers = [].concat(customers); self.selected = customers[0]; }); } } }})();
Our Customer template(app/scripts/customer/customer.html) uses angular material components to build user interface, and its is as follows:
我们的客户模板( app / scripts / customer / customer.html )使用角形材料组件来构建用户界面,其内容如下:
Customers
{ {it.name}} { { _ctrl.selected.name }}
Add Save Cancel Delete
app.js contains module initialization script and application route config as follows:
app.js包含模块初始化脚本和应用程序路由配置,如下所示:
(function () { 'use strict'; var _templateBase = './scripts'; angular.module('app', [ 'ngRoute', 'ngMaterial', 'ngAnimate' ]) .config(['$routeProvider', function ($routeProvider) { $routeProvider.when('/', { templateUrl: _templateBase + '/customer/customer.html' , controller: 'customerController', controllerAs: '_ctrl' }); $routeProvider.otherwise({ redirectTo: '/' }); } ]);})();
Finally here is our index page app/index.html
最后是我们的索引页面app / index.html
Customer Manager
Run your application using gulp run
command or press Ctrl + Shif + B
if you already configured VS Code task runner as above.
使用gulp run
命令运行您的应用程序,或者按Ctrl + Shif + B
如果您已按上述方式配置VS Code任务运行程序)。
To build our Angular application install gulp-uglify
, gulp-minify-css
and gulp-usemin
packages.
要建立我们的角应用程序安装gulp-uglify
, gulp-minify-css
和gulp-usemin
包。
npm install --save gulp-uglify gulp-minify-css gulp-usemin
Open your gulpfile.js
and import required modules
打开您的gulpfile.js
并导入所需的模块
var childProcess = require('child_process'); var electron = require('electron-prebuilt'); var gulp = require('gulp'); var jetpack = require('fs-jetpack'); var usemin = require('gulp-usemin'); var uglify = require('gulp-uglify'); var projectDir = jetpack; var srcDir = projectDir.cwd('./app'); var destDir = projectDir.cwd('./build');
Clean build directory if it already exists.
清理构建目录(如果已存在)。
gulp.task('clean', function (callback) { return destDir.dirAsync('.', { empty: true }); });
Copy files into build directory, We don't need to copy the angular application code using copy function. usemin
will do this for us in next section:
将文件复制到构建目录,我们不需要使用复制功能复制角度应用程序代码。 在下一部分中, usemin
将为我们做到这一点:
gulp.task('copy', ['clean'], function () { return projectDir.copyAsync('app', destDir.path(), { overwrite: true, matching: [ './node_modules/**/*', '*.html', '*.css', 'main.js', 'package.json' ] }); });
Our build task takes our app/index.html with gulp.src() and then we pipe it to usemin. It then writes the output into build directory and replace references in index.html with optimized version of code.
我们的构建任务将我们的app / index.html与gulp.src()一起使用,然后将其通过管道传递给usemin。 然后,将输出写入构建目录,并使用优化的代码版本替换index.html中的引用。
Note: Don't forget to define usemin blocks inside app/index.html as follows:
注意:不要忘记在app / index.html中定义usemin块,如下所示:
The build task should look as follows:
构建任务应如下所示:
gulp.task('build', ['copy'], function () { return gulp.src('./app/index.html') .pipe(usemin({ js: [uglify()] })) .pipe(gulp.dest('build/')); });
In this section we will package our Electron application for production. Create your build script in root directory as build.windows.js
. This script is intended to be used on Windows. For other platform you should create scripts specific to that platform and should run according to your platform.
在本节中,我们将打包我们的Electron应用程序以进行生产。 在根目录build.windows.js
构建脚本创建为build.windows.js
。 该脚本旨在在Windows上使用。 对于其他平台,您应该创建特定于该平台的脚本,并应根据您的平台运行。
A typical electron distribution can be found inside node_modules/electron-prebuilt/dist
directory. Here is our steps to build the electron application:
在node_modules/electron-prebuilt/dist
目录中可以找到典型的电子分布。 这是我们建立电子应用程序的步骤:
Our very first task to do is to copy electron distribution into our dist
folder.
我们要做的第一个任务是将电子分布复制到dist
文件夹中。
Each electron distribution contains a default application inside dist/resources/default_app
folder. We need to replace this application with our final angular application build.
每个电子分布都在dist/resources/default_app
文件夹中包含一个默认应用程序。 我们需要用最终的角度应用程序构建替换该应用程序。
To protect our application’s source code and resources from users, you can choose to package your app into an asar archive with little changes to your source code. An asar archive is a simple tar-like format that concatenate files into a single file, Electron can read arbitrary files from it without unpacking the whole file.
为了保护我们应用程序的源代码和资源免受用户的侵害,您可以选择将应用程序打包到一个asar存档中,而对源代码的更改很少。 asar归档文件是一种简单的类似tar的格式,可将文件连接成一个文件,Electron可以从其中读取任意文件,而无需解压缩整个文件。
Note: this section describes about packaging in windows platform. All these steps are same for other platforms but paths and files used here is different for other platforms. You can get the full build scripts for OSx and linux here in github.
注意:本节介绍有关在Windows平台中打包的信息。 对于其他平台,所有这些步骤都是相同的,但是此处使用的路径和文件对于其他平台是不同的。 您可以在github中获得OSx和linux的完整构建脚本。
Install dependencies required to build the electron as following: npm install --save q asar fs-jetpack recedit
.
安装构建电子所需的依赖项,如下所示: npm install --save q asar fs-jetpack recedit
。
Next initialize our build script as follows:
接下来,初始化构建脚本,如下所示:
var Q = require('q'); var childProcess = require('child_process'); var asar = require('asar'); var jetpack = require('fs-jetpack');var projectDir;var buildDir; var manifest; var appDir;function init() { // Project directory is the root of the application projectDir = jetpack; // Build directory is our destination where the final build will be placed buildDir = projectDir.dir('./dist', { empty: true }); // angular application directory appDir = projectDir.dir('./build'); // angular application's package.json file manifest = appDir.read('./package.json', 'json'); return Q(); }
Here we use fs-jetpack
node module for the file operation. It gives more flexibility on file operations.
在这里,我们使用fs-jetpack
节点模块进行文件操作。 它为文件操作提供了更大的灵活性。
Copy the default electron distribution from electron-prebuilt/dist
to our dist directory.
将默认的电子分布从electron-prebuilt/dist
复制到我们的dist目录。
function copyElectron() { return projectDir.copyAsync('./node_modules/electron-prebuilt/dist', buildDir.path(), { overwrite: true }); }
You can find a default HTML application inside resources/default_app
folder. We need to replace this application with our angular application. Remove it as follows:
您可以在resources/default_app
文件夹中找到默认HTML应用程序。 我们需要用我们的角度应用程序替换该应用程序。 如下删除它:
Note: Here path is specific to windows platform. For other platforms process is same but path is different. In OSX it's Contents/Resources/default_app
注意:这里的路径特定于Windows平台。 对于其他平台,过程相同,但路径不同。 在OSX中,它是目录/资源/ default_app
function cleanupRuntime() { return buildDir.removeAsync('resources/default_app'); }
function createAsar() { var deferred = Q.defer(); asar.createPackage(appDir.path(), buildDir.path('resources/app.asar'), function () { deferred.resolve(); }); return deferred.promise; }
This combines all your angular application files into single asar package file. You can find the destination asar file in dist/resources/
directory.
这会将您所有的角度应用程序文件合并为单个asar软件包文件。 您可以在dist/resources/
目录中找到目标asar文件。
Next step is to replace the default electron icon with your own, update the product information and rename the application.
下一步是用您自己的图标替换默认的电子图标,更新产品信息并重命名应用程序。
function updateResources() { var deferred = Q.defer(); // Copy your icon from resource folder into build folder. projectDir.copy('resources/windows/icon.ico', buildDir.path('icon.ico')); // Replace Electron icon for your own. var rcedit = require('rcedit'); rcedit(buildDir.path('electron.exe'), { 'icon': projectDir.path('resources/windows/icon.ico'), 'version-string': { 'ProductName': manifest.name, 'FileDescription': manifest.description, } }, function (err) { if (!err) { deferred.resolve(); } }); return deferred.promise;}//Rename the electron exe function rename() { return buildDir.renameAsync('electron.exe', manifest.name + '.exe');}
You can either use wix or NSIS to create windows installer. Here we use NSIS which is designed to be small and flexible as possible and is very suitable for internet distribution. With NSIS you can create such installers that are capable of doing everything that is needed to setup your software.
您可以使用wix或NSIS创建Windows安装程序。 在这里,我们使用NSIS,它设计得尽可能小巧,灵活,非常适合Internet分发。 使用NSIS,您可以创建这样的安装程序,它们能够执行设置软件所需的一切。
Create NSIS script in resources/windows/installer.nsis
在resources / windows / installer.nsis中创建NSIS脚本
!include LogicLib.nsh !include nsDialogs.nsh ; -------------------------------- ; Variables ; -------------------------------- !define dest "{ {dest}}" !define src "{ {src}}" !define name "{ {name}}" !define productName "{ {productName}}" !define version "{ {version}}" !define icon "{ {icon}}" !define banner "{ {banner}}" !define exec "{ {productName}}.exe" !define regkey "Software\${productName}" !define uninstkey "Software\Microsoft\Windows\CurrentVersion\Uninstall\${productName}" !define uninstaller "uninstall.exe" ; -------------------------------- ; Installation ; -------------------------------- SetCompressor lzma Name "${productName}" Icon "${icon}" OutFile "${dest}" InstallDir "$PROGRAMFILES\${productName}" InstallDirRegKey HKLM "${regkey}" "" CRCCheck on SilentInstall normal XPStyle on ShowInstDetails nevershow AutoCloseWindow false WindowIcon off Caption "${productName} Setup" ; Don't add sub-captions to title bar SubCaption 3 " " SubCaption 4 " " Page custom welcome Page instfiles Var Image Var ImageHandle Function .onInit ; Extract banner image for welcome page InitPluginsDir ReserveFile "${banner}" File /oname=$PLUGINSDIR\banner.bmp "${banner}" FunctionEnd ; Custom welcome page Function welcome nsDialogs::Create 1018 ${NSD_CreateLabel} 185 1u 210 100% "Welcome to ${productName} version ${version} installer.$\r$\n$\r$\nClick install to begin." ${NSD_CreateBitmap} 0 0 170 210 "" Pop $Image ${NSD_SetImage} $Image $PLUGINSDIR\banner.bmp $ImageHandle nsDialogs::Show ${NSD_FreeImage} $ImageHandle FunctionEnd ; Installation declarations Section "Install" WriteRegStr HKLM "${regkey}" "Install_Dir" "$INSTDIR" WriteRegStr HKLM "${uninstkey}" "DisplayName" "${productName}" WriteRegStr HKLM "${uninstkey}" "DisplayIcon" '"$INSTDIR\icon.ico"' WriteRegStr HKLM "${uninstkey}" "UninstallString" '"$INSTDIR\${uninstaller}"' ; Remove all application files copied by previous installation RMDir /r "$INSTDIR" SetOutPath $INSTDIR ; Include all files from /build directory File /r "${src}\*" ; Create start menu shortcut CreateShortCut "$SMPROGRAMS\${productName}.lnk" "$INSTDIR\${exec}" "" "$INSTDIR\icon.ico" WriteUninstaller "${uninstaller}" SectionEnd ; -------------------------------- ; Uninstaller ; -------------------------------- ShowUninstDetails nevershow UninstallCaption "Uninstall ${productName}" UninstallText "Don't like ${productName} anymore? Hit uninstall button." UninstallIcon "${icon}" UninstPage custom un.confirm un.confirmOnLeave UninstPage instfiles Var RemoveAppDataCheckbox Var RemoveAppDataCheckbox_State ; Custom uninstall confirm page Function un.confirm nsDialogs::Create 1018 ${NSD_CreateLabel} 1u 1u 100% 24u "If you really want to remove ${productName} from your computer press uninstall button." ${NSD_CreateCheckbox} 1u 35u 100% 10u "Remove also my ${productName} personal data" Pop $RemoveAppDataCheckbox nsDialogs::Show FunctionEnd Function un.confirmOnLeave ; Save checkbox state on page leave ${NSD_GetState} $RemoveAppDataCheckbox $RemoveAppDataCheckbox_State FunctionEnd ; Uninstall declarations Section "Uninstall" DeleteRegKey HKLM "${uninstkey}" DeleteRegKey HKLM "${regkey}" Delete "$SMPROGRAMS\${productName}.lnk" ; Remove whole directory from Program Files RMDir /r "$INSTDIR" ; Remove also appData directory generated by your app if user checked this option ${If} $RemoveAppDataCheckbox_State == ${BST_CHECKED} RMDir /r "$LOCALAPPDATA\${name}" ${EndIf} SectionEnd
Create a function called createInstaller
in your build.windows.js
file as follows:
在build.windows.js
文件中创建一个名为createInstaller
的函数,如下所示:
function createInstaller() { var deferred = Q.defer(); function replace(str, patterns) { Object.keys(patterns).forEach(function (pattern) { console.log(pattern) var matcher = new RegExp('{ {' + pattern + '}}', 'g'); str = str.replace(matcher, patterns[pattern]); }); return str; } var installScript = projectDir.read('resources/windows/installer.nsi'); installScript = replace(installScript, { name: manifest.name, productName: manifest.name, version: manifest.version, src: buildDir.path(), dest: projectDir.path(), icon: buildDir.path('icon.ico'), setupIcon: buildDir.path('icon.ico'), banner: projectDir.path('resources/windows/banner.bmp'), }); buildDir.write('installer.nsi', installScript); var nsis = childProcess.spawn('makensis', [buildDir.path('installer.nsi')], { stdio: 'inherit' }); nsis.on('error', function (err) { if (err.message === 'spawn makensis ENOENT') { throw "Can't find NSIS. Are you sure you've installed it and" + " added to PATH environment variable?"; } else { throw err; } }); nsis.on('close', function () { deferred.resolve(); }); return deferred.promise;}
You should have NSIS installed, and should be available in your path. creaeInstaller
function reads installer script and execute it against NSIS runtim with makensis
command.
您应该已经安装了NSIS,并且在您的路径中应该可用。 creaeInstaller
函数读取安装程序脚本,并使用makensis
命令针对NSIS runtim执行该脚本。
Create a function to put all pieces together, then export it to be accessed from gulp task:
创建一个将所有部分放在一起的函数,然后将其导出以从gulp任务中进行访问:
function build() { return init() .then(copyElectron) .then(cleanupRuntime) .then(createAsar) .then(updateResources) .then(rename) .then(createInstaller); } module.exports = { build: build };
Next create gulp task in gulpfile.js
to execute this build script:
接下来在gulpfile.js
创建gulpfile.js
任务以执行以下构建脚本:
var release_windows = require('./build.windows'); var os = require('os'); gulp.task('build-electron', ['build'], function () { switch (os.platform()) { case 'darwin': // execute build.osx.js break; case 'linux': //execute build.linux.js break; case 'win32': return release_windows.build(); } });
You can have your final product by running:
您可以通过运行以下命令获得最终产品:
gulp build-electron
Your final electron application should be in dist
folder and folder structure should be some thing similar to following.
您最终的电子应用程序应位于dist
文件夹中,并且文件夹结构应类似于以下内容。
Electron is not just a native web view that let's you to wrap your web application into desktop application . It now includes automatic app updates, Windows installers, crash reporting, notifications, and other useful native app features — all exposed through JavaScript APIs.
Electron不仅是一种本地Web视图,还可以让您将Web应用程序包装到桌面应用程序中。 现在,它包括自动应用程序更新,Windows安装程序,崩溃报告,通知和其他有用的本机应用程序功能-所有这些功能都通过JavaScript API公开。
So far there is huge range of apps created using electron including chat apps, database explorers, map designers, collaborative design tools, and mobile prototyping apps.
到目前为止,有大量使用电子工具创建的应用程序,包括聊天应用程序,数据库浏览器,地图设计师,协作设计工具以及移动原型应用程序。
Here is some useful resources about Github Electron:
这是有关Github Electron的一些有用资源:
翻译自:
github桌面应用下载慢
转载地址:http://rnywd.baihongyu.com/