寫給初中級前端的高級進階指南

大家好,我是若川。最近組織了源碼共讀活動。每週讀 200 行左右的源碼。很多第一次讀源碼的小夥伴都感覺很有收穫,感興趣可以加我微信ruochuan12,拉你進羣學習。


前言

我曾經一度很迷茫,在學了 Vue、React 的實戰開發和應用以後,好像遇到了一些瓶頸,不知道該怎樣繼續深入下去。相信這也是很多一兩年經驗的前端工程師所遇到共同問題,這篇文章,筆者想結合自己的一些成長經歷整理出一些路線,幫助各位初中級前端工程師少走一些彎路。

這篇文章會提到非常非常多的學習路線和鏈接,如果你還在初中級的階段,不必太焦慮,可以把這篇文章作爲一個進階的路線圖,在未來的時日裏朝着這個方向努力就好。
我也並不是說這篇文章是進階高級工程師的唯一一條路線,如果你在業務上做的精進,亦或是能在溝通上八面玲瓏,配合各方面力量把項目做的漂漂亮亮,那你也一樣可以擁有這個頭銜。本文只是我自己的一個成長路線總結。

本篇文章面對的人羣是開發經驗1到3年的初中級前端工程師,希望能和你們交個心。

已經晉升高級前端的同學,歡迎你在評論區留下你的心得,補充我的一些缺失和不足。

筆者本人 17 年畢業於一所普通的本科學校,20 年 6 月在三年經驗的時候順利通過面試進入大廠,職級是高級前端開發。

我的 github 地址 [1],歡迎 follow,我會持續更新一些值得你關注的項目。

我的 blog 地址 [2],這裏會持續更新,點個 star 不失聯!✨

基礎能力

我整理了一篇中級前端的必備技術棧能力,寫給女朋友的中級前端面試祕籍 [3] 。這篇文章裏的技術棧當然都是需要紮實掌握的,(其實我自己也有一些漏缺,偷偷補一下)。

當然了,上進心十足的你不會一直滿足於做中級前端,我們要繼續向上,升職加薪,迎娶白富美!

JavaScript

原生 js 系列

冴羽大佬的這篇博客裏,除了 undescore 的部分,你需要全部都能掌握。並且靈活的運用到開發中去。
JavaScript 深入系列、JavaScript 專題系列、ES6 系列 [4]

完全熟練掌握 eventLoop。

tasks-microtasks-queues-and-schedules[5]

Promise

  1. 你需要閱讀 Promise A + 規範,注意其中的細節,並且靈活的運用到開發當中去。
    Promise A+ 英文文檔 [6]

  2. 你需要跟着精品教程手寫一遍 Promise,對裏面的細節深入思考,並且把其中異步等待、錯誤處理等等細節融會貫通到你的開發思想裏去。
    剖析 Promise 內部結構,一步一步實現一個完整的、能通過所有 Test case 的 Promise 類 [7]

  3. 最後,對於 promise 的核心,異步的鏈式調用,你必須能寫出來簡化版的代碼。
    最簡實現 Promise,支持異步鏈式調用(20 行)[8]

題外話,當時精煉這 20 行真的繞了我好久 😂,但是搞明白了會有種恍然大悟的感覺。這種異步隊列的技巧要融會貫通。

async await

對於 Promise 我們非常熟悉了,進一步延伸到 async await,這是目前開發中非常非常常用的異步處理方式,我們最好是熟悉它的 babel 編譯後的源碼。

手寫 async await 的最簡實現(20 行搞定)[9]
babel 對於 async await 配合 generator 函數,做的非常巧妙,這裏面的思想我們也要去學習,如何遞歸的處理一個串行的 promise 鏈?

這個技巧在 axios 的源碼 [10] 裏也有應用。平常經常用的攔截器,本質上就是一串 promise 的串行執行。

當然,如果你還有餘力的話,也可以繼續深入的去看 generator 函數的 babel 編譯源碼。不強制要求,畢竟 generator 函數在開發中已經用的非常少了。
ES6 系列之 Babel 將 Generator 編譯成了什麼樣子 [11]

異常處理

你必須精通異步場景下的錯誤處理,這是高級工程師必備的技能,如果開發中的異常被你寫的庫給吞掉了,那豈不是可笑。
Callback Promise Generator Async-Await 和異常處理的演進 [12]

插件機制

你需要大概理解前端各個庫中的插件機制是如何實現的,在你自己開發一些庫的時候也能融入自己適合的插件機制。
Koa 的洋蔥中間件,Redux 的中間件,Axios 的攔截器讓你迷惑嗎?實現一個精簡版的就徹底搞懂了。[13]

