澳门新浦京娱乐场网站-www.146.net-新浦京娱乐场官网
做最好的网站

澳门新浦京娱乐场网站:构建桌面应用,Magento

摄像在youtube网址本国访问不了,能够使用FQ软件查看。
摄像地址:www.youtube.com/embed/682p52tFcmY@autoplay=1

Magento 2富有优良的建制,允许你成立数量库表,纠正现成的,以至增进一些数量到他们(如安装数量,已被增多在模块安装卡塔 尔(英语:State of Qatar)。 这种机制允许这几个变迁能够在差别的配备之间传输。

澳门新浦京娱乐场网站 1

GitHub 的 Electron 框架(早先叫做 Atom Shell卡塔尔国允许你接收 HTML, CSS 和 JavaScript 编写跨平台的桌面应用。它是io.js 运转时的衍生,潜心于桌面应用并非web 服务端。

上边是录制文字介绍:

Magento 2系统风流倜傥体化结构是树立在模块的底工上。平时,创设定制的率先步是营造模块。

要创制模块,需求形成以下步骤:

  1. 创立模块文件夹
  2. 创建 etc/module.xml 文件.
  3. 创建 registration.php 文件.
  4. 运行 bin/magento setup:upgrade剧本安装新模块
  5. 检查模块是或不是正规干活

澳门新浦京娱乐场网站,让我们详细地看一下那几个步骤。

关键的定义是,并不是做你能做的贰遍又壹回重新安装系统时,手动SQL操作,开采人员创立八个装置(或升官卡塔尔国脚本富含数据。 每一趟安装模块时,脚本将被推行。

webpack 是二个用来营造大家应用程序中的 JavaScript 模块的工具。webpack 通过神速建构应用程序注重图表并以准确的风流浪漫豆蔻梢头打包它们来简化你的专门的学问流。你能够针对你的代码来对 webpack 举行自定义的优化配置,比方为临蓐意况拆分 vendor/css/js 代码,对图纸展开base64转码,通过运营开荒服务器(development server卡塔 尔(英语:State of Qatar)来落到实处无刷新热重载(hot-reload卡塔尔通过babel进行es6的转码,能够剖判市道上超多预css编写翻译等众多绚烂的性状。

Electron 丰裕的原生 API 使我们能够在页面中一向动用 JavaScript 获取原生的内容。

创设模块文件夹

Magento 2有八种档案的次序的本子:installschema,installdata,upgradeschema和upgradedata。 安装脚本只进行一回,而进步脚本每回推行模块版本被转移时实行。

我们先尝个鲜,创设一个示范来演示一下

因为今后是依靠2.0的授课,在最早前,先要确认你早已设置 Node.js 的最新版本。使用 Node.js 最新的 LTS 版本,是下里巴人的开发银行。使用旧版本,你恐怕遇见各个难点,因为它们或许相当不足webpack 作用或短少相关 package 包。

怎么设置npm小编就十分少说了,大家都晓得的,英特网的事例超多,这里就十分的少陈诉了

以此科目向大家显示了如何接纳 Angular 和 Electron 创设叁个桌面应用。上边是本学科的全数手续:

Magento 2模块文件夹能够制造在四个地方: app/code 和 vendor 文件夹

基于Magento 2已设置,大旨模块能够投身 vendor/magento/magento-*文件夹 或 app/code/Magento/ 文件夹

要查看所有三种脚本项目,大家将不辱任务以下问好页任务:

注意

咱俩先全局安装一下经过
npm install webpack -g

安装好之后大家看一下webpack的版本
webpack --help || webpack -v 这里就展会示版本号假如是2.0之上的未有毛病

一旦原先在大局安装过的话请本人升个级
npm install webpack -g

咱俩来试着弄多少个demo,本人用的是windows,展开cmd

mkdir wepback2.0 && cd webpack2.0

复兴成叁个package.json文件,那是三个存方表达的文书,以json的格式寄放,每一个字段都意味差异的含义,不懂的能够看那些阮大神的教学http://javascript.ruanyifeng.com/nodejs/packagejson.html
先轻便的带头化

npm init -y

建多个 app文件夹,再app里成立多个 index.js 文件。

app/index.js

function component () {
  var element = document.createElement('div');

  /* 需要引入 lodash,下一行才能正常工作 */
  element.innerHTML = _.join(['Hello','webpack'], ' ');

  return element;
}

document.body.appendChild(component())

我们在根目录下再成立贰个Index.html
要运营这段代码,平日供给有以下 HTML :

webpack2.0/index.html

<html>
  <head>
    <title>webpack 2 demo</title>
    <script src="https://unpkg.com/lodash@4.16.6"></script>
  </head>
  <body>
    <script src="app/index.js"></script>
  </body>
</html>

在那示例中,<script> 标签之间存在隐式重视关系。

好端端用法存在的标题

运作 index.js 会信任于页面中提前引进的 lodash。之所以说是隐式的是因为 index.js 并未有显式评释需求引进 lodash,只是若是推断已经存在三个大局变量 _。

利用这种情势去管理 JavaScript 项目会有部分难题:

澳门新浦京娱乐场网站:构建桌面应用,Magento2开发教程。假使借助不设有,或许引进顺序错误,应用程序将不或然正常运维。
设若依赖被引进不过并从未利用,那样就能够设有重重浏览器不能不下载的失效代码。

  1. 创立三个粗略的 Electron 应用

  2. 行使 Visual Studio Code 编辑器管理大家的品种和职责

  3. 利用 Electron 开采(原版的书文为 Integrate卡塔尔国叁个 Angular 顾客保管使用(Angular Customer Manager App卡塔尔国

  4. 应用 Gulp 职责构建大家的利用,并扭转安装包

您应为你的新模块选拔怎么样地点?

举例为特定类型创设立模型块,最佳选拔应用app/code文件夹并交给到花色的蕴藏库中。

举例你要创设一个可选取的恢宏,最好使用composer来创立它,并将您的模块放在 vendor/<YOUR_VENDOR>/module-something 文件夹。

在Magento 2各类模块的称谓由两有个别构成–vendor和模块本身。换句话说,模块分为vendor,所以你必要定义vendor和模块名称。在这里个事例中,让大家的vendor名称“Learning”和“firstunit”模块。

让大家创立文件夹 app/code/Learning 和那个文件夹里面放四个文书夹:FirstUnit。倘令你使用命令行,代码:

  1. cd 到根文件夹
  2. mkdir app/code/Learning
  3. mkdirapp/code/Learning/FirstUnit
  • 创建 greeting_message 表和列greeting_id 和 message.
  • 增添三个记录: “Happy New Year”, “Happy Holidays”.
  • 接下去,纠正表增添另多个字段,“season”,我们增添了记录“Happy Thanksgiving”和“Fall”。
  • 更新第风姿浪漫和第二笔录的连串。

用webpack打包的改良方案

要在 index.js 中打包 lodash 注重,首先大家要求安装 lodash。
npm install --save lodash
因为在生养条件我们全应用到lodash,所以大家不用加-dev

接下来引进(import卡塔尔国它。

app/index.js

  import _ from 'lodash';
function component () {
}

理当如此大家还要修正 index.html,来引进打包好的单个 js 文件。

<html>
  <head>
    <title>webpack 2 demo</title>
-   <script src="https://unpkg.com/lodash@4.16.6"></script>
  </head>
  <body>
-   <script src="app/index.js"></script>
    <script src="dist/bundle.js"></script>
  </body>
</html>

在这里边,index.js 显式需要引进的 lodash 必得存在,然后将它以 _ 的外号绑定(不会形成全局范围变量名污染卡塔尔国。

由此注解模块所需的信赖性,webpack 能够运用那么些音信去营造重视图表,然后使用图表生成三个优化过的,会以科学代码顺序被运转的 bundle。何况未有接纳的依附将不会被 bundle 引入。

前天在这里文件夹下带上以下参数运转 webpack,个中 index.js 是进口文件,bundle.js 是已打包所需的有着代码的输出文件。因为大家前边全局安装过了webpack,所以大家得以在另内盘下运维

webpack js/index.js dist/bundle.js
//js/index代表我们要打包的文
//dist/bundle.js代表我们打到后的文件
Hash: ff6c1d39b26f89b3b7bb
Version: webpack 2.2.0
Time: 385ms
    Asset    Size  Chunks                    Chunk Names
bundle.js  544 kB       0  [emitted]  [big]  main
   [0] ./~/lodash/lodash.js 540 kB {0} [built]
   [1] (webpack)/buildin/global.js 509 bytes {0} [built]
   [2] (webpack)/buildin/module.js 517 bytes {0} [built]
   [3] ./app/index.js 278 bytes {0} [built]

在浏览器中开拓 index.html,查看创设变成功后的 bundle 的结果。你应有能观望带有以下文本的页面:‘Hello webpack’。

您放在心上到在 app/index.js
中运用的 ES二〇一六 模块援用(module import卡塔 尔(英语:State of Qatar) 了吗?尽管 import/export
语句在浏览器中还未有被协理,你也足以平常的使用,因为 webpack 会将其替换为 ES5 包容的代码。你能够核对 dist/bundle.js 的代码来讲服你本人放心使用。
当心 webpack 将不会改动你的 import/export
除了的代码。若是你在利用任何 ES2015 特性,确认保证您选择了三个疑似 Babel 或 Bublé 的转译器。

动用带有配置的 webpack

对此更目眩神摇的布局,我们能够动用二个配置文件,webpack 会参照他事他说加以考察它来打包代码。创制贰个 webpack.config.js 文件后,你能够透过以下配置向 CLI 命令传达和眼下雷同的新闻。

小编们依旧像在根目录下创办叁个webpack.config.js
其风流洒脱跟大家在cli命令行输入指令一下,前面webpack会通过剖析这么些文件来精晓您所急需的布局

var path = require('path');   //这个是引入Node的path路径模块用来解析路径的
var webpack = require("webpack"); //引入webpack来进行

module.exports = {
  entry: './js/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};

配合 npm 使用

思忖到用 CLI 这种办法来运作 webpack 不是特别便利,大家能够安装一个急迅方式。像这么调治 package.json:

{
  ...
  "scripts": {
    "build": "webpack"  //我们能过package.json里的script脚本来进行启动
  },
  ...
}

今昔你能够透过选取 npm run build 命令来贯彻与地点同样的作用。npm 通过命令接受脚本,并一时修补实施景况

创设你的 Electron 应用

开场,要是您的系统中还尚无设置 Node,你须求先安装它。大家应用的构造如下所示:

以此连串中有七个 package.json 文件。

  • 支出应用途目根目录下的 package.json 包涵你的配置,开辟景况的依据和构建脚本。这么些重视和 package.json 文件不会被打包到临盆条件构建中。

  • 利用使用app 目录下的 package.json 是你利用的清单文件。因而每当在你要求为您项目设置 npm 依赖的时候,你应有坚守本条 package.json 来开展安装。

package.json 的格式和 Node 模块中的完全风流倜傥致。你选拔的运转脚本(的门路卡塔 尔(阿拉伯语:قطر‎要求在 app/package.json 中的main属性中钦命。

澳门新浦京娱乐场网站:构建桌面应用,Magento2开发教程。app/package.json看起来是这么的:

?

1
2
3
4
5
{
  name: "AngularElectron",
  version: "0.0.0",
  main: "main.js"
}

过实施npm init命令分别创立那五个package.json文件,也能够手动成立它们。通过在指令提示行里键入以下命令来设置项目打包须求的 npm 依赖:

?

1
npm install --save-dev electron-prebuilt fs-jetpack asar rcedit Q

确认保证您有权力在安装中开创文件和文书夹

下一步, 你须要创制 etc/module.xml 文件。 此文件须要模块存在。

此文件富含以下音讯:

  • 模块名称
  • 模块版本
  • 模块信赖

模块名称定义的文件夹大家刚刚创造的,因为在Magento 2类名称必得遵从的公文夹结构。因为大家创立了文本夹Learning/FirstUnit, our module name will be Learning_FirstUnit 全体归于那一个模块的类将从 LearningFirstUnit – 示例: LearningFirstUnitObserverTest.

模块版本表示数据库架交涉数码的当下版本,并用于进步。 举例,借使您决定在模块中期维改善表的架构。 你怎可以作保在具备配置代码的图景下会时有发生这种转移?通过平昔SQL查询改正数据库将不起功效。相反,Magento 2已经设置和升高的每贰个模块的脚本(可选卡塔尔。这么些本子包括修正数据库架构或数量的下令。追踪是或不是执行脚本或不使用Magento 2模块版本。每一趟实践新的数据库改善时,您将得以达成模块的新本子并转移相应的版本 module.xml. Magento的保存在数据库的当下模块的本子,如若数据库中的一个值与 module.xml 不包容, 它将推行升级代码。

重视。假使二个模块注重于另二个模块,module.xml 文件将有三个不一致通常声明,定义当前模块信任的模块列表。在此个事例中,大家将使大家的模块正视magento_catalog。

运用以下命令行代码,成立文件夹 app/code/Learning/FirstUnit/etc:

mkdir app/code/Learning/FirstUnit/etc

接下来把下部的代码:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Learning_FirstUnit" setup_version="0.0.1"> <sequence>
<module name="Magento_Catalog"/> </sequence>
    </module>
</config>

请在乎,在内定的xml文件中:

  • 模块名称: Learning_FirstUnit (基于我们创立的文本夹)
  • 本子: 0.0.1 (大家的模块的带头版本)
  • 依赖: Magento_Catalog. 大家得以有多重正视。在这里种情形下, 大家会把<module name=”..” /> 系列节点下的节点。

咱俩须要运用的步骤来成功这个职务:

始建运行脚本

app/main.js是大家运用的进口。它担当创立主窗口和拍卖系统事件。 main.js 应该如下所示:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// app/main.js
 
// 应用的控制模块
var app = require('app');
 
// 创建原生浏览器窗口的模块
var BrowserWindow = require('browser-window');
var mainWindow = null;
 
// 当所有窗口都关闭的时候退出应用
app.on('window-all-closed'function () {
  if (process.platform != 'darwin') {
    app.quit();
  }
});
 
// 当 Electron 结束的时候,这个方法将会生效
// 初始化并准备创建浏览器窗口
app.on('ready'function () {
 
  // 创建浏览器窗口.
  mainWindow = new BrowserWindow({ width: 800, height: 600 });
 
  // 载入应用的 index.html
  mainWindow.loadUrl('file://' __dirname  '/index.html');
 
  // 打开开发工具
  // mainWindow.openDevTools();
  // 窗口关闭时触发
  mainWindow.on('closed'function () {
 
    // 想要取消窗口对象的引用,如果你的应用支持多窗口,
    // 通常你需要将所有的窗口对象存储到一个数组中,
    // 在这个时候你应该删除相应的元素
    mainWindow = null;
  });
   
});

创建registration.php 文件

各类模块必需有其一文件,它报告Magento如何牢固模块。继续我们的事例,制造文件app/code/Learning/FirstUnit/registration.php。然后把下边包车型地铁从头到尾的经过放进去:

<?php MagentoFrameworkComponentComponentRegistrar::register(
MagentoFrameworkComponentComponentRegistrar::MODULE, 'Learning_FirstUnit',
__DIR__
);

registration.php 是全数模块都遵照近似格局的尺度文件。

独一分裂的是模块名,在大家的例子中是Learning_FirstUnit

  1. 创立新模块.
  2. 创建 InstallSchema 脚本.
  3. 创建 InstallData 脚本.
  4. 丰硕一个新模块并表达创立数据表。
  5. 创建 UpgradeSchema 脚本.
  6. 创建 UpgradeData 脚本.
  7. 运转进级脚本并验证表已改造。

通过 DOM 访谈原生

正如自己上边提到的那么,Electron 使您能够直接在 web 页面中访谈本地 npm 模块和原生 API。你能够如此创制app/index.html文件:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<body>
  <h1>Hello World!</h1>
  We are using Electron
  <script>  document.write(process.versions['electron']) </script>
  <script> document.write(process.platform) </script>
  <script type="text/javascript">
     var fs = require('fs');
     var file = fs.readFileSync('app/package.json');
     document.write(file);
  </script>
</body>
</html>

app/index.html是叁个简便的 HTML 页面。在此,它经过运用 Node’s fs (file system) 模块来读取package.json文件并将其内容写入到 document body 中。

运行 “setup:upgrade” 命令

运转此命令令你的新模块主动打招呼Magento的留存。

php bin/magento setup:upgrade

它应有相应大批量的出口,此中一行应该是Learning_FirstUnit. 验证此行代码是或不是留存。

让我们走过每一步。

运营应用

比如你创制好了等级次序布局、app/index.html、app/main.js和app/package.json,你很只怕想要尝试去运作起来的 Electron 应用来测量检验并保管它平常专门的学业。

若是您以前在系统中全局安装了electron-prebuilt,就足以透过上面包车型客车授命运维应用:

electron app

在那间,electron是运营 electron shell 的一声令下,app是我们使用的目录名。如若您不想将 Election 安装到您全局的 npm 模块中,能够在命令提示行中经过上面三令五申使用当地npm_modules文件夹下的 electron 来运维应用。

"node_modules/.bin/electron" "./app"

固然你可以这么来运作应用,可是本身或许提出您在gulpfile.js中创立贰个 gulp task ,那样您就足以将你的天职和 Visual Studio Code 编辑器相结合,大家会在下局地呈现。

?

1
2
3
4
5
6
7
8
9
// 获取依赖
var gulp        = require('gulp'),
  childProcess  = require('child_process'),
  electron      = require('electron-prebuilt');
 
// 创建 gulp 任务
gulp.task('run'function () {
  childProcess.spawn(electron, ['./app'], { stdio: 'inherit' });
});

运作你的 gulp 职分:gulp run。我们的施用看起来会是这么些样子:

反省新模块是或不是处于激活状态

到方今停止,我们还未增加任何有效的代码到大家的模块-它依旧是空的(因此无形的卡塔尔。 为了求证它已被认同,检查文件 app/etc/env.php. 它有一个自动生成模块的列表是活泼的。

手动校勘此列表!

cat app/etc/env.php | grep Learning_FirstUnit

接纳这几个步骤,你能够成功地成立Magento 2新模块。

翻看原来的作品

1:成立新模块

创制新模块 Learning_GreetingMessage.

进入app/code 文件夹和创办理文件件夹 LearningLearning/GreetingMessage:

$ cd <magento2_root>/app/code
$ mkdir Learning
$ mkdir Learning/GreetingMessage

前些天创造多个文件:

Learning/GreetingMessage/registration.php

/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

MagentoFrameworkComponentComponentRegistrar::register(
  MagentoFrameworkComponentComponentRegistrar::MODULE,
  'Learning_GreetingMessage',
  __DIR__
);

Learning/GreetingMessage/etc/module.xml

<?xml version="1.0"?>
<!--
/**
* Copyright © 2016 Magento. All rights reserved.
* * See COPYING.txt for license details.
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
  <module name="Learning_GreetingMessage" setup_version="0.0.1">
  </module>
</config>

安顿 Visual Studio Code 开荒条件

Visual Studio Code 是微软的生机勃勃款跨平台代码编辑器。VS Code 是依靠 Electron 和 微软自己的 Monaco Code Editor 开辟的。你能够在 这里 下载到 Visual Studio Code。

在 VS Code 中张开你的 electron 应用。

2: 创建 InstallSchema 脚本

始建一个InstallSchema脚本,在 app/code/Learning/GreetingMessage 文件夹 和成立一个Setup 文件夹。

$ cd <magento2_root>/app/code/Learning/GreetingMessage
$ mkdir Setup

创建 Setup/InstallSchema.php文件

/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

namespace LearningGreetingMessageSetup;
use MagentoFrameworkSetupInstallSchemaInterface;
use MagentoFrameworkSetupModuleContextInterface;
use MagentoFrameworkSetupSchemaSetupInterface;

/**
 * @codeCoverageIgnore
 */
class InstallSchema implements InstallSchemaInterface
{
    /**
    * {@inheritdoc}
    * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
    */
    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
          /**
          * Create table 'greeting_message'
          */
          $table = $setup->getConnection()
              ->newTable($setup->getTable('greeting_message'))
              ->addColumn(
                  'greeting_id',
                  MagentoFrameworkDBDdlTable::TYPE_INTEGER,
                  null,
                  ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                  'Greeting ID'
              )
              ->addColumn(
                  'message',
                  MagentoFrameworkDBDdlTable::TYPE_TEXT,
                  255,
                  ['nullable' => false, 'default' => ''],
                    'Message'
              )->setComment("Greeting Message table");
          $setup->getConnection()->createTable($table);
      }
}

让大家花点时间探问代码。

installschema文件都以可怜独立的。 主代码位于install() 方法,有一个 $setup 参数。 那是二个最首要参数,因为它提供了拜访 Connection() 允许数据库操作的。

连接是 MagentoFrameworkDBAdapterPdoMysql 叁个实例类。

Magento使用DDL(数据定义语言卡塔 尔(阿拉伯语:قطر‎来支配数据库。 你可以在Magento 2主旨代码找到DDL的各个例子。

配置 Visual Studio Code Task Runner

有广大自动化的工具,像创设、打包和测验等。大家基本上从命令行中运营这一个工具。VS Code task runner 使您能够将你自定义的天职集成到花色中。你能够在您的品种中一贯运行grunt,、gulp,、MsBuild 或然其余职务,那并无需移步到命令行。

VS Code 可以自动物检疫查实验你的 grunt 和 gulp 职责。按下ctrl shift p然后键入Run Task敲击回车便可。

您将从gulpfile.js或gruntfile.js文件中拿走具备有效的职责。

只顾:你须要保险gulpfile.js文件存在于您使用的根目录下。

ctrl shift b会从您职责实践器(task runner卡塔 尔(英语:State of Qatar)中实践build职分。你能够应用task.json文件来隐讳职务集成。按下ctrl

  • shift p然后键入Configure Task敲击回车。那将会在你项目中成立八个.setting的文书夹和task.json文件。纵然你不断想要试行轻巧的天职,你必要在task.json中张开安顿。举个例子你只怕想要通过按下Ctrl
  • Shift B来运维应用,你能够如此编辑task.json文件:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "version""0.1.0",
  "command""gulp",
  "isShellCommand"true,
  "args": [ "--no-color" ],
  "tasks": [
    {
      "taskName""run",
      "args": [],
      "isBuildCommand"true
    }
  ]
}

根部分注脚命令为gulp。你能够在tasks部分写入你想要的越来越多职务。将一个职务的isBuildCommand设置为 true 意味着它和Ctrl Shift B进行了绑定。近日 VS Code 只扶植五个一级职责。

至今,若是你按下Ctrl Shift B,gulp run将会被实施。

你能够在 这里 阅读到越来越多关于 visual studio code 职责的音信。

3:创建 InstallData 脚本

创建 Setup/InstallData.php 文件:

/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace LearningGreetingMessageSetup;

use MagentoFrameworkSetupInstallDataInterface;
use MagentoFrameworkSetupModuleContextInterface;
use MagentoFrameworkSetupModuleDataSetupInterface;

/**
 * @codeCoverageIgnore
 */
class InstallData implements InstallDataInterface
{

    /**
     * {@inheritdoc}
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
          /**
           * Install messages
           */
          $data = [
              ['message' => 'Happy New Year'],
              ['message' => 'Marry Christams']
          ];
          foreach ($data as $bind) {
              $setup->getConnection()
                ->insertForce($setup->getTable('greeting_message'), $bind);
          }
    }
}

调试 Electron 应用

开发调节和测量试验面板点击配置按键就能够在.settings文件夹内创建三个launch.json文件,包罗了调治的配备。

大家没有要求运维 app.js 的配备,所以移除它。

后天,你的launch.json应该如下所示:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
  "version""0.1.0",
  // 配置列表。添加新的配置或更改已存在的配置。
  // 仅支持 "node" 和 "mono",可以改变 "type" 来进行切换。
  "configurations": [
    {
      "name""Attach",
      "type""node",
      // TCP/IP 地址. 默认是 "localhost"
      "address""localhost",
      // 建立连接的端口.
      "port": 5858,
      "sourceMaps"false
     }
   ]
}

依照下边所示改正在此之前创制的 gulprun义务,那样大家的 electron 将会采取调节和测量试验格局运转,5858 端口也会被监听。

?

1
2
3
gulp.task('run'function () {
  childProcess.spawn(electron, ['--debug=5858','./app'], { stdio: 'inherit' });
});

在调解面板中精选 “Attach” 配置项,点击最早(run卡塔尔国可能按下 F5。稍等片刻后你应当就能够在上部看见调节和测量试验命令面板。

4: 加多新模块并表明成立数据表

以后是运营安装脚本并表明带有开始数据的表的时候了,所以大家将运营setup:upgrade 脚本。

$ cd <magento2_root>
$ php bin/magento setup:upgrade

您应有见到一长串包涵的模块Learning_GreetingMessage.

现今让大家连年数据库: mysql -u<user> -p<password> <database>

SHOW TABLES LIKE “%greeting%”

 ------------------------------------ 
| Tables_in_magento_210 (%greeting%) |
 ------------------------------------ 
| greeting_message                   |
 ------------------------------------ 

SELECT * FROM greeting_message;

 ------------- ----------------- 
| greeting_id | message         |
 ------------- ----------------- 
| 1           | Happy New Year  |
| 2           | Happy Holidays  |
 ------------- ----------------- 

创建 AngularJS 应用

率先次接触 AngularJS?浏览 官方网站 或一些 Scotch Angular 教程 。

那生龙活虎部分会讲明怎么样运用 AngularJS 和 MySQL 数据库创造贰个主顾保管(Customer Manager卡塔 尔(阿拉伯语:قطر‎应用。那个动用的指标不是为了重申 AngularJS 的中坚概念,而是显示怎样在 GiHub 的 Electron 中同期选拔 AngularJS 和 NodeJS 以至 MySQL 。

我们的买主保管采取正如上面这样归纳:

  • 客户列表

  • 增多新客户

  • 筛选删除三个主顾

  • 寻觅钦赐的主顾

检查表和数据是还是不是留存

那是怎么专业的? 当你创建新模块运维 bin/magento setup:upgrade 脚本,Magento的检查代码,看有未有安装模块。 假使它找到任何,它检查是还是不是有别的安装脚本,要是是的话,运维它们。 在此未来,Magento更新表格setup_module提议关于模块的版本新闻有:

SELECT * FROM setup_module WHERE module='Learning_GreetingMessage';

 -------------------------- ---------------- -------------- 
| module                   | schema_version | data_version |
 -------------------------- ---------------- -------------- 
| Learning_GreetingMessage | 0.0.1          | 0.0.1        |
 -------------------------- ---------------- -------------- 

种类结构

咱俩的选拔在 app 文件夹下,目录结构如下所示:

主页是app/index.html文件。app/scripts文件夹包涵全数用在该利用中的关键脚本和视图。有众多艺术能够用来公司利用的文本。

这边小编更赏识奉公守法职能来组织脚本文件。各类成效都有它协调的文件夹,文件夹中有模板和调整器。获取更多关于目录结构的消息,能够阅读 AngularJS 最棒试行: 目录结构

在初叶 AngularJS 应用以前,大家将应用 bower 安装客商端方面包车型地铁依赖性。即使您还还未有 Bower 先要安装它。在命令提醒行上将当前职业目录切换至你使用的根目录,然后遵照上面包车型地铁授命安装信任。

?

1
bower install angular angular-route angular-material --save

5: 创建 UpgradeSchema 脚本

要查看晋级脚本如何行事,我们将向数据库加多一些数额。

先是,更正版本在 etc/module.xml 文件为0.0.2:

<module name="Learning_GreetingMessage" setup_version="0.0.2">

制造文件 Setup/UpgradeSchema.php:

/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace LearningGreetingMessageSetup;

use MagentoFrameworkSetupUpgradeSchemaInterface;
use MagentoFrameworkSetupModuleContextInterface;
use MagentoFrameworkSetupSchemaSetupInterface;

/**
 * Upgrade the Catalog module DB scheme
 */
class UpgradeSchema implements UpgradeSchemaInterface
{
    /**
     * {@inheritdoc}
     */
    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();
        if (version_compare($context->getVersion(), '0.0.2', '<')) {
            $setup->getConnection()->addColumn(
                $setup->getTable('greeting_message'),
                'season',
                [
                    'type' => MagentoFrameworkDBDdlTable::TYPE_TEXT,
                    'length' => 16,
                    'nullable' => false,
                    'default' => '',
                    'comment' => 'Season'
                ]
            );
        }
        $setup->endSetup();
    }
}

注意“version_compare”线。 如前所述,该upgradescript将每回的本子中实践module.xml。 因而,我们只愿意近日的版本进级脚本推行,并不是先前的升迁。 那就是干吗我们把提高放入“要是”条目。

安装数据库

在此个事例中,小编将接纳一个名为customer-manager的数据库和一张名叫customers的表。上面是数据库的导出文件,你能够根据本条便捷开端。

?

1
2
3
4
5
6
7
8
9
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`)
);

6: 创建 UpgradeData 脚本

开创文件 Setup/UpgradeData.php:

/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace LearningGreetingMessageSetup;

use MagentoFrameworkSetupUpgradeDataInterface;
use MagentoFrameworkSetupModuleContextInterface;
use MagentoFrameworkSetupModuleDataSetupInterface;

/**
 * Upgrade Data script
 */

class UpgradeData implements UpgradeDataInterface
{
    /**
     * {@inheritdoc}
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
     */
    public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();
        if ($context->getVersion()
            && version_compare($context->getVersion(), '0.0.2') < 0
        ) {
            $table = $setup->getTable('greeting_message');
            $setup->getConnection()
                ->insertForce($table, ['message' => 'Happy Thanksgiving, 'season' => 'fall']);

            $setup->getConnection()
                ->update($table, ['season' => 'winter'], 'greeting_id IN (1,2)');
        }
        $setup->endSetup();
    }
}

成立二个 Angular Service 和 MySQL 举行人机联作

借使您的数据库和表都计划好了,就可以起来制造一个 AngularJS service 来直接从数据库中获取数据。使用node-mysql那几个 npm 模块使 service 连接数据库——一个应用 JavaScript 为 NodeJs 编写的 MySQL 驱动。在你 Angular 应用的app/ 目录下安装node-mysql模块。

留意:大家将 node-mysql 模块安装到 app 目录下并非运用的根目录,是因为我们需求在最终的 distribution 中饱含那几个模块。

在指令提示行中切换专业目录至 app 文件夹然后根据上面所示安装模块:

npm install --save mysql

我们的 angular service —— app/scripts/customer/customerService.js 如下所示:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
(function () {
    'use strict';
    var mysql = require('mysql');
 
    // 创建 MySql 数据库连接
    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是二个精简的自定义 angular service,它提供了对表customers的底工 CRUD 操作。直接在 service 中央银行使了 node 模块mysql。若是你早已怀有了壹当中间隔的数据服务,你也能够应用它来替代之。

7: 运转晋级脚本并验证表已改造

咱俩会另行运转setupupgrade脚本:

$ cd <magento2_root>
$ php bin/magento setup:upgrade

现行反革命,大家能够连接到数据库,并证实大家的更改:

select * from greeting_message;

 ------------- -------------------- -------- 
| greeting_id | message            | season |
 ------------- -------------------- -------- 
| 1           | Happy New Year     | winter |
| 2           | Happy Holidays     | winter |
| 3           | Happy Thanksgiving | fall   |
 ------------- -------------------- -------- 

控制器 & 模板

app/scripts/customer/customerController中的customerController如下所示:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
(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;  
 
        // 载入初始数据
        getAllCustomers();
 
        //----------------------
        // 内部方法
        //----------------------
 
        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];
                });
            }
        }
    }
 
})();

我们的买主模板( app/scripts/customer/customer.html 卡塔 尔(阿拉伯语:قطر‎使用了 angular material 组件来创设 UI,如下所示:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<div style="width:100%" layout="row">
    <md-sidenav class="site-sidenav md-sidenav-left md-whiteframe-z2"
                md-component-id="left"
                md-is-locked-open="$mdMedia('gt-sm')">
 
        <md-toolbar layout="row" class="md-whiteframe-z1">
            <h1>Customers</h1>
        </md-toolbar>
        <md-input-container style="margin-bottom:0">
            <label>Customer Name</label>
            <input required name="customerName" ng-model="_ctrl.filterText" ng-change="_ctrl.filter()">
        </md-input-container>
        <md-list>
            <md-list-item ng-repeat="it in _ctrl.customers">
                <md-button ng-click="_ctrl.selectCustomer(it, $index)" ng-class="{'selected' : it === _ctrl.selected }">
                    {{it.name}}
                </md-button>
            </md-list-item>
        </md-list>
    </md-sidenav>
 
    <div flex layout="column" tabIndex="-1" role="main" class="md-whiteframe-z2">
 
        <md-toolbar layout="row" class="md-whiteframe-z1">
            <md-button class="menu" hide-gt-sm ng-click="ul.toggleList()" aria-label="Show User List">
                <md-icon md-svg-icon="menu"></md-icon>
            </md-button>
            <h1>{{ _ctrl.selected.name }}</h1>
        </md-toolbar>
 
        <md-content flex id="content">
            <div layout="column" style="width:50%">
                <br />
                <md-content layout-padding class="autoScroll">
                    <md-input-container>
                        <label>Name</label>
                        <input ng-model="_ctrl.selected.name" type="text">
                    </md-input-container>
                    <md-input-container md-no-float>
                        <label>Email</label>
                        <input ng-model="_ctrl.selected.email" type="text">
                    </md-input-container>
                    <md-input-container>
                        <label>Address</label>
                        <input ng-model="_ctrl.selected.address"  ng-required="true">
                    </md-input-container>
                    <md-input-container md-no-float>
                        <label>City</label>
                        <input ng-model="_ctrl.selected.city" type="text" >
                    </md-input-container>
                    <md-input-container md-no-float>
                        <label>Phone</label>
                        <input ng-model="_ctrl.selected.phone" type="text">
                    </md-input-container>
                </md-content>
                <section layout="row" layout-sm="column" layout-align="center center" layout-wrap>
                    <md-button class="md-raised md-info" ng-click="_ctrl.createCustomer()">Add</md-button>
                    <md-button class="md-raised md-primary" ng-click="_ctrl.saveCustomer()">Save</md-button>
                    <md-button class="md-raised md-danger" ng-click="_ctrl.cancelEdit()">Cancel</md-button>
                    <md-button class="md-raised md-warn" ng-click="_ctrl.deleteCustomer()">Delete</md-button>
                </section>
            </div>
        </md-content>
 
    </div>
</div>

app.js 满含模块开首化脚本和平运动用的路由配置,如下所示:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
(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: '/' });
        }
    ]);
 
})();

终极是大家的首页 app/index.html

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<html lang="en" ng-app="app">
    <title>Customer Manager</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge"gt;
    <meta name="description" content="">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
    <!-- build:css assets/css/app.css -->
    <link rel="stylesheet" href="../bower_components/angular-material/angular-material.css" />
    <link rel="stylesheet" href="assets/css/style.css" />
    <!-- endbuild -->
<body>
    <ng-view></ng-view>
    <!-- build:js scripts/vendor.js -->
    <script src="../bower_components/angular/angular.js"></script>
    <script src="../bower_components/angular-route/angular-route.js"></script>
    <script src="../bower_components/angular-animate/angular-animate.js"></script>
    <script src="../bower_components/angular-aria/angular-aria.js"></script>
    <script src="../bower_components/angular-material/angular-material.js"></script>
    <!-- endbuild -->
    
    <!-- build:app scripts/app.js -->
    <script src="./scripts/app.js"></script>
    <script src="./scripts/customer/customerService.js"></script>
    <script src="./scripts/customer/customerController.js"></script>
    <!-- endbuild -->
</body>
</html>

设若你早已如上边那样陈设过 VS Code task runner 的话,使用gulp run命令或然按下Ctrl Shif B来运维你的利用。

构建 AngularJS 应用

为了创设大家的 Angular 应用,须要安装gulp-uglify,gulp-minify-css和gulp-usemin信任包。

?

1
npm install --save gulp-uglify gulp-minify-css gulp-usemin

开垦你的gulpfile.js并且引进需要的模块。

?

1
2
3
4
5
6
7
8
9
10
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');

假设营造目录已经存在的话,清理一下它。

?

1
2
3
gulp.task('clean'function (callback) {
  return destDir.dirAsync('.', { empty: true });
});

复制文件到塑造目录。大家并不须要使用复制功用来复制 angular 应用的代码,在下有个别中usemin将会为我们做那件事请:

?

1
2
3
4
5
6
7
8
9
10
11
gulp.task('copy', ['clean'], function () {
    return projectDir.copyAsync('app', destDir.path(), {
        overwrite: true, matching: [
            './node_modules/**/*',
            '*.html',
            '*.css',
            'main.js',
            'package.json'
       ]
    });
});

大家的创设任务将动用 gulp.src() 获取 app/index.html 然后传递给 usemin。然后它会将出口写入到营造目录并且把 index.html 中的援用用优化版代码替换掉 。

小心: 千万毫无遗忘在 app/index.html 像那样定义 usemin 块:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- build:js scripts/vendor.js -->
<script src="../bower_components/angular/angular.js"></script>
<script src="../bower_components/angular-route/angular-route.js"></script>
<script src="../bower_components/angular-animate/angular-animate.js"></script>
<script src="../bower_components/angular-aria/angular-aria.js"></script>
<script src="../bower_components/angular-material/angular-material.js"></script>
<!-- endbuild -->
     
<!-- build:app scripts/app.js -->
<script src="./scripts/app.js"></script>
<script src="./scripts/customer/customerService.js"></script>
<script src="./scripts/customer/customerController.js"></script>
<!-- endbuild -->

营造职分如下所示:

?

1
2
3
4
5
6
7
gulp.task('build', ['copy'], function () {
  return gulp.src('./app/index.html')
    .pipe(usemin({
      js: [uglify()]
    }))
    .pipe(gulp.dest('build/'));
});

为发行(distribution)做准备

在此大器晚成有的大家将把 Electron 应用打包至分娩条件。在根目录成立塑造脚本build.windows.js。那么些剧本用于 Windows 上。对于其余平台来讲,你应该创造充裕平台湾特务定的本子并且依照平台来运作。

可以在node_modules/electron-prebuilt/dist目录中找到二个特出的 electron distribution。这里是构建 electron 应用的步调:

  • 咱俩珍视的天职是复制 electron distribution 到我们的dist目录。

  • 每叁个 electron distribution 都带有三个暗许的施用在dist/resources/default_app中 。大家须要用我们最后营造的采纳来替换它。

  • 为了掩护大家的运用源码和财富,你能够筛选将你的行使打包成多个 asar 归档,那会变动一些你的源码。一个 asar 归档是三个简易的相似 tar 的格式,它会将你富有的文本拼接成单个文件,Electron 能够在不解压整个文件的事态下从当中读取自便文件。

在乎:这意气风发有个别说述的是 windows 平台下的包裹。别的平新北的步骤是平等的,只是路线和采取的文件不等同而已。你能够在 github 中拿走 OSx 和 linux 的后生可畏体化创设脚本。

设置创设 electron 要求的依赖:npm install --save q asar fs-jetpack recedit

接下去,初阶化我们的塑造脚本,如下所示:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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() {
    // 项目路径是应用的根目录
    projectDir = jetpack;
    // 构建目录是最终应用被构建后放置的目录
    buildDir = projectDir.dir('./dist', { empty: true });
    // angular 应用目录
    appDir = projectDir.dir('./build');
    // angular 应用的 package.json 文件
    manifest = appDir.read('./package.json''json');
    return Q();
}

那边大家利用fs-jetpacknode 模块举办文件操作。它提供了越来越灵敏的文书操作。

复制 Electron Distribution

从electron-prebuilt/dist复制默许的 electron distribution 到我们的 dist 目录

?

1
2
3
function copyElectron() {
     return projectDir.copyAsync('./node_modules/electron-prebuilt/dist', buildDir.path(), { overwrite: true });
}

理清暗中认可使用

您能够在resources/default_app文件夹内找到一个暗许的 HTML 应用。大家需求用大家和好的 angular 应用来替换它。依据上面所示移除它:

留意:这里的门径是指向 windows 平台的。对于别的平台经过是大器晚成律的,只是路线不等同而已。在 OSX 南路线应该是 Contents/Resources/default_app

?

1
2
3
function cleanupRuntime() {
     return buildDir.removeAsync('resources/default_app');
}

创建 asar 包

?

1
2
3
4
5
6
7
function createAsar() {
     var deferred = Q.defer();
     asar.createPackage(appDir.path(), buildDir.path('resources/app.asar'), function () {
         deferred.resolve();
     });
     return deferred.promise;
}

那将会把您 angular 应用的有着文件打包到一个 asar 包文件里。你能够在dist/resources/目录中找到 asar 文件。

退换为温馨的行使财富

下一步是将暗中认可的 electron icon 替换来你谐和的,更新付加物的新闻然后重命名应用。

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function updateResources() {
    var deferred = Q.defer();
 
    // 将你的 icon 从 resource 文件夹复制到构建文件夹下
    projectDir.copy('resources/windows/icon.ico', buildDir.path('icon.ico'));
 
    // 将 Electron icon 替换成你自己的
    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;
}
// 重命名 electron exe
function rename() {
    return buildDir.renameAsync('electron.exe', manifest.name  '.exe');
}

创立原生安装包

你能够应用 wix 或 NSIS 创制 windows 安装包。这里大家尽量使用更加小更加灵活的 NSIS,它很合乎互联网使用。使用 NSIS 能够创立支持使用设置时要求的任何事情的安装包。

在 resources/windows/installer.nsis 中创建 NSIS 脚本

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
!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 "SoftwareMicrosoftWindowsCurrentVersionUninstall${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=$PLUGINSDIRbanner.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 $PLUGINSDIRbanner.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" '"$INSTDIRicon.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}" "" "$INSTDIRicon.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

在build.windows.js文件中创设一个称作createInstaller的函数,如下所示:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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;
 
}

您应当设置了 NSIS,何况有限补助它在你的门路中是可用的。creaeInstaller函数会读取安装包脚本况兼依据NSIS 运维时接纳makensis命令来试行。

将她们组成到一块儿

成立三个函数把具有的一些放在一块儿,为了使 gulp 职责能够取获得然后输出它:

?

1
2
3
4
5
6
7
8
9
10
function build() {
    return init()
            .then(copyElectron)
            .then(cleanupRuntime)
            .then(createAsar)
            .then(updateResources)
            .then(rename)
            .then(createInstaller);
}
module.exports = { build: build };

进而,在gulpfile.js中开创 gulp 职责来举办这几个创设脚本:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var release_windows = require('./build.windows');
var os = require('os');
gulp.task('build-electron', ['build'], function () {
    switch (os.platform()) {
        case 'darwin':
        // 执行 build.osx.js
        break;
        case 'linux':
        //执行 build.linux.js
        break;
        case 'win32':
        return release_windows.build();
    }
});

运作下边三令五申,你应该就能够获得终极的出品:

gulp build-electron

你最终的 electron 应用应该在dist目录中,並且目录结构应当和下部是日常的:

澳门新浦京娱乐场网站 2

总结

Electron 不仅是三个帮忙打包 web 应用成为桌面应用的原生 web view。它今后包含 app 的活动进级、Windows 安装包、崩溃报告、布告和局地别样有效的原生 app 作用——全数的那个都由此JavaScript API 调用。

到方今结束,一点都不小规模的施用使用 electron 创造,包罗闲聊应用、数据库微电脑、地图设计器、合营规划工具和手提式有线电话机原型等。

本文由澳门新浦京娱乐场网站发布于www.146.net,转载请注明出处:澳门新浦京娱乐场网站:构建桌面应用,Magento