您的位置:首页 > 其它

Ionic3 与Electron制作桌面应用

2017-11-13 20:23 309 查看
Ionic3 与Electron制作桌面应用

原文:https://medium.com/@LohaniDamodar/lets-make-desktop-application-with-ionic-3-and-electron-44316f82901d

ionic:https://ionicframework.com

electron:https://electron.atom.io

ionic是一个混合开发框架,electron是一个开发跨平台桌面应用的框架。

此教程包括三个步骤:

1. 创建ionic项目,开启服务

2. 在项目中添加electron依赖

3. 添加webpack配置和electron主体脚本以electron的方式运行项目

在教程第二部分,首先会创建一个简单的angular2服务来访问electron的api;然后给不同平台编译分包。

最终源代码地址:https://github.com/lohanitech/ion-electron

准备工作和预备知识:

1 安装和了解ionic

2 安装和了解electron

1. 创建Ionic项目,开启服务

运行如下命令


ionic start ion-electron


进入ion-electron文件夹运行:


ionic serve


可以在本地浏览器中输入 http://localhost:8100 预览效果

2. 在项目中安装electron依赖

在项目中运行如下命令:


npm install electron electron-builder foreman --save-dev


electron是我们要整合进来的一个桌面开发

electron-builder用于编译electron的脚本

foreman用于模拟多进程的node包。

安装完成后,package.json如下:

"name": "ion-electron",
"author": {
"name": "Damodar Lohani",
"email": "example@example.com",
"url": "https://lohanitech.com/members/damodar-lohani"
},
"description": "ionic framework based electron project",
"main": "electron/electron.js",
"config": {
"ionic_bundler": "webpack",
"ionic_webpack": "./config/webpack.config.js"
},
"build": {
"appId": "com.lohanitech.ionic-electron-test",
"electronVersion": "1.7.5",
"asar":false,
"files": [
"www/**/*",
"electron/*"
]
}


3. 添加webpack配置和electron主体脚本以electron的方式运行项目

在项目中新建一个文件夹名为config,并在其中加入一个文件名为webpack.config.js,将如下代码复制进去。

首先是ionic相关的配置,(目前位于 node_modules/@ionic/app-scripts/config/webpack.config.js),在源文件中加入:

externals: [

(function () {

var IGNORES = ["fs","child_process","electron","path","assert","cluster","crypto","dns","domain","events","http","https","net","os","process","punycode","querystring","readline","repl","stream","string_decoder","tls","tty","dgram","url","util","v8","vm","zlib"];

return function (context, request, callback) {

if (IGNORES.indexOf(request) >= 0) {

return callback(null, "require('" + request + "')");

}

return callback();

};

})()

],


最新的webpack配置变为如下(最新的配置文件我们需要在dev配置和production配置中添加):

/*

* The webpack config exports an object that has a valid webpack configuration

* For each environment name. By default, there are two Ionic environments:

* "dev" and "prod". As such, the webpack.config.js exports a dictionary object

* with "keys" for "dev" and "prod", where the value is a valid webpack configuration

* For details on configuring webpack, see their documentation here

* https://webpack.js.org/configuration/
*/
var path = require('path');

var webpack = require('webpack');

var ionicWebpackFactory = require(process.env.IONIC_WEBPACK_FACTORY);
var ModuleConcatPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin');