設計模式

對於一些複雜場景,你的開發不能再是if else嵌套一把梭了,你需要把設計模式好好看一遍,在合適的場景下選擇合適的設計模式。這裏就推薦掘金小冊吧,相信這篇小冊會讓你的工程能力得到質的飛躍,舉例來說,在 Vue 的源碼中就用到了觀察者模式發佈訂閱模式策略模式適配器模式發佈訂閱模式工廠模式組合模式代理模式門面模式等等。

而這些設計模式如果你沒學習過可能很難想到如何應用在工程之中,但是如果你學習過,它就變成了你內在的工程能力,往大了說,也可以是架構能力的一部分。

在《設計模式》這本小冊中我們提到過,即使是在瞬息萬變的前端領域,也存在一些具備 “一次學習,終生受用” 特性的知識。從工程的角度看,我推薦大家着重學習的是設計模式。- 修言

這裏推薦掘金修言的設計模式小冊 [14]。

基礎算法

算法這裏推薦慕課網 bobo 老師的 LeetCode 真題課程 [15],在這個課程裏算法大牛 bobo 老師會非常細心的給你講解各種分類的 LeetCode 真題。

由於這門課程是 C++ 爲主要語言的(不影響理解課程),我也針對此課程維護了一個對應的 JavaScript 版題解倉庫 [16],在 Issue 裏也根據標籤分類整理了各個題型的講解,歡迎 Star ✨。

算法對於前端來說重要嗎?也許你覺得做題沒用,但是我個人在做題後並且分門別類的整理好各個題型的思路和解法後,是能真切的感覺到自己的代碼能力在飛速提高的。

對於很多覺得自己不夠聰明,不敢去學習算法的同學來說,推薦 bobo 老師的這篇《天生不聰明》,也正是這篇文章激勵我開始了算法學習的旅程。

開發思想

有時候組合是優於繼承的,不光是面向對象編程可以實現複用,在某些場景下,組合的思想可能會更加簡潔優雅。

https://medium.com/javascript-scene/master-the-javascript-interview-what-s-the-difference-between-class-prototypal-inheritance-e4cd0a7562e9

“…the problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.” ~ Joe Armstrong — “Coders at Work”

面嚮對象語言的問題在於它們帶來了所有這些隱含的環境。你想要一個香蕉,但你得到的是拿着香蕉和整個叢林的大猩猩。

代碼規範

你需要熟讀 clean-code-javascript,並且深入結合到日常開發中,結合你們小組的場景制定自己的規範。
clean-code-javascript[17]

框架篇

對於高級工程師來說,你必須要有一個你趁手的框架,它就像你手中的一把利劍,能夠讓你披荊斬棘,斬殺各種項目於馬下。

下面我會分爲VueReact兩個方面深入去講。

Vue

Vue 方面的話,我主要是師從黃軼老師,跟着他認真走,基本上在 Vue 這方面你可以做到基本無敵。

熟練運用

  1. 對於 Vue 你必須非常熟練的運用,官網的 api 你基本上要全部過一遍。並且你要利用一些高級的 api 去實現巧妙的封裝。舉幾個簡單的例子。

  2. 你要知道怎麼用slot-scope去做一些數據和 ui 分離的封裝。以 vue-promised[18] 這個庫爲例。Promised 組件並不關注你的視圖展示成什麼樣,它只是幫你管理異步流程,並且通過你傳入的slot-scope,在合適的時機把數據回拋給你,並且幫你去展示你傳入的視圖。

<template>
  <Promised :promise="usersPromise">
    <!-- Use the "pending" slot to display a loading message -->
    <template v-slot:pending>
      <p>Loading...</p>
    </template>
    <!-- The default scoped slot will be used as the result -->
    <template v-slot="data">
      <ul>
        <li v-for="user in data">{{ user.name }}</li>
      </ul>
    </template>
    <!-- The "rejected" scoped slot will be used if there is an error -->
    <template v-slot:rejected="error">
      <p>Error: {{ error.message }}</p>
    </template>
  </Promised>
</template>
  1. 你需要熟練的使用Vue.extends,配合項目做一些命令式api的封裝。並且知道它爲什麼可以這樣用。(需要具備源碼知識)confirm 組件 [19]
