首页
/ After.js 项目升级指南:从 v1/v2 迁移到最新版本

After.js 项目升级指南:从 v1/v2 迁移到最新版本

2025-07-09 01:23:11作者:滑思眉Philip

前言

After.js 是一个基于 React 的服务端渲染框架,它建立在 Razzle 之上,提供了更简单的路由和数据获取方案。本文将详细介绍如何将 After.js 项目从旧版本升级到最新版本,包括从 v1 到 v2 以及从 v2 到 v3 的迁移过程。

从 v2 升级到 v3

主要变更

v3 版本的主要变更是将 react-helmet 从版本 5 升级到了版本 6。这个升级带来了一个重要的 API 变化:

依赖更新

运行以下命令更新依赖:

yarn upgrade @jaredpalmer/after react-helmet --latest

或使用 npm:

npm install @jaredpalmer/after@latest react-helmet@latest --save

代码变更

react-helmet 从版本 5 到版本 6 的升级中,将默认导出改为了命名导出:

旧代码:

import Helmet from 'react-helmet';

新代码:

import { Helmet } from "react-helmet";

这个变化不会影响 After.js 本身的功能,但需要开发者修改所有使用 Helmet 的代码文件。

从 v1 升级到 v2

为什么需要升级?

v2 版本解决了 v1 中存在的性能问题:

  1. 更快的资源加载:在 v1 中,浏览器需要先下载 client.js,解析并执行后,才能开始获取当前页面所需的其他代码块(chunks)。这导致了明显的延迟。

  2. 样式闪烁问题:由于 CSS 文件也是按需加载的,页面会先以无样式状态渲染,然后突然应用样式,造成不好的用户体验。

  3. 浏览器渲染机制:浏览器对 CSS 是渲染阻塞的,如果 CSS 在页面渲染后才加载,浏览器需要重新绘制整个页面,这是非常耗性能的操作。

v2 版本通过在服务器响应中直接包含所有需要的 JS 和 CSS 文件,解决了这些问题。

升级步骤

1. 更新依赖

运行以下命令:

yarn upgrade @jaredpalmer/after razzle --latest

或使用 npm:

npm install @jaredpalmer/after@latest razzle@latest --save

2. 添加 Babel 插件

在项目根目录创建或更新 .babelrc 文件:

{
  "presets": ["razzle/babel"],
  "plugins": ["after"]
}

这个插件会自动处理代码分割相关的配置,简化开发流程。

3. 更新服务器文件

修改 server.js,添加 chunks 清单:

import chunks from './build/chunks.json';  // 新增导入

const server = express();
server
  .disable('x-powered-by')
  .use(express.static(process.env.RAZZLE_PUBLIC_DIR))
  .get('/*', async (req, res) => {
    try {
      const html = await render({
        req,
        res,
        document: MyDocument,
        chunks,  // 新增参数
        routes,
        assets,
      });
      res.send(html);
    } catch (error) {
      console.log(error);
      res.json(error);
    }
  });

4. 更新文档组件

如果你使用了自定义的 Document.js,需要更新它以使用新的资源加载方式:

import {
  AfterRoot,
  AfterData,
  AfterScripts,
  AfterStyles,  // 新增导入
} from '@jaredpalmer/after';

class Document extends React.Component {
  // ... 其他代码保持不变
  
  render() {
    return (
      <html>
        <head>
          {/* ... 其他 head 内容 */}
          <AfterStyles />  {/* 替换原来的样式链接 */}
        </head>
        <body>
          <AfterRoot />
          <AfterData />
          <AfterScripts />  {/* 替换原来的脚本标签 */}
        </body>
      </html>
    );
  }
}

高级配置

手动配置代码分割

如果你选择不使用 Babel 插件,需要手动配置路由:

{
  path: '/about',
  component: asyncComponent({
    loader: () => import(/* webpackChunkName: "AboutPage" */ './About'),
    chunkName: 'AboutPage',  // 必须与 webpackChunkName 一致
  }),
}

Babel 插件的限制

Babel 插件无法处理动态生成的路由配置。例如:

function createRoute(name) {
  return {
    path: `/${name.toLowerCase()}`,
    component: asyncComponent({
      loader: () => import(`./pages/${name}`),
    }),
  };
}

对于这种情况,需要手动添加 webpack 魔法注释和 chunkName:

function createRoute(name) {
  return {
    path: `/${name.toLowerCase()}`,
    component: asyncComponent({
      loader: () => import(/* webpackChunkName: "[request]" */ `./pages/${name}`),
      chunkName: name,
    }),
  };
}

升级后的优势

  1. 更快的首屏渲染:所有资源在初始响应中发送,减少了额外的网络请求。
  2. 更好的用户体验:避免了样式闪烁问题。
  3. 更符合浏览器渲染机制:CSS 在正确的时间加载,减少了不必要的重绘。
  4. 简化的开发流程:通过 Babel 插件自动处理大部分代码分割配置。

总结

After.js 的 v2 和 v3 版本带来了显著的性能改进和开发体验提升。通过遵循本指南,你可以顺利地将项目升级到最新版本,享受这些改进带来的好处。升级过程大多数情况下只需要简单的依赖更新和少量代码修改,不会影响现有的业务逻辑。