应该选前端还是选后端?

其实,说到开发,就难免会遇到一个问题?

你是想做前端还是想做后端?

在大企业内,前端和后端差距都不大,不过从个人成长角度来看,二者又有所不同。

从技术成长的角度来看,前端和后端的选择并不会影响你最终成为技术大牛。任何一个领域,都有足够多的人不努力,等待着别人去教他们,只要你愿意努力,很容易就超过他们。所以,在这篇文章中,我并不想从技术的角度考虑。

这个想法是这两天在喂羊的间隙想到的。

前端和后端的区别是什么?区别在于前端更接近用户,而后端离用户更远。

在传统的开发模式下,前端切图,生成模板丢给后端,后端加入模板的标签,渲染界面。

在如今的开发模式下,后端提供 API ,前端负责完整的交互、路由等工作,需要花费大量的时间和精力在与用户相关的内容上。这使得前端开发人员,有更多的机会直面用户需求。而后端更多的是面对业务,根据一个个业务封装编写对应的 API,这使得后端无法完整的了解用户的需求到底是什么。

为什么要离用户近?

我见到过很多程序员,他们只关注于技术本身,而不在意产品、业务方面的事情,但是如果你有着自己做点什么东西的想法,那么,就一定要离用户近,接触到用户真实的需求,并去分析,为什么用户的需求产品经理给出的方案却是这个样子的。

离用户更近,离钱更近。

不过,虽然前端可能更适合一个想要自己做事情的人,但是你反而应该先去以后端的身份加入到整个生态中,因为在一开始的时候,你还有足够的精力和热情去研究技术,随着时间的流逝,你对技术的兴趣会越来越小,会花费大量的精力在产品、推广上。所以,前期关注底层的技术,后期关注用户、体验层面的东西。

为什么一个现代化的框架应该具备 Migration 功能

在过去刀耕火种的编程年代,程序员写代码的时候都是手动创建表

image 1
创建数据库的 SQL

但是,在开发过程中,难免会遇到需要对表结构进行修改,在一些小型团队中,尚且可以通过喊一声,大家都执行同样的操作来完成,确保各自的数据结构的一致性。

随着开发流程的变长、开发人员数目的增多、远程工作的流行,这种方案显然不可行。

因此,就出现了 Migration 。Migration 是将数据库的变化以代码的形式存储起来。一个人在进行数据库修改时,使用 Migration 进行操作,其他人只要执行对应的 Migration ,就可以进行数据库结构的同步。

image 2
rails 的 migration

一个现代化的框架,应该有 Migration。

WePy 整合云开发

由于工作上的原因,有需求要使用 WePy,刚好,有了云开发的契机,就决定研究一下。

初试 WePY

想要做云开发和 WePY,首先要先熟悉 WePY。 WePY 其实之前就听说过,不过自己一直没有使用,更多还是习惯用小程序原生写法来进行开发。

后续,也用过一些其他的框架,比如 MinUI 。

和 MinUI 相比,WePY 给我来说最大的感受是提供了 promise 的支持和 async/await 的支持,这个支持可以极大的改善 JavaScript 编程时遇到的 Callback Hell 的问题,可以让我们更加愉悦的开发。

此外,我比较看重的特性是支持外部的 NPM 包,支持 NPM 包意味着可以更好的使用 JavaScript 原本的工程化的产品,也是大大提升生产力的特性。不过,相比于 Promise 的支持和 async/await 的支持,这个如今已经被微信小程序官方团队所支持的 npm 也显得不那么重要了。

做一个 WePY 的 tempalte 吧!

在看文档时注意到,WePY 是使用 wepy init 来进行初始化的,而且可以使用 wepy list 来查看项目的模板。发现了其中有一个基于 ZanUI 的模板。

由于 ZanUI 及更名后的 VantUI 我都比较熟悉,所以从他下手,去研究一下如何制作 WePY 的模板。

复制 repo名/模板名,并在前面加上 github 的域名,就找到了对应的 repo 。