export const confirm = function (text, title, onConfirm = () ={}) {
  if (typeof title === "function") {
    onConfirm = title;
    title = undefined;
  }
  const ConfirmCtor = Vue.extend(Confirm);
  const getInstance = () ={
    if (!instanceCache) {
      instanceCache = new ConfirmCtor({
        propsData: {
          text,
          title,
          onConfirm,
        },
      });
      // 生成dom
      instanceCache.$mount();
      document.body.appendChild(instanceCache.$el);
    } else {
      // 更新屬性
      instanceCache.text = text;
      instanceCache.title = title;
      instanceCache.onConfirm = onConfirm;
    }
    return instanceCache;
  };
  const instance = getInstance();
  // 確保更新的prop渲染到dom
  // 確保動畫效果
  Vue.nextTick(() ={
    instance.visible = true;
  });
};
  1. 你要開始使用JSX來編寫你項目中的複雜組件了,比如在我的網易雲音樂項目中,我遇到了一個複雜的音樂表格需求 [20],支持搜索文字高亮、動態隱藏列等等。
    當然對於現在版本的 Vue,JSX 還是不太好用,有很多屬性需要寫嵌套對象,這會造成很多不必要的麻煩,比如沒辦法像 React 一樣直接把外層組件傳入的 props 透傳下去,Vue3 的 rfc 中提到會把 vnode 節點的屬性進一步扁平化,我們期待得到接近於 React 的完美 JSX 開發體驗吧。

  2. 你要深入瞭解 Vue 中 nextTick 的原理,並且知道爲什麼要用微任務隊列優於宏任務隊列,結合你的 eventloop 知識深度思考。最後融入到你的異步合併優化的知識體系中去。
    Vue 源碼詳解之 nextTick:MutationObserver 只是浮雲,microtask 纔是核心![21]

  3. 你要能理解 Vue 中的高階組件。關於這篇文章中爲什麼 slot-scope 不生效的問題,你不能看他的文章講解都一頭霧水。(需要你具備源碼知識)
    探索 Vue 高階組件 | HcySunYang[22]

  4. 推薦一下我自己總結的 Vue 高階組件文章,裏面涉及到了一些進階的用法。
    Vue 進階必學之高階組件 HOC[23]

  5. 對於 Vuex 的使用必須非常熟練,知道什麼時候該用 Vuex,知道怎麼根據需求去編寫 Vuex 的 plugin,合理的去使用 Vuex 的 subscribe 功能完成一些全局維度的封裝,比如我對於 Vuex 中 action 的錯誤處理懶得一個個去try catch,就封裝了一個 vuex-error-plugin[24]。代碼很簡單,重要的是去理解爲什麼能這樣做。這裏用了 monkey patch 的做法,並不是很好的實踐,僅以此作爲引子。

  6. 對於 vue-router 的使用必須非常熟練,知道什麼需求需要利用什麼樣的 router 鉤子,這樣才能 hold 住一個大型的項目,這個我覺得官方倉庫裏的進階中文文檔其實很好,不知道爲什麼好像沒放在官網。
    vue-router-advanced[25]

  7. 理解虛擬 DOM 的本質,虛擬 DOM 一定比真實 DOM 更快嗎?這篇是尤雨溪的回答,看完這個答案,相信你會對虛擬 DOM 有更進一步的認識和理解。
    網上都說操作真實 DOM 慢,但測試結果卻比 React 更快,爲什麼?[26]

源碼深入

  1. 你不光要熟練運用 Vue,由於 Vue 的源碼寫的非常精美,而且閱讀難度不是非常大,很多人也選擇去閱讀 Vue 的源碼。視頻課這裏推薦黃軼老師的 Vue 源碼課程。這裏也包括了 Vuex 和 vue-router 的源碼。
    Vue.js 源碼全方位深入解析 (含 Vue3.0 源碼分析)[27]

  2. 推薦 HcySunYang 大佬的 Vue 逐行分析,需要下載 git 倉庫,切到 elegant 分支自己本地啓動。
    Vue 逐行級別的源碼分析 [28]

  3. 當然,這個倉庫的 master 分支也是寶藏,是這個作者的渲染器系列文章,脫離框架講解了 vnode 和 diff 算法的本質
    組件的本質 [29]

Vue3 展望

  1. Vue3 已經發布了 Beta 版本,你可以提前學習Hook相關的開發模式了。這裏推薦一下我寫的這篇 Vue3 相關介紹:
    Vue3 究竟好在哪裏?(和 React Hook 的詳細對比)[30]

Vue3 源碼

對於響應式部分,如果你已經非常熟悉 Vue2 的響應式原理了,那麼 Vue3 的響應式原理對你來說應該沒有太大的難度。甚至在學習之中你會相互比較,知道 Vue3 爲什麼這樣做更好,Vue2 還有哪部分需要改進等等。

