服务端渲染(SSR)中模块化有哪些注意事项?
SSR 模块化挑战
- Node.js 和浏览器环境差异
- CJS vs ESM 在 SSR 中的处理
- 模块副作用在服务端的行为
- 条件导出的服务端入口
1. 环境差异
import { DOMPurify } from 'dompurify'
let DOMPurify
if (typeof window !== 'undefined') {
DOMPurify = (await import('dompurify')).default
}
import DOMPurify from 'isomorphic-dompurify'
2. package.json 条件导出
{
"exports": {
".": {
"browser": "./dist/browser.js",
"node": "./dist/server.js",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
}
}
3. SSR 中的模块副作用
document.documentElement.classList.add('dark')
export function initTheme() {
if (typeof window === 'undefined') return
document.documentElement.classList.add('dark')
}
import { useEffect } from 'react'
useEffect(() => {
initTheme()
}, [])
4. 'use client' / 'use server'(React Server Components)
export default async function Page() {
const data = await fetch('https://api.example.com/data')
return <div>{data.title}</div>
}
'use client'
import { useState } from 'react'
export default function Counter() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(c => c + 1)}>{count}</button>
}
'use server'
export async function submitForm(formData) {
await saveToDatabase(formData)
}
5. Nuxt 中的模块处理
<!-- Vue 组件默认在服务端和客户端都渲染 -->
<script setup>
// 服务端和客户端都会执行的代码
const { data } = await useFetch('/api/data')
// 只在客户端执行
onMounted(() => {
window.scrollTo(0, 0)
})
// 只在服务端执行
if (import.meta.server) {
// 服务端专用逻辑
}
// 只在客户端执行
if (import.meta.client) {
// 客户端专用逻辑
}
</script>
6. SSR 中的动态导入
import { defineAsyncComponent } from 'vue'
const ClientOnlyChart = defineAsyncComponent(() =>
import('chart.js').then(mod => mod.default)
)
import dynamic from 'next/dynamic'
const Chart = dynamic(() => import('react-chartjs-2'), {
ssr: false
})
7. 服务器模块缓存
let currentUser = null
export function setUser(user) { currentUser = user }
export function createAppContext(req) {
return {
user: req.user,
}
}
8. 序列化与水合
export async function getServerSideProps() {
const data = await fetchData()
return { props: { data } }
}
9. CSS 模块在 SSR 中
import styles from './Button.module.css'
10. 第三方库兼容性
export default {
webpack: (config) => {
config.resolve.fallback = {
fs: false,
path: false,
}
return config
}
}
SSR 模块化检查清单
同分类其他题目