从create-next-app学到的

缘起

经过一段时间的折腾,最终我决定将前端框架确定为 next.js,并准备花一些时间深入进去,做一个比较牢固的掌握。

今天用 create-next-app 新建一个项目,发现有了一些新的变化,学到了一些新知识,特此记录。

globals.css

@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
  --foreground-rgb: 0, 0, 0;
  --background-start-rgb: 214, 219, 220;
  --background-end-rgb: 255, 255, 255;
}

@media (prefers-color-scheme: dark) {
  :root {
    --foreground-rgb: 255, 255, 255;
    --background-start-rgb: 0, 0, 0;
    --background-end-rgb: 0, 0, 0;
  }
}

body {
  color: rgb(var(--foreground-rgb));
  background: linear-gradient(to bottom, transparent, rgb(var(--background-end-rgb))) rgb(
      var(--background-start-rgb)
    );
}

新版本的 create-next-app 可以默认配置好 Tailwind CSS,方便很多。

我学到的 CSS 知识:

  • 使用:root 伪类定义全局自定义 CSS 属性。
  • 使用 prefers-color-scheme 媒体查询,适配系统深色主题。
  • css 属性中使用 var()调用自定义属性。

我的 CSS 知识比较薄弱,以前主要用 Bootstrap,做很少的自定义修改,很多基础的认知都缺乏,现在可以慢慢补上。

APP 路由

新版本的APP 路由是我非常喜欢的一点,我感觉应该是借鉴了 Svelte Kit 的理念。

不过,服务器组件和客户端组件的概念让我有点迷惑,还需要更多练习。下面是一个简单的例子,在 layout 中添加了一个通用导航。

// app/layout.js
import './globals.css';
import { Nav } from '@/components/nav';

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <main className="flex min-h-screen flex-col items-center">
          <Nav />
          {children}
        </main>
      </body>
    </html>
  );
}

// components/nav.jsx
('use client');
import { usePathname } from 'next/navigation';
import Link from 'next/link';
import clsx from 'clsx';

const navLinks = [
  { text: 'Home', link: '/' },
  { text: 'Login', link: '/login' }
];

export function Nav() {
  const pathname = usePathname();

  return (
    <nav className="m-5">
      <ul className="flex gap-5 underline">
        {navLinks.map((item) => (
          <Link
            href={item.link}
            key={item.text}
            className={clsx('hover:text-indigo-600', pathname === item.link && 'text-indigo-600')}
          >
            {item.text}
          </Link>
        ))}
      </ul>
    </nav>
  );
}

我发现中文版的文档是落后的,要查看最新的教程,应该直接阅读英文网站。Tailwind CSS 也有同样的毛病,中文版本的翻译进度跟不上最新的进展。

新版的 metadata 更加的强大,以下是一个标题模板的用例:

app/layout.js

export const metadata = {
  title: {
    template: '%s | Language Big Bang',
    default: 'Language Big Bang'
  },
  description: '外语分级阅读学习神器'
};

app/login/page.js

export const metadata = {
  title: 'Login',
  description: '账号登录'
};

What I Learned

  • APP 路由下默认是服务端组件,添加客户端组件,需要在文件开头指定'use client'
  • 使用 usePathname 获取当前路线名称
  • 使用 clsx 可以简化 className 组合的工作
  • metadata 的进阶用法