Vue3 其實就是把實現換成了更加強大的 Proxy,並且把響應式部分做的更加的抽象,甚至可以,不得不說,Vue3 的響應式模型更加接近響應式類庫的核心了,甚至react-easy-state等 React 的響應式狀態管理庫,也是用這套類似的核心做出來的。

再次強調,非常非常推薦學習 Vue3 的@vue/reactivity這個分包。

推一波自己的文章吧,細緻了講解了 Vue3 響應式的核心流程。

  1. 帶你徹底搞懂 Vue3 的 Proxy 響應式原理!TypeScript 從零實現基於 Proxy 的響應式庫。[31]

  2. 帶你徹底搞懂 Vue3 的 Proxy 響應式原理!基於函數劫持實現 Map 和 Set 的響應式 [32]

  3. 深度解析:Vue3 如何巧妙的實現強大的 computed[33]

在學習之後,我把@vue/reactivity包輕鬆的集成到了 React 中,做了一個狀態管理的庫,這也另一方面佐證了這個包的抽象程度:
40 行代碼把 Vue3 的響應式集成進 React 做狀態管理 [34]

React

React 已經進入了 Hook 爲主的階段,社區的各個庫也都在積極擁抱 Hook,雖然它還有很多陷阱和不足,但是這基本上是未來的方向沒跑了。這篇文章裏我會減少 class 組件的開發技巧的提及,畢竟好多不錯的公司也已經全面擁抱 Hook 了。

熟練應用

  1. 你必須掌握官網中提到的所有技巧,就算沒有使用過,你也要大概知道該在什麼場景使用。

  2. 推薦 React 小書,雖然書中的很多 api 已經更新了,但是核心的設計思想還是沒有變
    React.js 小書 [35]

  3. 關於熟練應用,其實掘金的小冊裏有幾個寶藏

  4. 誠身大佬(悄悄告訴你,他的職級非常高)的企業級管理系統小冊,這個項目裏的代碼非常深入,而且在抽象和優化方面也做的無可挑剔,自己抽象了acl權限管理系統和router路由管理,並且引入了reselect做性能優化,一年前我初次讀的時候,很多地方懵懵懂懂,這一年下來我也從無到有經手了一套帶acl權限路由的管理系統後,才知道他的抽象能力有多強。真的是

    初聞不知曲中意,再聞已是曲中人。

    React 組合式開發實踐:打造企業管理系統五大核心模塊 [36]

  5. 三元大佬的 React Hooks 與 Immutable 數據流實戰,深入淺出的帶你實現一個音樂播放器。三元大家都認識吧?那是神,神帶你們寫應用項目,不學能說得過去嗎?React Hooks 與 Immutable 數據流實戰 [37]

  6. 深入理解 React 中的key
    understanding-reacts-key-prop[38]

    react 中爲何推薦設置 key[39]

  7. React 官方團隊成員對於派生狀態的思考:
    you-probably-dont-need-derived-state[40]

React Hook

你必須熟練掌握 Hook 的技巧,除了官網文檔熟讀以外:

  1. 推薦 Dan 的博客,他就是 Hook 的代碼實際編寫者之一,看他怎麼說夠權威了吧?這裏貼心的送上漢化版。
    useEffect 完整指南 [41]
    看完這篇以後,進入 dan 的博客主頁 [42],找出所有和 Hook 有關的,全部精讀!

  2. 推薦黃子毅大佬的精讀週刊系列
    096. 精讀《useEffect 完全指南》.md[43]
    注意!不是隻看這一篇,而是這個倉庫裏所有有關於 React Hook 的文章都去看一遍,結合自己的思想分析。

  3. Hook 陷阱系列 還是 Dan 老哥的文章,詳細的講清楚了所謂閉包陷阱產生的原因和設計中的權衡。
    函數式組件與類組件有何不同?[44]

  4. 去找一些社區的精品自定義 hook,看看他們的開發和設計思路,有沒有能融入自己的日常開發中去的。
    精讀《Hooks 取數 - swr 源碼》[45]
    Umi Hooks - 助力擁抱 React Hooks[46]
    React Hooks 的體系設計之一 - 分層 [47]

React 性能優化

React 中優化組件重渲染,這裏有幾個隱含的知識點。
optimize-react-re-renders[48]

如何對 React 函數式組件進行性能優化?這篇文章講的很詳細,值得仔細閱讀一遍。如何對 React 函數式組件進行優化 [49]

React 單元測試

  1. 使用@testing-library/react測試組件,這個庫相比起 enzyme 更好的原因在於,它更注重於站在用戶的角度去測試一個組件,而不是測試這個組件的實現細節
    Introducing The React Testing Library[50]
    Testing Implementation Details[51]

  2. 使用@testing-library/react-hooks測試自定義 Hook
    how-to-test-custom-react-hooks[52]

