2019 年即將結束,回顧這一年,前端領域依然保持着高速迭代的節奏。React Hooks 全面鋪開、Vue 3 進入 RFC 階段、TypeScript 成為越來越多團隊的標配。站在 2019 年末,我想對 2020 年的技術趨勢做一些預判,既是給自己定方向,也希望能給大家一些參考。
Vue 3 正式版即將到來
Vue 3 從 2018 年底宣佈重寫,到 2019 年陸續公開 RFC,核心團隊在 Composition API、響應式系統、TypeScript 重寫等方面做了大量工作。從 Evan You 和核心團隊的動態來看,Vue 3.0 正式版大概率會在 2020 年 Q1-Q2 發佈。
Composition API 是最受關注的變更,它讓邏輯複用不再依賴 mixins:
// Vue 2.x 的 mixins 方式,存在命名衝突和來源不明的問題
const loggerMixin = {
created() {
console.log('組件創建:', this.$options.name)
},
methods: {
log(message) {
console.log(`[${this.$options.name}]`, message)
}
}
}
// Vue 3 Composition API,邏輯清晰、類型友好
import { ref, onMounted, computed } from 'vue'
export function useCounter(initialValue = 0) {
const count = ref(initialValue)
const double = computed(() => count.value * 2)
function increment() {
count.value++
}
function decrement() {
count.value--
}
onMounted(() => {
console.log('Counter 組件已掛載, 初始值:', initialValue)
})
return { count, double, increment, decrement }
}
Composition API 的優勢顯而易見:邏輯複用更清晰、TypeScript 推導更友好、代碼組織更靈活。對於我們的組件庫來説,Vue 3 的支持將是 2020 年的重要工作。
React Concurrent Mode 的探索
React 16.8 引入 Hooks 之後,React 團隊將重心轉向了 Concurrent Mode。這是一項根本性的調度機制變革,允許 React 同時準備多個版本的 UI,根據優先級決定哪些更新先渲染。
// Concurrent Mode 的核心理念示例
// 開啓 Concurrent Mode
import { createRoot } from 'react-dom'
const root = createRoot(document.getElementById('app'))
root.render(<App />)
// 使用 useTransition 標記低優先級更新
import { useState, useTransition } from 'react'
function SearchResults() {
const [query, setQuery] = useState('')
const [results, setResults] = useState([])
const [isPending, startTransition] = useTransition()
function handleSearch(e) {
const value = e.target.value
setQuery(value) // 高優先級:輸入框立即響應
startTransition(() => {
// 低優先級:搜索結果可以延遲
setResults(performSearch(value))
})
}
return (
<div>
<input value={query} onChange={handleSearch} />
{isPending ? (
<Spinner />
) : (
<ResultList results={results} />
)}
</div>
)
}
Concurrent Mode 目前仍是實驗性特性,2020 年預計會進入穩定階段。它的核心價值在於:用户輸入永遠不會被高開銷的渲染阻塞,體驗將大幅提升。
Vite 的萌芽
Evan You 在開發 Vue 3 的過程中,創造了一個名為 Vite 的開發服務器。Vite 利用瀏覽器原生 ES Module 支持,在開發環境下無需打包,實現秒級啓動和即時熱更新。
// Vite 的核心原理非常簡潔
// 開發環境下,瀏覽器直接請求 ES Module
// index.html
// <script type="module" src="/src/main.js"></script>
// 瀏覽器發出請求時,Vite 按需編譯
// /src/main.js -> 編譯後返回
// /src/components/Foo.vue -> 實時編譯 .vue 文件返回
// vite.config.js 基礎配置
export default {
// 開發服務器配置
server: {
port: 3000,
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
},
// 生產構建使用 Rollup
build: {
rollupOptions: {
input: 'index.html'
}
}
}
Vite 在 2019 年還處於非常早期的階段,但它代表的理念——利用瀏覽器原生能力而非重度打包——很可能是 2020 年乃至更遠未來的重要方向。
Deno 能否撼動 Node.js
Node.js 之父 Ryan Dahl 在 2018 年 JSConf 上公開了他對 Node.js 的 10 大遺憾,併發布了 Deno 項目。到了 2019 年,Deno 已經具備了不少實用特性:
// Deno 的核心特性對比 Node.js
// 1. 原生 TypeScript 支持,無需配置
// hello.ts
const greeting: string = 'Hello, Deno!'
console.log(greeting)
// 2. 使用 URL 導入,無需 npm/yarn
import { serve } from 'https://deno.land/std/http/server.ts'
const server = serve({ port: 8000 })
console.log('HTTP server running on http://localhost:8000/')
for await (const req of server) {
req.respond({ body: 'Hello World\n' })
}
// 3. 安全模型:默認無權限,需顯式授權
// deno run --allow-net --allow-read server.ts
// 4. 內置工具鏈
// deno test 運行測試
// deno fmt 代碼格式化
// deno bundle 打包
// deno doc 生成文檔
Deno 的理念先進,但在 2020 年要撼動 Node.js 的地位仍然很難。生態是最大的壁壘——npm 上百萬個包不會一夜遷移。但 Deno 在內部工具、腳本場景中值得嘗試。
pnpm 的增長趨勢
包管理器領域,npm 和 yarn 佔據了絕大多數份額。但 pnpm 憑藉其獨特的 node_modules 結構,在 2019 年獲得了越來越多的關注。
# pnpm 使用硬鏈接和符號鏈接,避免重複安裝
# 安裝速度對比(內部項目測試)
npm install # 45s
yarn install # 32s
pnpm install # 12s
# node_modules 結構差異
# npm/yarn: 扁平化,存在幽靈依賴問題
node_modules/
lodash/ # 直接依賴
axios/ # 依賴的依賴也能被項目訪問到(幽靈依賴)
# pnpm: 嚴格隔離
node_modules/
.pnpm/
lodash@4.17.21/node_modules/lodash/
axios@0.19.2/node_modules/axios/
lodash -> .pnpm/lodash@4.17.21/node_modules/lodash # 符號鏈接
axios -> .pnpm/axios@0.19.2/node_modules/axios
pnpm 的嚴格依賴隔離解決了幽靈依賴問題,這在大型 monorepo 項目中尤為重要。2020 年我預計 pnpm 的市場份額會有顯著提升。
CSS-in-JS vs Utility CSS 的爭論
2019 年,CSS 方案的爭論依然激烈。一邊是 styled-components、Emotion 等 CSS-in-JS 方案,另一邊是 Tailwind CSS 代表的 Utility First 方案。
// CSS-in-JS 方案 (styled-components)
import styled from 'styled-components'
const Button = styled.button`
padding: 8px 16px;
border-radius: 4px;
font-size: 14px;
background: ${props => props.primary ? '#1890ff' : '#fff'};
color: ${props => props.primary ? '#fff' : '#333'};
border: ${props => props.primary ? 'none' : '1px solid #d9d9d9'};
&:hover {
opacity: 0.85;
}
`
// Utility CSS 方案 (Tailwind CSS)
function Button({ primary, children }) {
return (
<button
className={`
px-4 py-2 rounded text-sm
${primary
? 'bg-blue-500 text-white border-none'
: 'bg-white text-gray-800 border border-gray-300'
}
hover:opacity-85
`}
>
{children}
</button>
)
}
我的判斷是:大型應用中 CSS-in-JS 依然有其價值(主題化、動態樣式),但 Tailwind CSS 代表的 Utility CSS 在 2020 年會有更大的增長。它的學習曲線雖然陡峭,但一旦團隊適應,開發效率和樣式一致性都有保障。
小結
- Vue 3 正式版預計 2020 年上半年發佈,Composition API 將改變 Vue 的代碼組織方式
- React Concurrent Mode 仍處實驗階段,但 useTransition 等 API 值得提前學習
- Vite 利用瀏覽器原生 ES Module,可能改變開發服務器的工作方式
- Deno 理念先進但生態薄弱,2020 年適合觀望和內部嘗試
- pnpm 憑藉嚴格的依賴隔離,在大型項目中優勢明顯
- CSS-in-JS 和 Utility CSS 各有適用場景,Tailwind CSS 增長勢頭強勁
- 作為前端工程師,保持對新趨勢的敏感度,但不過度追逐,選擇性深入學習