编者按:本文作者Berwin,W3C性能工作组成员,360导航资深前端工程师。《深入浅出Vue.js》作者。
两月以后,看着电脑,我回想起接到通知说要开发小程序引擎的那个下午。当时的我以为,这个小程序和其他小程序都不一样,因为它是个假的,其实是个网页。两月之后,我才发现,“噢~原来大家都是这么做的啊”。
最近一直在做小程序的底层实现,过程中磕磕绊绊也多次进行架构方向上的转型,趁着周末抽空写一篇文章记录一下开发过程中遇到的问题和一些思考与决策。
本篇文章更多的是在描述架构与技术方向层面的思考和决策,不会过多介绍具体某个问题是如何解决的,因为细节实在太多。
1. 单线程
当时的我将我们的小程序定位成一个SPA单页应用,因为我们的小程序的宿主环境是浏览器。
它只是看起来像小程序(因为这个窗口没有地址栏什么的),但其实包括UI渲染和事件交互在内的绝大部分功能都是基于Web技术,虽然会提供Native和OS的一些能力与API,但本质上其实是个网页。又考虑到目前很多人使用第三方工具用Vue或React写小程序,我就在思考:“反正本质上就是一个网页,那为什么不原生内置Vue让用户直接用Vue的语法写小程序呢?”。
所以当时定了一个基本方向:让开发者使用Vue开发我们的小程序,开发体验完全与Web保持一致。
虽然开发体验与Web保持一致,但是Web技术实在是太开放了,开发者可以为所欲为。这种情况在小程序中是不允许的,不允许使用<iframe>、不允许<a>直接外跳到其他在线网页、不允许开发者触碰DOM、不允许使用某些未知的危险API等。
所以遇到的第一个问题是如何禁止用户在Vue的模板中使用iframe或a或其他不允许使用的东西。
若想做到这一点就不得不对Vue的渲染层进行一个托管与改造。
1.1 改造Vue
对Vue进行改造通常有两种方案:
使用类似polyfill的手法覆盖一些Vue原生提供的API
Fork一个Vue出来自己改
第一个方案能力有限,有一些Vue内部的逻辑没有办法通过polyfill的形式更改。第二种方案的缺陷是如果我只想修改Vue中的某一块逻辑,其他我不修改的部分如果有Bug,Vue官方更新了版本我没有办法同步。
这两种方案都有缺陷和不足,所以我没有使用这两个其中的任何一个,我使用了另一个方案,我觉得应该是目前为止最好的一种方案。
我简单介绍一下这种方案:
把Vue.js装到node_modules里
项目里使用webpack,并设置上别名
把自己想改造的那部分代码copy到自己的项目目录中进行修改
因为我需要对渲染层进行改造,所以我需要重设web这个别名,如下:
const path = require('path')
module