React 和 TypeScript 結合使用

  1. 這個倉庫非常詳細的介紹瞭如何把 React 和 TypeScript 結合,並且給出了一些進階用法的示例,非常值得過一遍!
    react-typescript-cheatsheet[53]

  2. 這篇文章是螞蟻金服數據體驗技術部的同學帶來的,其實除了這裏面的技術文章以外,螞蟻金服的同學也由非常生動給我們講解了一個高級前端同學是如何去社區尋找方案,如何思考和落地到項目中的,由衷的佩服。
    React + Typescript 工程化治理實踐 [54]

  3. 微軟的大佬帶你寫一個類型安全的組件,非常深入,非常過癮...
    Writing Type-Safe Polymorphic React Components (Without Crashing TypeScript)[55]

  4. React + TypeScript 10 個需要避免的錯誤模式。
    10-typescript-pro-tips-patterns-with-or-without-react[56]

React 代碼抽象思考

  1. 何時應該把代碼拆分爲組件?
    when-to-break-up-a-component-into-multiple-components[57]

  2. 仔細思考你的 React 應用中,狀態應該放在什麼位置,是組件自身,提升到父組件,亦或是局部 context 和 redux,這會有益於提升應用的性能和可維護性。
    state-colocation-will-make-your-react-app-faster[58]

  3. 仔細思考 React 組件中的狀態應該如何管理,優先使用派生狀態,並且在適當的時候利用 useMemo、reselect 等庫去優化他們。
    dont-sync-state-derive-it[59]

  4. React Hooks 的自定義 hook 中,如何利用 reducer 的模式提供更加靈活的數據管理,讓用戶擁有數據的控制權。
    the-state-reducer-pattern-with-react-hooks[60]

TypeScript

自從 Vue3 橫空出世以來,TypeScript 好像突然就火了。這是一件好事,推動前端去學習強類型語言,開發更加嚴謹。並且第三方包的 ts 類型支持的加入,讓我們甚至很多時候都不再需要打開文檔對着 api 擼了。

關於 TypeScript 學習,其實幾個月前我還對於這門 JavaScript 的超集一竅不通,經過兩三個月的靜心學習,我能夠去理解一些相對複雜的類型了,

可以說 TypeScript 的學習和學一個庫或者學一個框架是完全不同的,

入門

  1. 除了官方文檔以外,還有一些比較好的中文入門教程。
    TypeScript Handbook 入門教程 [61]

  2. TypeScript Deep Dive 非常高質量的英文入門教學。
    TypeScript Deep Dive[62]

  3. 工具泛型在日常開發中都非常的常用,必須熟練掌握。
    TS 一些工具泛型的使用及其實現 [63]

  4. 視頻課程,還是黃軼大佬的,並且這個課程對於單元測試、前端手寫框架、以及網絡請求原理都非常有幫助。
    基於 TypeScript 從零重構 axios[64]

進階

  1. 這五篇文章裏藉助非常多的案例,爲我們講解了 ts 的一些高級用法,請務必反覆在 ide 裏嘗試,理解,不懂的概念及時回到文檔中補習。
    巧用 TypeScript 系列 一共五篇 [65]

  2. TS 進階非常重要的一點,條件類型,很多泛型推導都需要藉助它的力量。
    conditional-types-in-typescript[66]

  3. 以及上面那個大佬博客中的所有 TS 文章。
    https://mariusschulz.com

實戰

  1. 一個參數簡化的實戰,涉及到的高級知識點非常多。

  2. 🎉TypeScript 的高級類型(Advanced Type)

  3. 🎉Conditional Types (條件類型)

  4. 🎉Distributive conditional types (分佈條件類型)

  5. 🎉Mapped types(映射類型)

  6. 🎉 函數重載
    TypeScript 參數簡化實戰 [67]

  7. 實現一個簡化版的 Vuex,同樣知識點結合滿滿。

  8. 🎉TypeScript 的高級類型(Advanced Type[68])

  9. 🎉TypeScript 中利用泛型進行反向類型推導。(Generics[69])

  10. 🎉Mapped types(映射類型)

  11. 🎉Distributive Conditional Types(條件類型分配)

  12. 🎉TypeScript 中 Infer 的實戰應用(Vue3 源碼裏 infer 的一個很重要的使用 [70])
    TS 實現智能類型推導的簡化版 Vuex[71]

刻意訓練

它幾乎是一門新的語言(在類型世界裏來說),需要你花費很大的精力去學好它。

