NW.js 入坑指南
NW.js是什么?
NW.js 是基于 Chromium 和 Node.js 运行的, 以前也叫nodeWebkit。这就给了你使用HTML和JavaScript来制作桌面应用的可能。在应用里你可以直接调用Node.js的各种api以及现有的第三方包。因为Chromium和 Node.js 的跨平台,那么你的应用也是可以跨平台的。现在已经有很多知名的应用是基于NW.js实现,这是官方统计的一些列表: https://github.com/nwjs/nw.js/wiki/List-of-apps-and-companies-using-nw.js
Getting Started
先下载好最新版的 NW.js,官方网站地址。
我就以 nwjs-v0.12.3-win-x64为例子,先看下有哪些文件吧。
/app/ 目录是项目的具体代码; /package.json 是我添加的,等下再讲它的作用;
项目根目录下的其他文件都是NW.js自带的;
项目结构
具体的代码可以到 github 围观;
我把项目的代码都放在app目录下,然后以版本号区别开,比如这里的v0.0.1;这么做的目的是为后面的版本更新,更新的办法后面会详细说;
/app/v0.0.1/assest/ 放置一些资源文件,具体的就不介绍了,等下会介绍下/app/v0.0.1/assest/read.js;
/app/v0.0.1/node_modules/ 放置一些第三方包、通过npm管理;
/app/v0.0.1/index.html 项目的入口页面,这里我演示了如何使用第三方包 node-read 来获取一个网页的正文,具体代码可以点这里;
/app/v0.0.1/node-main.js/ 在 package.json里指定;可以在客户端崩溃的情况下,也记录下错误 具体的介绍查看这里;
/app/v0.0.1/package.json/ 告诉NW.js各种信息的配置文件,具体介绍查看这里;
package.json解析
每个配置项的说明查看这里;
{
"name": "demo-app",
"main": "./app/v0.0.1/index.html",//指定项目主页面
"build": "1445048139741",//这是为了给更新时判断版本用的
"version": "0.0.1",//当前版本
"homepage": "http://nero-zou.com",
"description": "Nw.js Demo",
"window": {
"title": "Nw.js Demo",//如果 index.html没有title,则会显示这里的值
"icon": "assest/img/logo.png",
"position": "center",
"width": 1280,
"height": 680,
"toolbar": true,//是否隐藏窗口的工具条
"frame": true,//是否显示最外层的框架,设为false之后 窗口的最小化、最大化、关闭 就没有了
"resizable": true,
"min_width": 1028
},
"node-main": "./app/v0.0.1/node-main.js",//node-main.js 位置
"contributors": [
{
"name": "邹志强",
"email": "Nero@nero-zou.com",
"web": "http://nero-zou.com"
}
],
"dependencies": { //依赖的包
"MD5": "1.2.1",
"cheerio": "^0.19.0",
"fetch": "^0.3.6",
"node-read": "^0.1.6"
}
}
代码加密保护
有些情况下,代码还是不能直接暴露给用户的;我们可以使用V8 Snapshot 的方式来达到代码加密保护的目的;
具体的方式是使用 /nwjs.exe 来运行 nwjc source.js core.bin命令,然后再index.html里使用require('nw.gui').Window.get().evalNWBin(null, './app/v0.0.1/core.bin');(注意这里的路径,是相对于nw.exe的位置)将代码引入到项目中;
可以查看 使用V8 shapshot 比不使用的变化 ;
注意 使用V8 Snapshot 还是有一些限制的 ,比如官方提到的这些;
还有就是加密的代码里不要使用 let、const这些关键字,我曾经就因为这个始终编译不通过;
自动更新
更新分为两种情况:
仅仅项目的代码需要更新
nw.js本身也需要更新;
通常情况下,不会遇到需要更新nw.js 本身的情况,因为当选定一个版本的NW.js后,就认定它了,除非遇到了什么无法解决的BUG;
那我们先实现仅更新项目的代码这种情况吧,这个比较简单;前面介绍项目接口就提到 /app/v0.0.1/ 就是放置V0.0.1的所有代码的位置;
那么如果要更新到V0.0.2,那我们新建一个文件夹 /app/V0.0.2,然后把V0.0.2的代码都放到这个文件下,然后把/package.json替换成新版本的package.json;这样重启客户端之后,然会读取v0.0.2的代码了。具体的更新代码就不写了,可以把新版本的代码打包成zip包,然后客户端下载好,解压就行。
下面说说NW.js本身也需要更新的情况吧,这个目前我还没遇到,所以只能提供一个思路,由于nw.exe在运行时,我们是不能替换它的,那么肯定需要用别的可执行文件来替换它了,我猜钉钉的实现方式就是这种思路:
项目打包发布
一般都是使用NSIS来打包,但是别忘了在打包前,把需要保护的代码加密,然后删除源文件。干这些机械、无聊的事当然不能让自己来做,必须使用Gulp.js来啊。还能把顺便把代码压缩、文件合并什么的也干了。
一些小坑
里面带的调试工具是不能打断点的,webstorm可以配置,然后就可以断点调试了;
使用NSIS打包别忘了加上文件夹权限的控制,不然会遇到文件无法写入的情况;
NW.js 入坑指南的更多相关文章
- electron入坑指南
electron入坑指南 简介 electron 实际集成chrome浏览器和node环境, 运行你写的网页 app 基本目录结构 index.html 名称可以不是index, 这个文件与普通网页的 ...
- C语言入坑指南-被遗忘的初始化
前言 什么是初始化?为什么要初始化?静态变量和局部变量的初始化又有什么区别?实际应用中应该怎么做?本文将一一回答这些问题. 什么是初始化 初始化指的是对数据对象或者变量赋予初始值.例如: int va ...
- Elasticsearch入坑指南之RESTful API
Elasticsearch入坑指南之RESTful API Tags:Elasticsearch ES为开发者提供了非常丰富的基于Http协议的Rest API,通过简单的Rest请求,就可以实现非常 ...
- ElasticSearch入坑指南之概述及安装
---恢复内容开始--- ElasticSearch入坑指南之概述及安装 了解ElasticSearch ElasticSearch(简称ES)基于Lucene的分布式全文检索引擎.使用ES可以实现近 ...
- eclipse中导入外部包却无法查看对应源码或Javadoc的入坑指南
eclipse中导入外部包却无法查看对应源码或Javadoc的 入坑指南 出现这个错误的原因是,你虽然导入了.jar包,但没有配置对应的Javadoc或源码路径,所以在编辑器中无法查看源 码和对应AP ...
- Rust入坑指南:核心概念
如果说前面的坑我们一直在用小铲子挖的话,那么今天的坑就是用挖掘机挖的. 今天要介绍的是Rust的一个核心概念:Ownership.全文将分为什么是Ownership以及Ownership的传递类型两部 ...
- Rust入坑指南:鳞次栉比
很久没有挖Rust的坑啦,今天来挖一些排列整齐的坑.没错,就是要介绍一些集合类型的数据类型."鳞次栉比"这个标题是不是显得很有文化? 在Rust入坑指南:常规套路一文中我们已经介绍 ...
- Rust入坑指南:亡羊补牢
如果你已经开始学习Rust,相信你已经体会过Rust编译器的强大.它可以帮助你避免程序中的大部分错误,但是编译器也不是万能的,如果程序写的不恰当,还是会发生错误,让程序崩溃.所以今天我们就来聊一聊Ru ...
- Rust入坑指南:朝生暮死
今天想和大家一起把我们之前挖的坑再刨深一些.在Java中,一个对象能存活多久全靠JVM来决定,程序员并不需要去关心对象的生命周期,但是在Rust中就大不相同,一个对象从生到死我们都需要掌握的很清楚. ...
随机推荐
- 阻塞IO、非阻塞IO的区别
1.类与类之间的关系:依赖,实现,泛化(继承),关联,组合,聚合. 1)依赖(虚线):一个类是 另一个类的函数参数 或者 函数返回值. 2)实现(实线加小圆):对纯虚函数类(抽象类)的实现. 3)继承 ...
- unity, 3dmax制作的morph(blendshape)导入unity中使用注意事项
在实现<乱纪元大冒险>(见:http://www.cnblogs.com/wantnon/p/4857072.html)中由于质子展开失败形成的变形几何体和眼睛.几何体经过一系列形变最后变 ...
- 在Visual Studio 2013顯示SCSS詳細錯誤訊息
在WebEssentials套件加持之下,Visual Studio 2013可以直接編修SCSS,每次存檔自動編譯出css.min.css及.map,非常方便.但初心者如我,寫錯語法在所難免,一旦造 ...
- Spark-shell 无法启动之网络问题
由于需要首次手动安装sbt,需要联网,故将虚拟机的网络适配器模式设置为"桥接模式",这样就可以和互联网相连接. 但是后面执行"spark-shell --master ...
- 转:python之如何在某文件中调用其他文件内的函数
假设名为A.py的文件需要调用B.py文件内的C(x,y)函数 情形1:在同一目录下, (1) import B if __name__ == "__main__": B.C(x, ...
- redis命令_ZADD
ZADD key score member [[score member] [score member] ...] 将一个或多个 member 元素及其 score 值加入到有序集 key 当中. 如 ...
- AxureRP_for_chorme的安装和使用方法
1.下载AxureRP_for_chorme_version.crx 2.打开Chrome,右上角菜单图标->更多->扩展程序 3.将crx文件拖入,安装 4.选中AxureRP的“已启用 ...
- 浅谈P2P终结者原理及其突破
P2P终结者按正常来说是个很好的网管软件,但是好多人却拿它来,恶意的限制他人的流量,使他人不能正常上网,下面我们就他的功能以及原理还有突破方法做个详细的介绍! 我们先来看看来自在网上PSP的资料:P2 ...
- httpclient 优化
(1)采用单例模式(重用HttpClient实例) 对于一个通信单元甚至是整个应用程序,Apache强烈推荐只使用一个HttpClient的实例.例如: private static HttpC ...
- extjs经典form的submit()和ajax()
extjs 的submit: // 发送请求 this.formPanel.getForm().submit({ u ...