简单的看了一下项目的文件,发现其中并没有什么特殊的,需要指明初始化内容的文件,所以猜测大概率是不需要进行单独的配置的。

这方面 WePY 的文档做的不是很好,我在文档中并没有找到相关的说明。如果可以的话,希望开发者可以加一个功能,比如加上一个 .wepy-template ,可以在里面加入一些交互式的问题,从而来让用户设置一些内容。

在确定了模板其实并不困难以后,我就开始做自己的云开发模板了。

如何做一个模板

做一个模板只需要三步

  1. 下载官方的 empty 模板
  2. 加入你自己的代码
  3. 上传到 Github

说起来简单,不过,在实际制作时,还是应当注意一些问题:

  1. 初始化 Empty 模板后,尽快使用 git init 来初始化版本控制。这是因为云开发是与小程序的 AppID 进行绑定的,如果前期没有做好控制,容易出现后续将 AppID 加入了版本追踪。所以在一开始,我就将项目进行了初始化,方便后续的回溯。
  2. 上传到 Github 时,应当注意配置 Readme,在我之前的文章中,曾经提到过我们应当尽可能的交付一些产品给世界,好让世界根绝我们所交付的产品进行估值。特别是对于模板类型的 repo ,更是需要一个非常好的 Readme ,来引导别人去使用自己的模板
  3. 制作完成模板后,记得自己使用 wepy init 命令将整个过程完整的走一遍。确保你的模板是可用的。

在使用 WePY 过程中遇到的一些问题

CloudFunctionRoot 的设定问题

在做第一个版本的时候,我是将云函数的目录放在 src 目录下,后续,在运行时发现, WePY 会自动编译云函数的目录,导致出错。不得已,我将云函数的目录放置在了项目的根目录。

当时在研究这部分时,我试图去寻找 wepy.config.js文件的配置说明,希望找到一个 exclude 配置项目,来忽略一部分目录,可惜,我并没有找到。

WePY 下的一些定义问题

在使用原生写法的时候,我常常会在 Page({}) 函数外部放上一些引用。比如这样

const database = wx.cloud.database()
const storeCollection = database.collection('store')
Page({
    onReady():function(){
        // some code
    }
})

在 WePY 中我试图将代码放在 Page 实例的内部,不过会导致报错,因此,我不得不废弃这样的写法,改用 constructor 来实现。

 export default class Index extends wepy.page {
    constructor () {
      super()
      this.db = wx.cloud.database()
    }
    onLoad() {
      console.log('onLoad')
      console.log(this.db)
    }
}

对 getApp 报错

在 WePY 中,由于传承了 Vue 的思想,并没有提供对 getApp的 hack ,不过在实际的测试过程中,发现 getApp() 依然可用。

如果不引入 Redux 之类的状态管理工具的情况下,getApp() 的单例模式作为一个全局的 Bus 来进行数据的传递还是非常方便的。

关于 WePY 的其他

总的来说, WePY 是一个值得尝试的框架,单纯 Async/Await 的引入,可以让你的代码变得更加简洁易懂。特别是如果你的项目需要长期运转的情况下,整洁的代码会帮助你的项目成功。

此外,如果你很习惯于 Vue 的写法,那么 WePY 不容错过,computed 属性还是非常实用的。

为什么谈场景不谈功能?

在接触到了很多小白以后,我开始习惯性的说:

你是什么样的场景需要 XXX 的?

背后的逻辑其实是,你的方法可能无法被你所提出的解决方案所解决,你可以告诉我你实际遇到的问题是什么,我可以借助我的经验,帮你想到一个 workaround 来解决掉这个问题。

人生需要干湿兼备

年轻人难免会心急,希望快速成长,希望在有限的时间内,获得无限的成长,因此,对于干活的希望是无比渴求的,他们希望自己接收到的都是干活,没有湿货。但是应当注意:

干货如骨架,吸收越来越多的干货,只是让你的骨架越来越大。若是没有足够的湿货来辅助,就是空有骨架,依然不是一个完整的人,只是从一个骨头架子变成了另一个骨头架子。看点湿货,让自己的骨架成长的时候,也有对应的血肉填上,这才是刚刚好的一个人。

湿货看的比干货多的话,一个人就会骨架不强而血肉有余,满口空话,不过是痴肥罢了。

小程序合照助手

合照助手小程序用于快速在一些聚餐、合照的场合生成合照图片。

image

用户可以打开手机小程序,选择图片,然后分别输入合照的名称、第一行的顺序、第二行的顺序。然后可以点击保存将图片保存至本地。

适合场景:聚餐、聚会、会议

2019 年 1 月 月度总结

2019 年 1 月没有太大的变化,仅仅是敲定了 2019 年上半年的工作问题。

工作相关

正式入职青宁信安,职责从后端转为前端。负责青宁信安的所有前端相关的事宜。后续如果工作时间有充裕的,再考虑接手 Scala 的后台开发事宜。

情感相关

本月情感有较大的突破。但是也要考虑到存在一些不稳定因素,仍需努力。

身体健康相关

本月停止锻炼,下月需要恢复锻炼。

其他

本月 Side Project 有较大突破


年度任务对标

  • 年读书 52 本,1月应读书籍: 4 本。 1月实读书籍: 3 本,落后进度 1 本
    • 《高效前端:Web 高效编程与优化实践》
    • 《程序员的思维训练》
    • 《深阅读》
  • 每年国内旅游 5 次, 1月旅游1次,为广州,游览了广州长隆野生动物园、广州塔。
  • 得到课程学习: 1门 ,戴愫的《怎样成为人脉管理的高手》

向世界交付产品,而不是Demo

作为开发者,最常见的问题是,做项目的适合,所做的产品完全无法交付给第三方使用。你所做的东西只能用于自己使用,无法交付给第三方使用时,实际上你并没有交付出去价值。

当你交付出去了价值的时候,世界才能为你定价。所以,做东西尽可能做成可以交付的产品,交付出去产品,让世界为你估价。

以上心得是我在做美食地图时得到的。

在做美食地图时,我需要做以下事情来保证交付:

  1. 一个安装文档
  2. 一个配置说明
  3. 一个FAQ
  4. 一个升级说明(当你有 breaking changes 时,就需要写清楚升级说明,来辅助你的用户完成版本升级)

小程序的 marker 无法触发 bindmarkertap 事件应该如何处理

TL;DR

如果想要 marker 可以响应 bindmarkertap 事件,需要设定 markerID,这一点文档中并没有标注。

具体情况

在开发美食地图时,出现了一个问题,marker 的点击总是不会触发 bindmarkertap 事件。

我的代码是这样写的

    store.get().then(res => {
      this.setData({
        stores: res.data,
        windowHeight: app.globalData.windowHeight,
      }, () => {
        wx.hideLoading();
        wx.showToast({
          title: '双指缩放可以调整地图可视区域,查看更多美食',
          icon: 'none'
        })
      })
    })
Code language: JavaScript (javascript)

在地图中去调用 stores. marker

在地图上的确可以出现图标,但是无法点击 maker 并触发事件。

通过复制官方的 marker 的数据进行调试后发现,当 maker 有 id 时,marker 就可以触发事件,因此,怀疑是 ID 的问题。

在美食地图小程序中,我使用的是腾讯云提供的小程序·云开发,其使用的是 MongoDB 作为后台的 Database ,默认的主键为 _id,所以,我自己写了代码来转换 _id

      data.map(item => {
        item.id = item._id
      });
Code language: JavaScript (javascript)

对应的 commit :https://github.com/CloudKits/miniprogram-foodmap/commit/5abcad1f756e03a388bb33dd1c699d3cae9ea0c4#diff-f5ea41cdd371d7b65bfdf8d32188e37d