我對於 TypeScript 的學習建議其實就是一個關鍵詞:刻意訓練,在過基礎概念的時候,不厭其煩的在vscode中敲擊,理解,思考。在基礎概念過完以後去尋找實踐文章,比如我上面進階實戰部分推薦的幾篇,繼續刻意訓練,一定要堆積代碼量,學習一門新的語言是不可能靠看文檔獲得成功的。

我會建立一個倉庫,專門記錄我遇到的 TypeScript 的有趣代碼 [72],自己動手敲一遍,並且深入理解。

能力分級

其實 TypeScript 的能力也是兩級分化的,日常寫業務來說,你定義一些 interface,配合 React.FC 這種官方內置的類型也就跑通了,沒什麼特別難的點。

但是如果是造輪子呢?如果你自己寫了一個工具庫,並且類型比較複雜,你能保證推導出來嗎?亦或者就拿 Vue3 來說,ref 是一個很複雜的嵌套類型,

假如我們這樣定義一個值const value = ref(ref(2)),對於嵌套的 ref,Vue3 會做一層拆包,也就是說其實ref.value會是 2,

那麼它是如何讓 ts 提示出 value 的類型是 number 的呢?

如果你看到源碼裏的這段代碼,你只有基礎的話,保證懵逼。
Vue3 跟着尤雨溪學 TypeScript 之 Ref 類型從零實現 [73]

// Recursively unwraps nested value bindings.
export type UnwrapRef<T> = {
  cRef: T extends ComputedRef<infer V> ? UnwrapRef<V> : T
  ref: T extends Ref<infer V> ? UnwrapRef<V> : T
  array: T
  object: { [K in keyof T]: UnwrapRef<T[K]}
}[T extends ComputedRef<any>
  ? 'cRef'
  : T extends Array<any>
    ? 'array'
    : T extends Ref | Function | CollectionTypes | BaseTypes
      ? 'ref' // bail out on types that shouldn't be unwrapped
      : T extends object ? 'object' : 'ref']
業務開發人員

如果短期內你對自己的要求是能上手業務,那麼你理解 TypeScript 基礎的interfacetype編寫和泛型的普通使用(可以理解爲類型系統裏的函數傳參)也已經足夠。

框架開發人員

但是長期來看,如果你的目的是能夠自己編寫一些類型完善的庫或框架,或者說你在公司扮演前端架構師輪子專家等等角色,經常需要寫一些偏底層的庫給你的小夥伴們使用,那麼你必須深入學習,這樣才能做到給你的框架使用用戶完美的類型體驗。

面試題

TypeScript 相關的面試題我見得不多,不過力扣中國的面試題算是難度偏高的,其中有一道 TS 的面試題,可以說是實用性和難度都有所兼顧,簡單來說就是解包。

// 解開參數和返回值中的Promise
asyncMethod<T, U>(input: Promise<T>): Promise<Action<U>>
 ↓
asyncMethod<T, U>(input: T): Action<U>

// 解開參數中的Action
syncMethod<T, U>(action: Action<T>): Action<U>
 ↓
syncMethod<T, U>(action: T): Action<U>

我在高強度學習了兩三個月 TS 的情況下,已經能把這道題目相對輕鬆的解出來,相信這也是說明我的學習路線沒有走偏(題解就不放了,尊重面試題,其實就是考察了映射類型infer的使用)。
力扣面試題 [74]

代碼質量

代碼風格

  1. 在項目中集成 Prettier + ESLint + Airbnb Style Guideintegrating-prettier-eslint-airbnb-style-guide-in-vscode[75]

  2. 在項目中集成 ESLint with Prettier, TypeScript[76]

高質量架構

  1. 如何重構一個過萬 Star 開源項—BetterScroll,是由滴滴的大佬嵇智 [77] 所帶來的,無獨有偶的是,這篇文章除了詳細的介紹一個合格的開源項目應該做到的代碼質量保證,測試流程,持續集成流程以外,也體現了他的一些思考深度,非常值得學習。
    如何重構一個過萬 Star 開源項目—BetterScroll[78]

Git 提交信息

  1. 很多新手在提交 Git 信息的時候會寫的很隨意,比如fixtest修復,這麼糊弄的話是會被 leader 揍的!

    [譯] 如何撰寫 Git 提交信息 [79]

    Git-Commit-Log 規範(Angular 規範)[80]

    commitizen[81] 規範流程的 commit 工具,規範的 commit 格式也會讓工具幫你生成友好的changelog

構建工具

  1. webpack 基礎和優化
    深入淺出 webpack[82]

  2. 滴滴前端工程師的 webpack 深入源碼分析系列,非常的優秀。
    webpack 系列之一總覽 [83]

