一套代码小程序&Web&Native运行的探索07——mpvue简单调研

  最近工作比较忙,加之上个月生了小孩,小情人是各种折腾他爸妈,我们可以使用的独立时间片不多,虽然这块研究进展缓慢,但是一直做下去,肯定还是会有一些收获的
  
  之前我们这个课题研究一直是做独立的研究,没有去看已有的解决方案,这个是为了保证一个自己独立的思维,无论独立的思维还是人格都是很重要的东西,然独学而无友则孤陋而寡闻,稍微有点自己的东西后,还是应该看看外面已有的东西了,今天的目标是mpvue,我们来看看其官方描述:
  
  mpvue (github 地址请参见)是一个使用 Vue.js 开发小程序的前端框架。框架基于 Vue.js 核心,mpvue 修改了 Vue.js 的 runtime 和 compiler 实现,使其可以运行在小程序环境中,从而为小程序开发引入了整套 Vue.js 开发体验。
  
  使用 mpvue 开发小程序,你将在小程序技术体系的基础上获取到这样一些能力:
  
  彻底的组件化开发能力:提高代码复用性
  
  完整的 Vue.js 开发体验
  
  方便的 Vuex 数据管理方案:方便构建复杂应用
  
  快捷的 webpack 构建机制:自定义构建策略、开发阶段 hotReload
  
  支持使用 npm 外部依赖
  
  使用 Vue.js 命令行工具 vue-cli 快速初始化项目
  
  H5 代码转换编译成小程序目标代码的能力
  
  似乎,mpvue已经完成了我们想要做的工作,如果他真的好用,我们去学习吸收他也不失为一个好的方式,于是我们便去试试他的5分钟上手教程,简单编译后便形成了小程序代码,运行之:
  
  这里最终生成的代码已经可以完全适配小程序了,我们这里主要来看看其app.json的配置:
  
  复制代码
  
  {
  
  "pages": [
  
  "pages/index/main",
  
  "pages/logs/main",
  
  "pages/counter/main"
  
  ],
  
  "window": {
  
  "backgroundTextStyle": "light",
  
  "navigationBarBackgroundColor": "#fff",
  
  "navigationBarTitleText": "WeChat",
  
  "navigationBarTextStyle": "black"
  
  }
  
  }
  
  复制代码
  
  这里设置了起始页面,每个目录下都是main作为入口,我们简单看一下main的写法
  
  <import src="/pages/index/index.vue.wxml" /><template is="b26bd43a" data="{{ ...$root['0'], $root }}"/>
  
  都很一致,其中奇怪的template id就是真实的模板,然后我们看看源文件src:
  
  index.vue
  
  import Vue from 'vue'
  
  import App from 'www.365soke.com/./index'
  
  const app = new Vue(App)
  
  app.$mount()
  
  mpvue原理研究
  
  可以看到,mpvue经过一次编译后,通过一个制定的规则,将vue的写法的页面,变成了小程序可以识别的代码,这里我们再回看其实现部分描述:
  
  mpvue 修改了 Vue.js 的 runtime 和 compiler 实现,使其可以运行在小程序环境中,从而为小程序开发引入了整套 Vue.js 开发体验
  
  mpvue-template-compiler 提供了将 vue 的模板语法转换到小程序的 wxml 语法的能力
  
  这里我们回到Vue的部分,稍加说明,Vue现在已经做为了一套完整的解决方案而存在,特别是weex的出现后,框架出了platforms目录,经过之前的学习,我们知道:
  
  我们在项目中写的html结构会被翻译为虚拟dom vnode从而形成ast(虚拟语法树),只要有了这个ast,不管后续容器是什么,可以是浏览器、可以是服务器端、也可以是native端,我们可以轻易的根据这个ast生成我们要的html结构:
  
  el('ul', {id: 'list'}, [
  
  el('li', {class: 'item'}, ['Item 1']),
  
  el('li', {class: 'item'}, ['Item 2']),
  
  el('li', {class: 'item'}, ['Item 3'])
  
  ])
  
  这段代码(数据结构)可以很轻易被翻译为html结构,比如:
  
  1 <ul id='list'>
  
  2   <li class='item'>Item 1</li>
  
  3   <li class='item'>Item 2</li>
  
  4   <li class='item'>Item 3</li>
  
  5 </ul>
  
  也可以很轻易的被映射成Native视图代码,而我们知道其实我们习惯中的html代码其实并不是必须的,比如这段代码事实上会被变成这个样子:
  
  new Vue({
  
  template: '<div a="aaa">www.leyouzaixian2.com<div>www.furong157.com</div></div>'
  
  })
  
  ===>等价的
  
  复制代码
  
  new Vue({
  
  render: function (www.huarenyl.cn) {
  
  return this._h(www.hjpt521.com 'div', {
  
  attrs:{
  
  a: 'aaa'
  
  }
  
  }, [
  
  this._h('div')
  
  ])
  
  }
  
  })
  
  复制代码
  
  platforms的工作就是解决的是要讲ast转换为html结构还是native页面,显然,我们拿着vue解析后的ast可以形成小程序能够识别的代码片段,为了证明我们的猜想我们来看看mpvue的代码(详情看这里):
  
  在web环境下,我们直接借用snabbdom对比两颗虚拟DOM的差异,直接完成渲染生成HTML,而mpvue完成的工作是将Vue的html模板编译为小程序识别的代码,其中一些差异,比如vue模板中指令处理会全部被磨平,我们这里来看一段代码,以下是for指令编译时候的处理:
  
  复制代码
  
  export default www.120xh.cn{
  
  if: 'wx:if',
  
  iterator1: 'wx:for-index',
  
  key: 'wx:key',
  
  alias: 'wx:for-item',
  
  'v-for': 'wx:for'
  
  }
  
  复制代码
  
  复制代码
  
  import astMap from '../config/astMap'
  
  export default function (ast) {
  
  const { iterator1, for: forText, key, alias, attrsMap } = ast
  
  if (forText) {
  
  attrsMap[astMap['v-for']] = `{{${forText}}}`
  
  if (iterator1) {
  
  attrsMap[astMap['iterator1']] = iterator1
  
  }
  
  if (key) {
  
  attrsMap[astMap['key']www.mhylpt.com] = key
  
  }
  
  if (alias) {
  
  attrsMap[astMap[www.michenggw.com'alias']] = alias
  
  }
  
  delete attrsMap['v-for']
  
  }
  
  return ast
  
  }
  
  复制代码
  
  可以看到,mpvue其实在vue的基础上,在vue标签的处理下,改变ast中的一些属性,对等翻译成了小程序识别的代码,当然截止此时都还只是一些猜想,我们接下来深入demo的核心看看
  
  代码编译-webpack
  
  对于前端工程师来说,webpack已经成为了一种必备技能了,他包含了本地开发、编译压缩、性能优化的所有工作,这个是工程化统一化思维集大成的结果(虽然绕不开但有点难用)
  
  webpack是现在最常用的JavaScript程序的静态模块打包器(module bundler),他的特点就是以模块(module)为中心,我们只要给一个入口文件,他会根据这个入口文件找到所有的依赖文件,最后捆绑到一起,这里盗个图:
  
  这里几个核心概念是:
  
  ① 入口 - 指示webpack应该以哪个模块(一般是个js文件),作为内部依赖图的开始
  
  ② 输出 - 告诉将打包后的文件输出到哪里,或者文件名是什么
  
  ③ loader - 这个非常关键,这个让webpack能够去处理那些非JavaScript文件,或者是自定义文件,转换为可用的文件,比如将jsx转换为js,将less转换为css
  
  test就是正则标志,标识哪些文件会被处理;use表示用哪个loader
  
  ④ 插件(plugins)
  
  插件被用于转换某些类型的模块,适用于的范围更广,包括打包优化、压缩、重新定义环境中的变量等等,这里举一个小例子进行说明,react中的jsx这种事实上是浏览器直接不能识别的,但是我们却可以利用webpack将之进行一次编译:
  
  // 原 JSX 语法代码
  
  return <h1>Hello,Webpack</h1>
  
  // 被转换成正常的 JavaScript 代码
  
  return React.createElement('h1', null, www.gcyl159.com'Hello,Webpack')
  
  这个便是Babel所做的工作,我们要做的就是为我们的项目提供这样的解析器,比如babel-preset-react
  
  我们前面说过,mpvue是我们以vue的语法写代码,并将其编译为小程序识别的代码,而这个工作是由webpack执行的,所以我们来看看mpvue的几个配置文件:
  
  package.json
  
  复制代码
  
  "scripts": {
  
  "dev:wx": "node build/dev-server.js wx",
  
  "start:wx": "npm run dev:wx",
  
  "build:wx": "node build/build.js wx",
  
  "dev:swan": "node build/dev-server.js swan",
  
  "start:swan": "npm run dev:swan",
  
  "build:swan": "node build/build.js swan",
  
  "dev": "node build/dev-www.gcyl152.com server.js wx",
  
  "start": "npm run dev",
  
  "build": "node build/build.js wx",
  
  "lint": "eslint --ext .js,.vue src"
  
  },
  
  复制代码
  
  然后我们看看其webpack的配置(build/dev-server.js):
  
  View Code
  
  里面比较关键的代码在此:
  
  webpack.base.conf.js
  
  {
  
  test: /\.vue$/,
  
  loader: 'mpvue-loader',
  
  options: vueLoaderConfig
  
  },
  
  关键就落到了我们这里的mpvue-loader了,他是自 vue-loader 修改而来,主要为 webpack 打包 mpvue components 提供能力,mpvue-loader 是 vue-loader 的一个扩展延伸版,类似于超集的关系,除了 vue-loader 本身所具备的能力之外,它还会产出微信小程序所需要的文件结构和模块内容。
  
  详细的说明文档在:http://mpvue.com/build/mpvue-loader/,https://github.com/mpvue/mpvue-loader
  
  我们这里简单看看他是怎么做的,这里以wxml做下研究,先看看这个简单的转换:
  
  复制代码
  
  <template>
  
  <div class="my-component">
  
  <h1>{{msg}}</h1>
  
  <other-component :msg="msg"></other-component>
  
  </div>
  
  </template>
  
  复制代码
  
  模板部分会变成这个样子:
  
  复制代码
  
  <import src="components/other-component$hash.wxml" />
  
  <template name="component$hash">
  
  <view class="my-component">
  
  <view class="_h1">{{msg}}</view>
  
  <template is="other-component$hash" wx:if="{{ $c[0] }}" data="{{ ...$c[0] }}"></template>
  
  </view>
  
  </template>
  
  复制代码
  
  而这块工作的进行在这:mpvue-template-compiler 提供了将 vue 的模板语法转换到小程序的 wxml 语法的能力
  
  这里的代码有点多,涉及到了很多东西,今天篇幅很大了,等我们明天研究下vue-loader再继续学习吧......

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值