今天是2024年4月26日,是我的32岁生日,也是我从事前端开发十年的日子,这篇文章是对我职业生涯的一次回顾,这次回顾颇有感慨,不仅回顾了之前工作的公司、同事,也看了一遍之前写的代码、写的文章,还有以前看的技术书的笔记。
本文就以技术栈为线,把这十年的前端经历串起来,一来让读者一窥这十年前端发展的历程,二来也希望通过分享我个人的经历,给技术人一点信心和方向,原来一直做技术也可以做十年,很快我也35岁了,希望我能打破程序员只能干到35岁的魔咒,40岁、50岁,我依然会写代码,这不仅仅是我的赖以谋生的手段,更是一种生活方式,通过写代码我认识了很多志同道合的朋友,在写代码的路上,我也在欣赏和探索这个世界。
关键词:jQuery
、全栈
我的第一份前端工作,在一家电商创业公司,我主要做电商后台管理系统,使用的是 jQuery 技术,当时刚从学校出来,没有系统学习过前端知识,于是买了两本书📚。
每天利用上下班坐公交时间(当时每天上下班的通勤时间长达3个小时)疯狂阅读,很快就掌握了 JavaScript + jQuery 技术,加上导师的耐心指导,很快就能在工作中运用自如。
jQuery 写出来的代码大致如下:
$('input[type="button"]').eq(0).click(function() {
// 点击事件的逻辑
}).end().eq(1).click(function() {
$('input[type="button"]:eq(0)').trigger('click');
}).end().eq(2).toggle(function() {
$('.menu-item').hide('slow');
}, function() {
$('.menu-item').show('slow');
});
jQuery 简化了DOM操作,并且采用链式调用的语法,在众多 JS 库中脱颖而出,从2006年开始到2016年,引领了前端近十年。
除了电商后台管理系统,我还用 jQuery 开发了一个 FAQ 系统,这个系统也是我的第一个全栈项目,从产品到开发,从前端到后台,从开发和运维,都是我一个人负责的。
也是在这个阶段接触了 Linux、MongoDB、Node.js 等全栈技术。
当时写了几篇总结文章:
关键词:Angular.js
、MVVM
、工程化
大约在2015年,公司开发新的 B2B 搭配管理系统,想着有没有什么新框架可以用,就去搜索了一下,发现了 Angular.js
这个当时还算比较火的前端框架。
jQuery
是通过便捷的选择器、链式操作等简化了 DOM 操作,而 Angular.js 则是一种新的前端开发模式:MVVM
,不直接操作 DOM,开发者写代码时操作的是数据,框架将数据绑定到视图(DOM),数据变化,视图跟着变化。
目前最流行的三大框架:Vue
、React
、Angular
都是类似的模式,其中 Angular 是最早出现的,在 2009 年就已经有了 Angular.js,对比之下,Vue 和 React 最早是 2013 年发布的。
为了系统地学习 Angular.js,我又买了一本书📖(我是有多喜欢看书😋)。
Angular.js 写出来的代码大致是这样的:
hello-world.html
<div>
{{vm.greeting}}
</div>
hello-world.js
module.exports = function(ngModule) {
ngModule.directive('helloWorld', helloWorldFn); // 定义指令,对应页面中的 <hello-world></hello-world>
require('./hello-world.scss');
function helloWorldFn() {
return {
restrict: 'E', // 元素(element)
scope: {},
template: require('./hello-world.html'),// 模板
controllerAs: 'vm', // <=> $scope.vm = {greeting: '你好,我是卡哥'}
controller: function () {
this.greeting = '你好,我是卡哥,很高兴见到你';
}
}
}
}
当我们修改了 greeting 这个变量,视图中对应使用了这个变量的部分也会跟着变化,Angular.js 可以理解为 Angular 1.0 版本,和我们现在用的 Angular 2+ 版本的写法有巨大的差异,后面我们会看到 Angular 2+ 版本的写法比较接近现在三大框架的写法。
除了开发 B2B 搭配管理系统,我还用 Angular.js 开发了马来支付客服系统,也是在开发这个项目的过程中,接触了 Webpack 构建工具这些前端工程化的东西。
当时是 2015 年底,我已经从原来的电商创业公司离职,来到了腾讯,当时的 Webpack 官网还是一个很简陋的 http 域名的网站:http://webpack.github.io/(现在是:https://webpack.js.org/),可以说是看着 Webpack 不断发展壮大的😝。
我尝试用 Webpack 打包 Angular.js 项目成功,并写了一篇总结文章。
除了 Angular.js 这个 MVVM 框架之外,当时团队有项目使用的是 Backbone.js 项目,所以也学过几个月 Backbone.js(也是当时流行的 MVC 框架之一),写了一篇总结文章。
除了上面提到的 jQuery、Angular.js、Backbone.js,这个阶段其实还有不少前端库和前端框架,比如:Bootstrap、Riot.js、YUI、Kissy 等,当然 React、Vue 也开始出现,只是还不是很火,大部分前端还是用 jQuery。
关键词:React
、组件化
、研发全流程
2016年开始在腾讯做海外广告平台,用的是 React 技术栈,当时还是 React v0.x 的版本,后面才升级到 React 15。
这是我参与的第一个中型商用项目,从一开始负责效果数据子模块,到后面负责整体广告平台的前端。
除了深入学习了 React 这个前端框架,也学习如何与产品、设计、测试、后台等团队其他角色的同事打交道,甚至与跨部门的同事沟通,学习了如何从0到1开发一个新产品。
从 jQuery 到 Angular.js,再到 React,让我对前端开发的模式有了更全面的认识,与 Webpack 的深度结合,也加深了我对前端工程化的认识。
特别是 React 组件化的思想,以及我在海外广告平台中的实践,让我形成了自己的组件设计理论,并写了一篇总结文章。
这也是我第一次接触前端组件库,当时团队并没有自己的组件库,用的是 Ant Design,当时市面上的 UI 组件库其实并不多,我印象比较深的就是 Material UI 和 Ant Design。
当时团队的技术大佬一直想自建组件库,只是由于领导是后台出身,对前端没有那么重视,导致没有足够的资源做这件事。
不过我们还是私下在做,而且我也为这个组件库贡献了几个组件,写了几篇组件设计的文章。
React 代码大致是以下样子。
import React, { Component } from 'react';
import { render } from 'react-dom';
import { Router, hashHistory as history } from 'react-router';
import { Provider } from 'react-redux';
import routes from './routes';
import configureStore from './configureStore';
import './theme.scss';
const store = configureStore();
const rootElement = document.getElementById('root');
class App extends Component {
render() {
return (
<Provider store={store}>
<Router history={history} routes={routes} />
</Provider>
);
}
}
render(<App />, rootElement);
可以看到 React 的代码已经是组件化的写法,和我们现在用三大框架写的代码比较接近。
除了 React,当时还接触了 ECharts、Nginx、PHP 的 CI 框架等技术,总结了一些技术文章(请叫我总结大师😎)。
这个阶段我疯狂看各种技术书📚,在技术广度和深度上都有长足的进步。
关键词:Angular
、富文本
、组件库建设
、大型商用项目
、开源运营
时间来到了 2019 年,也就是新冠疫情爆发那年,我到了华为做 EditorX
富文本编辑器、Ng DevUI
组件库和 ProjectMan
大型商用项目。
Angular 代码大致以下样子。
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { MemberListModule } from '@component/member-list/member-list.module';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
MemberListModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html
<div>
<app-header></app-header>
<div>
<div>
<nav>
<app-bonus
dStepsGuide
dStepsGuidePosition="bottom"
pageName="step-bonus"
[steps]="steps"
[stepIndex]="2"
[observerDom]="observerDom"
(operateChange)="operateChange($event)"
></app-bonus>
<app-group></app-group>
<app-custom-group></app-custom-group>
</nav>
<div>
<app-main-content-head></app-main-content-head>
<app-operation-bar></app-operation-bar>
<app-project-list></app-project-list>
</div>
</div>
</div>
<app-footer></app-footer>
</div>
<router-outlet></router-outlet>
app.component.ts
import { Component, OnInit } from '@angular/core';
import { StepsGuideService } from 'ng-devui';
import { STEPS_BONUS, STEPS_CATEGORY_SEARCH } from './shared/const';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
title = 'devcloud-portal';
steps = STEPS_BONUS;
observerDom;
constructor(
private stepService: StepsGuideService,
) {}
ngOnInit(): void {
this.observerDom = document.querySelector('.main-content');
}
operateChange({ clickType, currentIndex }): void {
if (clickType === 'prev' && currentIndex === 0) {
localStorage.removeItem('devui_guide_step-category-search');
this.stepService.setSteps(STEPS_CATEGORY_SEARCH);
this.stepService.setCurrentIndex(1);
return;
}
}
}
Angular 是一款能够跨 Web、移动 Web、移动应用、原生应用和桌面原生应用多个平台的前端框架,目前经过数十年的发展,已形成了一个庞大的生态,基于 Angular 的生态项目也是多如牛毛。
它不仅仅是一个视图层,更是一个全能的前端框架,MVVM 架构、依赖注入、CLI、模块、组件、指令、服务、路由、管道、表单管理、SSR,几乎提供了前端应用开发的全套工具,这么庞大的工具,也让部分前端开发者觉得入门门槛太高,因此国内用 Angular 的前端开发者并不多,反而由于 Angular 的类和装饰器写法和 Java 比较类似,受不少后端开发着的青睐。
这个阶段看书比较少,写文章比较多。
从 2020 年 3 月到 2022 年 9 月,一共写了 80 多篇文章,覆盖 Angular
、Vue
、TypeScript
、富文本编辑器
、组件库建设
、Git
、Monorepo
、DevOps
、性能分析
、单元测试
、开源社区运营
等众多领域。
Vue:
组件库建设:
前端开发的积木理论与实践(共 5 篇)
从0到1搭建Vue组件库(共 12 篇)
其他组件设计相关的文章:
富文本编辑器:
也是从这个阶段开始接触开源社区运营,这是一项我非常热爱的事情,虽然是业余时间在做,但我依然付出了大量时间和精力,我觉得这是一件很有价值的事情,对我自身成长也很有益。
做开源开发和在公司做业务开发有一个很大的差别就是,我不仅要负责项目架构演进和代码开发,还要负责项目的推广和运营,为项目吸引用户,为社区吸引贡献者参与共建,这让我得以接触到一个更广阔的开发者社区,认识很多优秀和勤奋的开发者,他们和我一样,是一群热爱技术、热爱生活的人。
据 GitHub 官方统计,从2016年开始,Github 平台每年平均新增1000多万开发者、5000多万开源项目,且增幅呈现逐年递增的趋势。而中国的开发者参与开源的热情更是超过其他国家,不管是开发者还是开源项目的增长速度,中国都是名列前茅,2021年中国共有755万 GitHub 开发者,全球排名第二。
我国在“十四五”规划中首次把开源纳入顶层设计, 从国家层面体现了对开源的重视,国内的华为、腾讯、阿里等多家大厂也都将开源作为公司战略的一部分,国内外开源呈现一片繁荣的景象,我相信开源的春天马上要来了,这是大趋所势。
因此在技术之外,我专门开设了一个开源专栏,希望自己在开源运营领域有更多积累和沉淀。
关键词:Vue
、跨框架组件库建设
、团队管理
2022年9月,我加入了华为云云岭团队,负责 TinyVue 跨端跨框架组件库建设和 OpenTiny 开源社区运营。
技术栈也从 Angular 转到 Vue。
相比 Angular,Vue 在国内的使用者更多,社区更加活跃,不管在掘金、知乎、思否等国内技术社区,Vue 的关注者、文章数、讨论数都比 Angular 高,Vue 相关视频在B站的播放量和评论数总体上也比 Angular 高。
我在 2021 年就已经创建过一个 Vue3 的开源组件库项目,结识了一群 Vue 开发者朋友,因此可以平滑过渡到 TinyVue,TinyVue 和一般的 Vue 组件库不同的是,它是一个跨端、跨框架的组件库,底层将组件逻辑抽离成框架无关的 renderless,基于 renderless 实现 PC / Mobile 多端适配,实现一套代码同时支持 Vue2 / Vue3,近期我们也在基于 renderless 实现 React 版本,已经取得了初步的成果。
Vue 的代码大致如下样子。
main.ts
import { createApp } from 'vue'
import App from './App.vue'
import TinyVue from '@opentiny/vue'
import './style.css'
const app = createApp(App)
app.use(TinyVue).mount('#app')
App.vue
<script setup lang="ts">
import { ref, getCurrentInstance, version, watch, onMounted, Ref } from 'vue'
import {
Button as TinyButton,
Alert as TinyAlert
} from '@opentiny/vue'
import { IconAdd } from '@opentiny/vue-icon'
const vueVersion = getCurrentInstance().appContext.app.version
const ipValue = ref('192.168.0.1')
const helloRef = ref<IMethod>()
const clickEvent = () => {
Modal.alert('基本提示框', '标题')
}
watch(ipValue, (newVal) => {
if (newVal === '0.5.1.2') {
Notify({ message: '验证成功'})
}
})
onMounted(() => {
const str = helloRef.value?.myMethod('test', 30)
})
</script>
<template>
<tiny-button type="primary">TinyVue</tiny-button>
<tiny-alert size="large" description="TinyVue"></tiny-alert>
<tiny-time-line :data="data" :active="active">
<template #top="data">
<div style="text-align: center">{{ data.slotScope.name }}</div>
<div style="text-align: center">
<tiny-tag v-for="item in data.slotScope.technical">{{ item }}</tiny-tag>
</div>
<div style="text-align: center">
<tiny-tag v-for="item in data.slotScope.project">{{ item }}</tiny-tag>
</div>
</template>
<template #bottom="data">
<p>{{ data.slotScope.time }}</p>
</template>
</tiny-time-line>
<tiny-tabs
tab-style="card"
:editable="false"
:with-add="true"
@add="handleadd"
show-more-tabs
>
<tiny-tab-item
:key="item.name"
v-for="item in Tabs"
:title="item.title"
:name="item.name"
>
{{ item.content }}
</tiny-tab-item>
</tiny-tabs>
</template>
<style scoped lang="scss">
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
filter: drop-shadow(0 0 2em #42b883aa);
}
.my-tabs ::v-deep .tiny-tabs__header {
justify-content: flex-start;
}
</style>
这个阶段最主要的任务是打造 OpenTiny 开源项目的内外部影响力,让 OpenTiny 成为受开发者欢迎的组件库,并建设一个受开发者喜爱、让开发者有所成长的开源社区。
技术上主要是深入 TinyVue 跨端跨框架组件库,实现 React 版本,并争取出一本相关的小册。
技术书籍方面:
技术写作方面:
未来,前端技术将持续发展和演进,我也将不断学习和探索新技术。
感兴趣的朋友也可以关注下我的微信公众号:前端开源星球
和个人博客。
公众号:OpenTiny
GitHub:https://github.com/opentiny/tiny-vue(欢迎 Star ⭐)
官网:https://opentiny.design/tiny-vue