electron 打包web应用

时下流行的web app打包工具主要有两个,一个是国内开发者主导的nw.js,另一个是国外大厂支撑的electron。对比了nw.js以及electron之后还是选择了electron,原因主要有以下几点:

  • 1、基于该工具已有广泛被使用的产品,如:atomvs code等。
  • 2、在开发者中口碑比较好,有大公司参与进来,遇到问题,提个issue能很快得到响应。

下载基于electron打包的HolaStudio。


使用webpack编译项目

HolaStudio离线版本打包的时候需要把服务器、客户端打包到一个安装包内。所以第一步首先要把服务器代码混淆,为接下来打包做准备。

构建工具选择了webpack, 关于构建工具没有做很细致的筛选,因为我都不熟悉:)。所以就听从朋友建议,选择了入了webpack的坑。

关于webpack的使用,官方有详细的文档说明,github自行搜索。

webpack需要一个配置文件(webpack.config.js),用来描述项目的环境,以及第三方插件的集成等信息:


var webpack = require('webpack');
var path = require('path');
var fs = require('fs-extra');
var packageJSON = fs.readJsonSync('./package.json');

var nodeModules = {};
fs.readdirSync('./node_modules')
  .filter(function(x) {
    return ['.bin', '.npminstall'].indexOf(x) === -1;
  })
  .filter(function(y) {
    return !(y in packageJSON.devDependencies);
  })
  .forEach(function(mod) {
    nodeModules[mod] = 'commonjs ' + mod;
});

module.exports = {
    entry: './app.js',
    target: 'node',
    context: __dirname,
    node: {
        __dirname: false,
        __filename: false
    },  
    output: {
        path: path.join(__dirname, 'output'),
        filename: 'output.js',
        externals: nodeModules,
    },
    externals: nodeModules,
    plugins: [
        new webpack.optimize.UglifyJsPlugin({compress: {warnings: false}}),
        new webpack.IgnorePlugin(/\.(css|less)$/)
    ]
}

简要的说明:
- entry: 指定项目的入口文件,即启动node服务指定的文件
- target: 指定当前的编译环境为node, 其他选择有webwebworker
- context: 指定一个路径找到entry文件
- node: 用于指定一些nodejs环境配置 __dirname=false 表示启用__dirname 变量(默认为’/’), __filename=false 表示启用__filename 变量(默认为’/index.js’)。
- output: 指定编译输出文件及目录
- externals: 指定外部依赖库文件
- plugins: webpack插件集成,这里主要用到了一个混淆插件

运行 webpack . 会在当前目录下的output 文件夹得到编译输出文件。


安装electron以及相关工具

  • 运行命令npm i -g electron-prebuilt 安装electron

简要说说关于electron的设计理念:

electron打包的应用分为主进程和渲染进程,渲染进程使用Chromium来展示页面,主进程以类似创建窗口的方式创建网页。主进程具备调用系统相关服务的功能,主进程和渲染进程之间以进程间通信的方式交互。 更详细的electron说明文档.

在打包HolaStudio的过程中,选择把node服务端代码放在主进程,编辑器放在一个渲染进程。

electron项目的构建目录结构:

在该目录下运行electron .即可调式electron应用。

所以在启动electron应用的过程中,需要启动node后台的同时创建一个渲染窗口显示编辑器。


//处理windows 应用安装以及更新时刻的默认事件  
if(require('electron-squirrel-startup')) return;

var app = require('app');
var path = require('path');
var electron = require('electron');
var BrowserWindow = require('browser-window');
var globalShortcut = require('global-shortcut');

var mainWindow = null;
var webContents = null;

//所有窗口被关闭
app.on('window-all-closed', function() {
  // 在 OS X 上,通常用户在明确地按下 Cmd + Q 之前
  // 应用会保持活动状态
    if(process.platform != 'darwin') {
        app.quit();
    }
});

//当前应用准备退出
app.on('will-quit', function() {
    globalShortcut.unregisterAll();
});

// 当 Electron 完成了初始化并且准备创建浏览器窗口的时候
app.on('ready', function() {
    global.mainProcess = app;
    require('./hola_studio.js');
    registerShortcut();
});

