从零开始编写属于你的前端mvc框架 2
项目的工程化与基本架构
1. 前言
在 前一篇 中我们实现了基本的内容并发布了第一个release版本,但是显而易见的,这样一个结构对于长期维护是不太方便的,所以对项目作出一定的调整是必要的。
2. 项目工程化
2.1 webpack
我们的项目基本和绝大部分 spa 项目一致,只有一个html入口(即使有多个也没关系)
所以使用webpack是一个比较简单且良好的选择,首先我们的项目基本是一个完全的javascript项目,所以事实上,在短期内不太需要对css html的操作,我们只需要实现一个html入口即可。
接下来首先看看我们需要些什么?
- babel 我们需要代码转义,事实上我们的代码使用了不少es6的特性(甚至我还想用typescript呢),我们需要babel对项目进行转码
- eslint 没有一个开发者能保证自己的格式不出错,还是程序靠谱
- mocha 没有单元测试的js不是好js(好吧现在可能确实不太需要)
- hotload 怎么能没有热加载!难不成还要手动刷新不成!
- jsdoc 我注释写这么好,自动生成文档吧!
那么基于以上几点先做个基本的配置吧
2.2 babel
暂时我们不知道具体会用什么但是一下几个加上总不会出错的
2.3 eslint
首先我们从eslint standard继承一份配置过来然后稍稍改一下
- promise:我们还是需要检测promise的,这里上个plugin
- indent:缩进必须整整齐齐,上个4位差不多了,switch case就1倍即可
- spaced-comment:对于comment我们就不检测了吧
- no-trailing-spaces: 行末尾的空格我对这个需求不大,就去掉吧
- new-cap: 构造函数大写,这个我不太喜欢,我设定的class都是小写的自然构造函数也是小写的,除非用工厂模式构建的否则显然不可能做到,也去除
- comma-dangle:行末逗号是非常好用的功能,这得加上
- no-undef: 提示未定义函数/变量,这个暂时还是去掉吧,有时候还是需要未定义直接使用的比如闭包引入等等
2.4 webpack-hot load
这里写个node即可,和官网教程1没啥区别
最后记得在package.json中加上dev即可
此外还有production环境的设置,这部分暂且停一下吧,等框架写过半自然会用上。
2.5 jsdoc
在之前相比都见过我使用的一些注释比如
这些注释在jsdoc中都是可以被准确识别,并编译成文档的,具体可以参见:jsdoc 官方文档
除了jsdoc以外,我们还需要个模板,因为原生的模板讲道理还是有点难看的,我是用的是docstrap ,github地址
按照官方文档进行简单配置以后就可以尝试生成文档啦,下面是效果图。
3. 项目的架构
此前我们是没有设计项目的基本架构的,事实上一个开发中的项目架构难免会发生变动,但是一开始的架构很大程度上限制了整个项目的复杂程度和划分。
对于架构首先需要分析项目的抽象结构是怎么样的。
- parser类:这一类是用来处理html处理的类,在未来可以升级为 compiler类用来处理所有的模板等等
- core类: 核心类,通常对于一些重要的实现都放在core类中如compnoment类,utils类等等
- compnoment类:这一类是用来处理组件的类,此后用户所有的类都会继承自这一个类
- util类:这一类主要用来存放一些工具,比如bug汇报器等等
大致暂定为这样
随后是项目的结构
|-test 项目测试用例
|-测试对象名称
|-doc 文章存放处,包括一些零散的说明
|-Api 通过jsdoc生成的项目api文档
|-src 项目源文件
|-parser
|-core
|-util
|-compnoment
|-other
|-config 项目的设置文件
随后根据现在做出的内容进行修正吧!
4. 项目代码整理
4.1 模块的拆分
首先我们的main.js现在暂时还需要一边测试一边制作,所以还没有办法单独脱离开index.html。
不过现在为了方便起见,我们先把整个main.js全部拎出来。
内容太多了,这里就先不介绍了,具体看github上的更新历史。
4.2 模块的补充
在这里我们不难发现,在对element操作的时候带来了困难,原因很简单,因为在系统中只有element的生成,却没有其他的生成过程,这样是不合理的,所以呢,现在我们需要完善整个生命周期,首先我们需要对具体的element作出储存,同时将内容与对应的data scope绑定起来。
首先常见的元素生成过程大致如下:
- create
- mounted
- ready
- destory
上述4个就是element的创建过程了,对此我们要讲原来耦合的元素创建分离开来。
同时在做这一步的同时,我们可以顺便将不同类型的 node 创建过程分离,对于不同的内容我们可以选择产生几种新的方法代理执行,而不是直接写在内部。
此外我们还可以将dom与vm绑定。
最后主要的几个方法大致是这样的:
createElement这是用来创建实际dom 的之后将会把添加一个创建compnoent的
/**
* 创建一个 Imit dom对象
* @param {String} tag 标签名称
* @param {Array} components 引入的组件列表
* @param {Object} option 额外内容,包括作用域,属性/属性列表
* @returns {domElement} 返回的是一个已经绑定完所有内容的dom对象
*/
export function createImitElement(tag, components, option) { ... }
v-dom的相关方法
4.3 现有组件的问题
随后我们将过程拆分开来,具体的更新可以查看github的内容,上面有详细的记录。现在我们的项目已经看上去比之前健壮了一点,但是显然的问题还是有个,那就是组件的嵌套,子组件的使用,现在只有普通的node和textnode却没有关于子组件的创建,同样的,这里还有一个更加显著的问题,那就是虽然使用了一种类似于 虚拟dom 的手段,但是实际上,这一实现的本质并不是 虚拟dom,我们需要的不是类似于观察者模式的触发。(因为这会导致组件呗重复的操作)事实上我们需要的是一个延时性质的更新组件。
从之前的内容我们不难发现不论怎么操作,所有的操作都会汇总到某个medthod方法完成,而不是某个属性的完成,诚然,观察者模式的记录我们任然可以使用,但不应该直接去更新dom而是触发一个延时的更新函数,并通过这个延时更新函数,diff差异,并将差异完整的更新上去。
而这里的差异,显然的需要一个散列方法来处理。
结语
由于最近时间实在不够用,更新的时间和周期也是不确定的,这也是没有办法,最后期待下一篇,下次的内容中将实现对多个组件的绑定(说的本来这次要实现的呢!),那么下篇博客再见!
脚注
-
webpack,WEBPACK DEV SERVER.http://webpack.github.io/docs/webpack-dev-server.html,2017. ↩
本文标题:从零开始编写属于你的mvc框架[2]
永久链接:https://iceprosurface.com/2017/05/07/2017/2017-05-7-how-to-implement-a-simple-mvc-2/
作者授权:本文由 icepro 原创编译并授权刊载发布。
版权声明:本文使用「署名-非商业性使用-相同方式共享 4.0 国际」创作共享协议,转载或使用请遵守署名协议。