性能優化

  1. 推薦修言大佬的性能優化小冊 [84],這個真的是講的深入淺出,從webpack網絡dom操作,全方位的帶你做一些性能優化實戰。這本小冊我當時看的時候真的是完全停不下來,修言大佬的風格既輕鬆又幽默。但是講解的東西卻能讓你受益匪淺。

  2. 谷歌開發者性能優化章節,不用多說了吧?很權威了。左側菜單欄裏還有更多相關內容,可以按需選擇學習。
    user-centric-performance-metrics[85]

  3. 詳談合成層,合成層這個東西離我們忽遠忽近,可能你的一個不小心的操作就造成層爆炸,當然需要仔細關注啦。起碼,在性能遇到瓶頸的時候,你可以打開 chrome 的layer面板,看看你的頁面到底是怎麼樣的一個層分佈。
    詳談層合成(composite)[86]

  4. 劉博文大佬的性能優化指南,非常清晰的講解了網頁優化的幾個重要的注意點。
    讓你的網頁更絲滑 [87]

社區討論

作爲一個合格的前端工程師,一定要積極的深入社區去了解最新的動向,比如在twitter上關注你喜歡的技術開發人員,如 Dan、尤雨溪。

另外 Github 上的很多 issue 也是寶藏討論,我就以最近我對於 Vue3 的學習簡單的舉幾個例子。

爲什麼 Vue3 不需要時間切片?

尤雨溪解釋關於爲什麼在 Vue3 中不加入 React 時間切片功能?並且詳細的分析了 React 和 Vue3 之間的一些細節差別,狠狠的吹了一波 Vue3(愛了愛了)。
Why remove time slicing from vue3?[88]

Vue3 的composition-api到底好在哪?

Vue3 的 functional-api 相關的 rfc,尤大舌戰羣儒,深入淺出的爲大家講解了 Vue3 的設計思路等等。
Amendment proposal to Function-based Component API[89]

Vue3composition-api的第一手文檔

vue-composition-api 的 rfc 文檔,在國內資料還不齊全的情況下,我去閱讀了
vue-composition-api-rfc[90] 英文版文檔,對於裏面的設計思路歎爲觀止,學到了非常非常多尤大的思想。

總之,對於你喜歡的倉庫,都可以去看看它的 issue 有沒有看起來感興趣的討論,你也會學到非常多的東西。並且你可以和作者保持思路上的同步,這是非常難得的一件事情。

關於 Hook 的一些收穫

我在狠狠的吸收了一波尤大對於 Vue3 composition-api的設計思路的講解,新舊模式的對比以後,這篇文章就是我對 Vue3 新模式的一些見解。
Vue3 Composition-Api + TypeScript + 新型狀態管理模式探索。[91]

在 Vue2 裏,可以通過plugin先體驗composition-api,截取這篇文章對應的實戰項目中的一小部分代碼吧:

<template>
  <Books :books="booksAvaluable" :loading="loading" />
</template>

<script lang="ts">
import { createComponent } from '@vue/composition-api';
import Books from '@/components/Books.vue';
import { useAsync } from '@/hooks';
import { getBooks } from '@/hacks/fetch';
import { useBookListInject } from '@/context';
export default createComponent({
  name: 'books',
  setup() {
    const { books, setBooks, booksAvaluable } = useBookListInject();
    const loading = useAsync(async () ={
      const requestBooks = await getBooks();
      setBooks(requestBooks);
    });
    return { booksAvaluable, loading };
  },
  components: {
    Books,
  },
});
</script>

<style>
.content {
  max-width: 700px;
  margin: auto;
}
</style>

本實戰對應倉庫:

vue-bookshelf[92]

並且由於它和React Hook在很多方面的思想也非常相近,這甚至對於我在React Hook上的使用也大有裨益,比如代碼組織的思路上,

在第一次使用Hook開發的時候,大部分人可能還是會保留着以前的思想,把state集中起來定義在代碼的前一大段,把computed集中定義在第二段,把mutation定義在第三段,如果不看尤大對於設計思想的講解,我也一直是在這樣做。

但是爲什麼 Logical Concerns 優於 Vue2 和 React Class Component 的 Option Types?看完 detailed-design[93] 這個章節你就全部明白了,並且這會融入到你日常開發中去。

總之,看完這篇以後,我果斷的把公司裏的首屏組件的一坨代碼直接抽成了 n 個自定義 hook,維護效率提升簡直像是坐火箭。

當然,社區裏的寶藏 issue 肯定不止這些,我只是簡單的列出了幾個,但就是這幾個都讓我的技術視野開闊了很多,並且是真正的融入到公司的業務實戰中去,是具有業務價值的。希望你養成看 issue,緊跟英文社區的習慣,Github issue 裏單純的技術探討氛圍,真的是國內很少有社區可以媲美的。

function AppInner({ children }) {
  const [menus, setMenus] = useState({});

  // 用戶信息
  const user = useUser();

  // 主題能力
  useTheme();

  // 權限獲取
  useAuth({
    setMenus,
  });

  // 動態菜單也需要用到菜單的能力
  useDynamicMenus({
    menus,
    setMenus,
  });

  return (
    <Context.Provider value={user}>
      <Layout routers={backgrounds}>{children}</Layout>
    </Context.Provider>
  );
}

可以看到,Hook在代碼組織的方面有着得天獨厚的優勢,甚至各個模塊之間值的傳遞都是那麼的自然,僅僅是函數傳參而已。
總之,社區推出一些新的東西,它總歸是解決了之前的一些痛點。我們跟着大佬的思路走,一定有肉喫。

Tree Shaking 的 Issue

相學長的文章你的 Tree-Shaking 並沒什麼卵用 [94] 中,也詳細的描述了他對於副作用的一些探尋過程,在 UglifyJS 的 Issue[95] 中找到了最終的答案,然後貢獻給中文社區,這些內容最開始不會在任何中文社區裏出現,只有靠你去探尋和發現。

學習方法的轉變

從初中級前端開始往高級前端進階,有一個很重要的點,就是很多情況下國內社區能找到的資料已經不夠用了,而且有很多優質資料也是從國外社區二手、三手翻譯過來的,翻譯質量也不能保證。

這就引申出我們進階的第一個點,開始接受英文資料

這裏很多同學說,我的英文能力不行啊,看不懂。其實我想說,筆者的英語能力也很一般,從去年開始我立了個目標,就是帶着劃詞翻譯插件也要開始艱難的看英文文章和資料,遇到不懂的單詞就劃出來看兩眼(沒有刻意去背),第五六次遇見這個單詞的時候,就差不多記得它是什麼意思了。

半年左右的時間下來,(大概保持每週 3 篇以上的閱讀量)能肉眼可見的感覺自己的英語能力在進步,很多時候不用劃詞翻譯插件,也可以完整的閱讀下來一段文章。

這裏是我當時閱讀英文優質文章的一些記錄,

英文技術文章閱讀 [96]

後面英文閱讀慢慢成了一件比較自然的事情,也就沒有再刻意去記錄,前期可以用這種方式激勵自己。

推薦兩個英文站點吧,有很多高質量的前端文章。

dev.to[97]
medium[98]

medium 可能需要藉助一些科學工具才能查看,但是裏面的會員付費以及作者激勵機制使得文章非常的優質。登錄自己的谷歌賬號即可成爲會員,前期可能首頁不會推薦一些前端相關的文章,你可以自己去搜索關鍵字如VueReactWebpack,任何你興趣的前端技術棧,不需要過多久你的首頁就會出現前端的推薦內容。好好享受這個高質量的英文社區吧。

關於實踐

社區有很多大佬實力很強,但是對新手寫的代碼嗤之以鼻,認爲有 any 的就不叫 TypeScript、認爲沒有單元測試就沒資格丟到 Github 上去。這種言論其實也不怪他們,他們也只是對開源軟件的要求高到偏執而已。但是對於新手學習來說,這種言論很容易對大家造成打擊,導致不敢寫 ts,寫的東西不敢放出來。其實大可不必,工業聚 對於這些觀點就發表了一篇很好的看法,讓我覺得深受打動,也就是這篇文章開始,我慢慢的把舊項目用 ts 改造起來,慢慢的進步。

Vue 3.0 公開代碼之後……

總結

本篇文章是我在這一年多的學習經歷抽象中總結出來,還有很多東西我會陸續加入到這篇文章中去。

希望作爲初中級前端工程師的你,能夠有所收穫。如果能夠幫助到你就是我最大的滿足。


················· 若川簡介 ·················

你好,我是若川,畢業於江西高校。現在是一名前端開發 “工程師”。寫有《學習源碼整體架構系列》多篇,在知乎、掘金收穫超百萬閱讀。
從 2014 年起,每年都會寫一篇年度總結,已經寫了 7 篇,點擊查看年度總結
同時,活躍在知乎 @若川,掘金 @若川。致力於分享前端開發經驗,願景:幫助 5 年內前端人走向前列。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/-kuak_S3LqKOkE1MBJQHGw