var PurifyPlugin = require('@angular-devkit/build-optimizer').PurifyPlugin;
var optimizedProdLoaders = [

{

test: /\.json$/,

loader: 'json-loader'

},

{

test: /\.js$/,

loader: [

{

loader: process.env.IONIC_CACHE_LOADER

},
{

loader: '@angular-devkit/build-optimizer/webpack-loader',

options: {

sourceMap: true

}

},

]

},

{

test: /\.ts$/,

loader: [

{

loader: process.env.IONIC_CACHE_LOADER

},
{

loader: '@angular-devkit/build-optimizer/webpack-loader',

options: {

sourceMap: true

}

},
{

loader: process.env.IONIC_WEBPACK_LOADER

}

]

}

];
function getProdLoaders() {

if (process.env.IONIC_OPTIMIZE_JS === 'true') {

return optimizedProdLoaders;

}

return devConfig.module.loaders;

}
var devConfig = {

entry: process.env.IONIC_APP_ENTRY_POINT,

output: {

path: '{{BUILD}}',

publicPath: 'build/',

filename: '[name].js',

devtoolModuleFilenameTemplate: ionicWebpackFactory.getSourceMapperFunction(),

},

externals: [ (function () { var IGNORES = ["fs","child_process","electron","path","assert","cluster","crypto","dns","domain","events","http","https","net","os","process","punycode","querystring","readline","repl","stream","string_decoder","tls","tty","dgram","url","util","v8","vm","zlib"]; return function (context, request, callback) { if (IGNORES.indexOf(request) >= 0) { return callback(null, "require('" + request + "')"); } return callback(); }; })() ],

devtool: process.env.IONIC_SOURCE_MAP_TYPE,
resolve: {

extensions: ['.ts', '.js', '.json'],

modules: [path.resolve('node_modules')]

},
module: {

loaders: [

{

test: /\.json$/,

loader: 'json-loader'

},

{

test: /\.ts$/,

loader: process.env.IONIC_WEBPACK_LOADER

}

]

},
plugins: [

ionicWebpackFactory.getIonicEnvironmentPlugin(),

ionicWebpackFactory.getCommonChunksPlugin()

],
// Some libraries import Node modules but don't use them in the browser.

// Tell Webpack to provide empty mocks for them so importing them works.

node: {

fs: 'empty',

net: 'empty',

tls: 'empty'

}

};
var prodConfig = {

entry: process.env.IONIC_APP_ENTRY_POINT,

output: {

path: '{{BUILD}}',

publicPath: 'build/',

filename: '[name].js',

devtoolModuleFilenameTemplate: ionicWebpackFactory.getSourceMapperFunction(),

},

externals: [ (function () { var IGNORES = ["fs","child_process","electron","path","assert","cluster","crypto","dns","domain","events","http","https","net","os","process","punycode","querystring","readline","repl","stream","string_decoder","tls","tty","dgram","url","util","v8","vm","zlib"]; return function (context, request, callback) { if (IGNORES.indexOf(request) >= 0) { return callback(null, "require('" + request + "')"); } return callback(); }; })() ],

devtool: process.env.IONIC_SOURCE_MAP_TYPE,
resolve: {

extensions: ['.ts', '.js', '.json'],

modules: [path.resolve('node_modules')]

},
module: {

loaders: getProdLoaders()

},
plugins: [

ionicWebpackFactory.getIonicEnvironmentPlugin(),

ionicWebpackFactory.getCommonChunksPlugin(),

new ModuleConcatPlugin(),

new PurifyPlugin()

],
// Some libraries import Node modules but don't use them in the browser.

// Tell Webpack to provide empty mocks for them so importing them works.

node: {

fs: 'empty',

net: 'empty',

tls: 'empty'

}

};
module.exports = {

dev: devConfig,

prod: prodConfig

}


这是ionic的webpack配置,只需稍作改动就可以与electron一起使用了。

添加election主脚本

在项目内创建一个文件夹名为electron,在其中新建一个electron.js。这个是创建和加载electron窗口的主脚本。打开electron.js,贴入以下代码:

'use strict';

const electron = require('electron');

// Module to control application life.

const {

app } = electron;

// Module to create native browser window.

const {

BrowserWindow

} = electron;
let win;
function createWindow() {

// Create the browser window.

win = new BrowserWindow({

width: 1024,

height: 600

});
var url = 'file://' + __dirname + '/../www/index.html';

var Args = process.argv.slice(2);

Args.forEach(function (val) {

if (val === "test") {

url = 'http://localhost:8100'

}

});
// and load the index.html of the app.

win.loadURL(url);
// Open the DevTools.

win.webContents.openDevTools();
// Emitted when the window is closed.

win.on('closed', () => {

// 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.

win = null;

});

}
// This method will be called when Electron has finished

// initialization and is ready to create browser windows.

// Some APIs can only be used after this event occurs.

app.on('ready', createWindow);
// Quit when all windows are closed.

app.on('window-all-closed', () => {

// On OS X it is common for applications and their menu bar

// to stay active until the user quits explicitly with Cmd + Q

if (process.platform !== 'darwin') {

app.quit();

}

});
app.on('activate', () => {

// On OS X it's common to re-create a window in the app when the

// dock icon is clicked and there are no other windows open.

if (win === null) {

createWindow();

}

});


在package.json中加入启动脚本

在package.json的scripts中贴入以下代码:

"scripts": {

"dev": "nf start",

"start":"ionic-app-scripts serve",

"electron dist": "electron .",

"ebuild":"npm run build && node_modules/.bin/build",

"clean": "ionic-app-scripts clean",

"build": "ionic-app-scripts build",

"ionic:build": "ionic-app-scripts build",

"ionic:serve": "ionic-app-scripts serve"

}


由于现在加入了foreman,我们需要给他添加配置。在项目根目录下新建文件Procfile,贴入代码:


ionic: npm start

electron: node electron-wait-ionic.js



在根目录下新建electron-wait-ionic.js,更新如下:

const net = require('net');

const port = 8100;
process.env.E_URL = `http://localhost:${port}`;
const client = new net.Socket();
let startedElectron = false;

const tryConnection = () => client.connect({port: port}, () => {

client.end();

if(!startedElectron) {

console.log('starting electron');

startedElectron = true;

const exec = require('child_process').exec;

exec('electron .');

}

}

);
tryConnection();
client.on('error', (error) => {

setTimeout(tryConnection, 1000);

});


这个脚本的作用是尝试连接端口8100,因为8100端口在electron接入的时候会激活。如果连接失败会接着连接。

此时,运行npm run dev会以开发模式运行项目。

由于electron在完全编译之前会运行服务,所以第一次可能会看到空白页面,发生这种情况的话可以根据console输出信息,在编译完成后按ctrl+r重新加载electron窗口即可。

正常工作的效果图如下:



完成此教程可以查看第二部分来学习如何在Ionic项目中访问electron的api
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: