As 2019 draws to a close, the frontend landscape kept moving at a rapid pace. React Hooks went mainstream, Vue 3 entered its RFC phase, and TypeScript became standard in more and more teams. From this vantage point at the end of 2019, I want to make a few predictions about 2020's tech trends—partly to set my own direction, and hopefully to give you some reference as well.
Vue 3 Official Release Coming Soon
Vue 3 was announced as a rewrite at the end of 2018, and through 2019 its RFCs were published one after another. The core team did a great deal of work on the Composition API, the reactivity system, and the TypeScript rewrite. Based on signals from Evan You and the core team, the Vue 3.0 stable release will most likely ship in Q1–Q2 of 2020.
The Composition API is the most anticipated change—it lets logic reuse stop depending on 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 }
}
The advantages of the Composition API are clear: cleaner logic reuse, friendlier TypeScript inference, and more flexible code organization. Supporting Vue 3 will be important work for our component library in 2020.
Exploring React Concurrent Mode
After React 16.8 introduced Hooks, the React team shifted its focus to Concurrent Mode. This is a fundamental change to the scheduling mechanism: it lets React prepare multiple versions of the UI at once and decide which updates render first based on priority.
// 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 is still experimental, but it's expected to stabilize during 2020. Its core value is that user input is never blocked by expensive rendering, which significantly improves the experience.
The Seeds of Vite
While building Vue 3, Evan You created a dev server called Vite. Vite leverages the browser's native ES Module support, so there's no bundling in development—giving it near-instant startup and hot updates.
// 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 was still in a very early stage in 2019, but the philosophy it represents—leveraging the browser's native capabilities instead of heavy bundling—is likely an important direction for 2020 and well beyond.
Can Deno Shake Up Node.js?
Ryan Dahl, the creator of Node.js, publicly shared his "10 regrets" about Node.js at JSConf 2018 and launched the Deno project. By 2019, Deno had already gained a number of practical features:
// 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's philosophy is advanced, but shaking Node.js's position in 2020 is still a tall order. The ecosystem is the biggest barrier—millions of packages on npm won't migrate overnight. Still, Deno is worth trying for internal tooling and scripting.
pnpm's Growing Trend
In the package-manager space, npm and yarn still hold the vast majority of the market. But pnpm, with its unique node_modules structure, drew increasing attention in 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's strict dependency isolation solves the phantom-dependency problem, which matters especially in large monorepo projects. I expect pnpm's market share to grow significantly in 2020.
CSS-in-JS vs Utility CSS Debate
In 2019, the debate over CSS approaches was still fierce. On one side are CSS-in-JS solutions like styled-components and Emotion; on the other is the Utility First approach represented by Tailwind CSS.
// 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>
)
}
My take: CSS-in-JS still earns its place in large apps (theming, dynamic styles), but Utility CSS as represented by Tailwind CSS will grow much faster in 2020. Its learning curve is steep, but once a team adapts, both development speed and style consistency are guaranteed.
Summary
- The Vue 3 stable release is expected in the first half of 2020; the Composition API will change how Vue code is organized
- React Concurrent Mode is still experimental, but APIs like
useTransitionare worth learning ahead of time - Vite leverages the browser's native ES Modules and could change how dev servers work
- Deno's philosophy is advanced but its ecosystem is thin; in 2020 it's worth watching and trying internally
- pnpm's strict dependency isolation gives it a clear edge in large projects
- CSS-in-JS and Utility CSS each fit different scenarios; Tailwind CSS's momentum is strong
- As frontend engineers, stay sensitive to new trends—but don't chase every one; pick selectively and learn deeply
