微信小程序 在Chrome浏览器上运行以及WebStorm的使用


Posted in Javascript onSeptember 27, 2016

「微信小程序」的开发框架体验起来,还不错——自带了UI框架。但是问题是他的IDE,表现起来相当的糟糕——其实主要是因为,我当时买WebStorm License买了好多年。所以,我觉得他的IDE真不如我这个付费好用。

而且,作为一个拥护自由和开源的 「GitHub 中国区首席Markdown程序员」。微信在「微信小程序」引导着Web开向封闭,我们再也不能愉快地分享我们的代码了。

如果我们放任下去,未来的Web世界令人堪忧。

好了,废话说完了:

文章太长不想看,可以直接看Demo哈哈:

GitHub: https://github.com/phodal/weapp-webdemo
预览:http://weapp.phodal.com/

真实世界下的MINA三基本元素

「微信小程序」的背后运行的是一个名为MINA框架。在之前的几篇文章里,我们介绍得差不多了。现在让我们来作介绍pipeline:

Transform wxml和wxss

当我们修改完WXML、WXSS的时候,我们需要重新编译项目才能在浏览器上看到效果。这时候后台就会执行一些transform动作:

1.wcc来转换wxml为一个genrateFun,执行这个方法将会得到一个virtual dom
2.wxss就会转换wxss为css——这一点有待商榷。

wcc和wxss,可以从vendor目录下获取到,在“微信web开发者工具”下敲入help,你就会得到下面的东东:

微信小程序 在Chrome浏览器上运行以及WebStorm的使用

运行openVendor(),你就会得到上面的wcss、wxss、WAService.js、WAWebview.js四个文件了。

Transform js文件

对于js文件来说,则是一个拼装的过程,如下是我们的app.js文件:

App({
onLaunch: function () { }
})

它在转换后会变成:

define("app.js", function(require, module){var window={Math:Math}/*兼容babel*/,location,document,navigator,self,localStorage,history,Caches;
  App({
   onLaunch: function () {

   }
  })
});
require("app.js");

我假装你已经知道这是什么了,反正我也不想、也不会解释了~~。同理于:

define("pages/index/index.js", function(require, module){var window={Math:Math}/*兼容babel*/,location,document,navigator,self,localStorage,history,Caches;
  Page({
   data: {
    text: initData
   }
  });
 require("pages/index/index.js");

至于它是如何replace或者apend到html中,我就不作解释了。

MINA如何运行?

为了运行一个Page,我们需要有一个virtual dom,即用wcc转换后的函数,如:

 

/*v0.7cc_20160919*/
  var $gwxc
  var $gaic={}
  $gwx=function(path,global){
   function _(a,b){b&&a.children.push(b);}
   function _n(tag){$gwxc++;if($gwxc>=16000){throw 'enough, dom limit exceeded, you don\'t do stupid things, do you?'};return {tag:tag.substr(0,3)=='wx-'?tag:'wx-'+tag,attr:{},children:[]}}
   function _s(scope,env,key){return typeof(scope[key])!='undefined'?scope[key]:env[key]}
   function _wl(tname){console.warn('template `' + tname + '` is being call recursively, will be stop.')}
   function _ai(i,p,e,me){var x=_grp(p,e,me);if(x)i.push(x);else{console.warn('path `'+p+'` not found from `'+me+'`')}}
   function _grp(p,e,me){if(p[0]!='/'){var mepart=me.split('/');mepart.pop();var ppart=p.split('/');for(var i=0;i<ppart.length;i++){if( ppart[i]=='..')mepart.pop();else if(!ppart[i])continue;else mepart.push(ppart[i]);}p=mepart.join('/');}if(me[0]=='.'&&p[0]=='/')p='.'+p;if(e[p])return p;if(e[p+'.wxml'])return p+'.wxml';}
//以下省略好多字。

然后在我们的html中加一个script,如

document.dispatchEvent(new CustomEvent("generateFuncReady", {
  detail: {
   generateFunc: $gwx('index.wxml')
  }
 }))

就会凑发这个事件了。我简单的拆分了WXWebview.js得到了几个功能组件:

  1. define.js,这里就是定义AMD模块化的地方
  2. exparser.js,用于转换WXML标签到HTML标签
  3. exparser-behvaior.js,定义不同标签的一些行为
  4. mobile.js,应该是一个事件库,好像我并不关心。
  5. page.js,核心代码,即Page、App的定义所在。
  6. report.js,你所说的一切都能够用作为你的呈堂证供。
  7. virtual_dom.js,一个virtual dom实现结合wcc使用,里面应该还有component.css,也可能是叫weui
  8. wa-wx.js,定义微信各种API以及WebView和Native的地方,和下面的WX有冲突。
  9. wx.js,同上,但是略有不同。
  10. wxJSBridge.js,Weixin JS Bridge

于是,我就用上面的组件来定义不同的位置好了。当我们触发自定义的generateFuncReady事件时,将由virtual_dom.js来接管这次Render:

document.addEventListener("generateFuncReady", function (e) {
 var generateFunc = e.detail.generateFunc;
 wx.onAppDataChange && generateFunc && wx.onAppDataChange(function (e) {
  var i = generateFunc((0, d.getData)());
  if (i.tag = "body", e.options && e.options.firstRender){
   e.ext && ("undefined" != typeof e.ext.webviewId && (window.__webviewId__ = e.ext.webviewId), "undefined" != typeof e.ext.downloadDomain && (window.__downloadDomain__ = e.ext.downloadDomain)), v = f(i, !0), b = v.render(), b.replaceDocumentElement(document.body), setTimeout(function () {
    wx.publishPageEvent(p, {}), r("firstRenderTime", n, Date.now()), wx.initReady && wx.initReady()
   }, 0);
  } else {
   var o = f(i, !1), a = v.diff(o);
   a.apply(b), v = o, document.dispatchEvent(new CustomEvent("pageReRender", {}));
  }
 })
})

因此,这里就是负责DOM初始化的地方了,这里得到的Dom结果是这样的:

<wx-view class="btn-area">
 <wx-view class="body-view">
  <wx-text><span style="display:none;"></span><span></span></wx-text>
  <wx-button>add line</wx-button>
  <wx-button>remove line</wx-button>
 </wx-view>
</wx-view>

而我们写的wxml是这样的:

<view class="btn-area">
 <view class="body-view">
 <text>{{text}}</text>
 <button bindtap="add">add line</button>
 <button bindtap="remove">remove line</button>
 </view>
</view>

很明显view会被转换为wx-view,text会被转换为wx-text等等,以此类推。这个转换是在virtual dom.js中调用的,调用的方法就是exparser。

遗憾的是我现在困在 data初始化上面了~~,这里面有两套不同的事件系统,有一些困扰。其中有一个是:WeixinJSBridge、还有一个是app engine中的事件系统,两个好像不能互调。。。

使用WebStorm开发

在浏览器上运行之前,我们需要简单的mock一些方法,如:

  1. window.webkit.messageHandlers.invokeHandler.postMessage
  2. window.webkit.messageHandlers.publishHandler.postMessage
  3. WeixinJSCore.publishHandler
  4. WeixinJSCore..invokeHandler

然后把 config.json中的一些内容变成__wxConfig,如:

__wxConfig = {
 "debug": true,
 "pages": ["index"],
 "window": {
  "backgroundTextStyle": "light",
  "navigationBarBackgroundColor": "#fff",
  "navigationBarTitleText": "WeChat",
  "navigationBarTextStyle": "black"
 },
 "projectConfig": {

 },
 "appserviceConfig": {

 },
 "appname": "fdfafafafafafafa",
 "appid": "touristappid",
 "apphash": 2107567080,
 "isTourist": true,
 "userInfo": {}
}

如这里我们的appname是哈哈哈哈哈哈哈——我家在福建。

然后在我们的html中引入各个js文件,啦啦。

我们还需要一个自动化的glup脚本来watch wxml和wxss的修改,然后编译,如:

exec('./vendor/wcc -d ' + inputPath + ' > ' + outputFileName, function(err, stdout, stderr) {
   console.log(stdout);
   console.log(stderr);
});

说了这么多,你还不如去看代码好了:

GitHub: https://github.com/phodal/weapp-webdemo

预览:http://weapp.phodal.com/

通过此文,希望能帮助大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
jQuery-ui中自动完成实现方法
Jun 10 Javascript
jquery checkbox 勾选的bug问题解决方案与分析
Nov 13 Javascript
AngularJS入门教程(一):静态模板
Dec 06 Javascript
javascript数据结构与算法之检索算法
Apr 04 Javascript
jQuery实现带幻灯的tab滑动切换风格菜单代码
Aug 27 Javascript
JQuery EasyUI Layout 在from布局自适应窗口大小的实现方法
May 28 Javascript
使用JS代码实现点击按钮下载文件
Nov 12 Javascript
js中的eval()函数把含有转义字符的字符串转换成Object对象的方法
Dec 02 Javascript
最常用的jQuery表单验证(简单)
May 23 jQuery
AngularJS集合数据遍历显示的实例
Dec 27 Javascript
详解Node 定时器
Feb 26 Javascript
angular6.0使用教程之父组件通过url传递id给子组件的方法
Jun 30 Javascript
微信小程序 开发指南详解
Sep 27 #Javascript
纯JavaScript 实现flappy bird小游戏实例代码
Sep 27 #Javascript
jQuery实现表格文本框淡入更改值后淡出效果
Sep 27 #Javascript
angular基于路由控制ui-router实现系统权限控制
Sep 27 #Javascript
IOS中safari下的select下拉菜单文字过长不换行的解决方法
Sep 26 #Javascript
javascript动画之模拟拖拽效果篇
Sep 26 #Javascript
微信小程序(应用号)简单实例应用及实例详解
Sep 26 #Javascript
You might like
特转载一高手总结PHP学习资源和链接.
2006/12/05 PHP
PHP文件上传实例详解!!!
2007/01/02 PHP
php算开始时间到过期时间的相隔的天数
2011/01/12 PHP
PHP生成数组再传给js的方法
2014/08/07 PHP
PHP中的switch语句的用法实例详解
2015/10/21 PHP
discuz论坛更换域名,详细文件修改步骤
2020/12/09 PHP
PHP读取文件或采集时解决中文乱码
2021/03/09 PHP
jquery设置按钮停顿3秒不可用
2014/03/07 Javascript
基于JavaScript实现类似于百度学术高级检索功能
2016/03/02 Javascript
Wireshark基本介绍和学习TCP三次握手
2016/08/15 Javascript
浅谈jQuery hover(over, out)事件函数
2016/12/03 Javascript
jQuery UI Grid 模态框中的表格实例代码
2017/04/01 jQuery
Vue中的数据监听和数据交互案例解析
2017/07/12 Javascript
vue解决跨域路由冲突问题思路解析
2017/11/03 Javascript
nodejs使用http模块发送get与post请求的方法示例
2018/01/08 NodeJs
vue2.0 兄弟组件(平级)通讯的实现代码
2018/01/15 Javascript
Vue组件之自定义事件的功能图解
2018/02/01 Javascript
vue 引用自定义ttf、otf、在线字体的方法
2019/05/09 Javascript
微信小程序的授权实现过程解析
2019/08/02 Javascript
解决layer.confirm选择完之后消息框不消失的问题
2019/09/16 Javascript
使用Python编写基于DHT协议的BT资源爬虫
2016/03/19 Python
python如何实现视频转代码视频
2019/06/17 Python
Flask配置Cors跨域的实现
2019/07/12 Python
详解Python3 pandas.merge用法
2019/09/05 Python
如何基于Python获取图片的物理尺寸
2019/11/25 Python
Python pygame绘制文字制作滚动文字过程解析
2019/12/12 Python
Mytheresa美国官网:德国知名的女性奢侈品电商
2017/05/27 全球购物
时尚设计师手表:The Watch Cabin
2018/10/06 全球购物
银行给客户的感谢信
2015/01/23 职场文书
2016年国培研修日志
2015/11/13 职场文书
2016大一新生军训心得体会
2016/01/11 职场文书
2016学习全国教书育人楷模先进事迹心得体会
2016/01/21 职场文书
关于党风廉政建设宣传教育月的活动总结!
2019/08/08 职场文书
Redis基本数据类型Zset有序集合常用操作
2022/06/01 Redis
使用HBuilder制作一个简单的HTML5网页
2022/07/07 HTML / CSS
Django数据库(SQlite)基本入门使用教程
2022/07/07 Python