//hola_studio 服务器发出`done`事件后,准备渲染编辑器界面
app.on('done', function(url) {
    var electronScreen = electron.screen;
    var size = electronScreen.getPrimaryDisplay().workAreaSize;
    mainWindow = new BrowserWindow({resizable: true, width: size.width, height: size.height,
        title: 'HolaStudio'});
    mainWindow.loadURL(url);
    webContents = mainWindow.webContents;
    mainWindow.on('closed', function() {
        mainWindow = null;
        webContents = null;
    });
});

//注册快捷键用于打开开发者工具以及刷新当前页面
function registerShortcut() {
    function doRegister(cmd, callback) {
        globalShortcut.register(cmd, callback);
    }

    doRegister('F12', function() {
        var win = BrowserWindow.getFocusedWindow();
        win.webContents.toggleDevTools();
        console.log("toggleDevTools F12");
    });

    //windows 平台下`F12`按键按下收不到消息(貌似还没有解决方案),所以写了一个替代按键
    doRegister('F6', function() {
        var win = BrowserWindow.getFocusedWindow();
        win.webContents.toggleDevTools();
        console.log("toggleDevTools F6");
    });

    doRegister('F5', function() {
        var win = BrowserWindow.getFocusedWindow();
        win.reload();
        console.log("refresh");
    });

    return;
}

如果之前有做过MFCQT类GUI的开发,对electron这样的工作流程一定非常熟悉。


安装electron-builder工具来编译安装包

electron-builder把几个不同平台的安装包编译工具集成到一起,得到一个统一的接口,方便使用。

electron-builder 建议把构建目录分为两层,上面一层主要管理编译工具、构建所需的资源以及构建的输出,称之为dev 目录。下面一层则为以electron为入口的工程目录,称之为app 目录。

dev目录预览:

app目录预览:

需要做的工作很简单:
- 安装构建工具(electron、electron-prebuilder)
- 修改dev目录下package.json指定编译脚本
- 修改app目录下package.json指定编译选项
- 运行脚本编译安装包

dev 目录下package.json预览:

{
  "name": "HolaStudio",
  "version": "0.0.1",
  "homepage": "http://studio.holaverse.cn",
  "description": "HolaStudio Release Version.",
  "scripts": {
    "dist": "npm run dist:linux && npm run dist:win",
    "dist:osx": "build --platform darwin --arch all -d",
    "dist:win": "build --platform win32 --arch all -d",
    "dist:linux": "build --platform linux --arch all -d"
  },
  "keywords": [
    "HolaStudio"
  ],
  "author": "holaverse Tech Inc.",
  "license": "ISC",
  "devDependencies": {
    "electron-builder": "^2.11.0",
    "electron-prebuilt": "^0.37.2"
  },
  "build": {
    "osx": {
      "title": "HolaStudio",
      "background": "build/background.png",
      "icon": "build/icon.icns",
      "icon-size": 128,
      "contents": [
        {
          "x": 355,
          "y": 125,
          "type": "link",
          "path": "/Applications"
        },
        {
          "x": 155,
          "y": 125,
          "type": "file"
        }
      ]
    }
  }
}
  • scripts字段指定npm编译不同平台的运行脚本。
  • build指定编译时载入的资源配置

app 目录下package.json增加编译时配置选项(最新版本electron-builder已经把它提出到dev目录下的package.json)
javascript
"build": {
"asar": false,
"iconUrl": "http://7xsec6.com1.z0.glb.clouddn.com/icon.ico",
"app-bundle-id": "holaverse.studio",
"app-category-type": "public.app-category.productivity"
},

- asar告诉打包工具,不要压缩资源文件,因为在HolaStudio运行过程中,需要频繁改动项目路径下文件。
- iconUrl指定windows安装包icon url
- app-bundle-id/public.app-category.productivity,mac平台下编译选项

更详细的配置文档请看这里。

成功打包了各种平台的安装包后,后续需要做的是阅读electron文档,在有新需求的时候能够很快的处理掉。

你可能感兴趣的:(前端技术,Nodejs)