创建项目

从这一章节开始,我们将进入实战教程部分。在实战教程中,我们将会从环境准备开始,从简单到复杂,一步一步搭建一个真实的项目。

环境准备

Node.js

在开始使用前,你需要安装 Node.js,并保证 Node.js 版本不低于 16.2.0,我们推荐使用 Node.js 18 的 LTS 版本

你可以通过以下命令检查当前使用的 Node.js 版本:

node -v

如果你当前的环境中尚未安装 Node.js,或是安装的版本低于 16,可以通过 nvmfnm 安装需要的版本。

下面是通过 nvm 安装 Node.js 18 LTS 版本的例子:

# 安装 Node.js 18 的长期支持版本
nvm install 18 --lts

# 将刚安装的 Node.js 18 设置为默认版本
nvm alias default 18

# 切换到刚安装的 Node.js 18
nvm use 18
nvm 和 fnm

nvm 和 fnm 都是 Node.js 版本管理工具。相对来说,nvm 较为成熟和稳定,而 fnm 是使用 Rust 实现的,比 nvm 提供了更好的性能。

此外,在安装 nvm 或 fnm 后,然后只要仓库根目录下有内容为 lts/hydrogen.nvmrc 文件,进入这个仓库时就会自动安装或切换到正确的 Node.js 版本。

pnpm

推荐使用 pnpm 来管理依赖:

npm install -g pnpm@8
NOTE

Modern.js 同样支持使用 yarnnpm 进行依赖管理。

初始化项目

我们创建新的目录,通过命令行工具初始化项目:

mkdir myapp && cd myapp
npx @modern-js/create@latest

@modern-js/create 会提供一个可交互的问答界面,根据结果初始化项目,按照默认的选择进行初始化:

? 请选择你想创建的工程类型 Web 应用
? 请选择开发语言 TS
? 请选择包管理工具 pnpm
? 请选择构建工具 webpack

在生成项目后,Modern.js 会自动安装依赖、创建 git 仓库。

[INFO] 依赖自动安装成功
[INFO] git 仓库初始化成功
[INFO] 创建成功!
可在新项目的目录下运行以下命令:
pnpm run dev          # 启动开发服务器
pnpm run build        # 构建生产环境产物
pnpm run serve        # 启动生产环境服务
pnpm run lint         # 运行 ESLint 并自动修复问题
pnpm run new          # 启用可选功能或创建项目要素

现在,项目结构如下:

. ├── node_modules ├── src │ ├── modern-app-env.d.ts │ └── routes │ ├── index.css │ ├── layout.tsx │ └── page.tsx ├── modern.config.ts ├── package.json ├── pnpm-lock.yaml ├── README.md └── tsconfig.json

调试项目

在项目中执行 pnpm run dev 即可启动项目:

$ pnpm run dev

> modern dev

info    Starting dev server...
ready   Client compiled in 50 ms

  > Local:    http://localhost:8080/
  > Network:  http://192.168.0.1:8080/

在浏览器中打开 http://localhost:8000/,可以看到页面内容。

修改代码

我们将原本的示例代码删除,替换成一个简单的联系人列表:

src/routes/page.tsx
const getAvatar = (users: Array<{ name: string; email: string }>) =>
  users.map(user => ({
    ...user,
    avatar: `https://api.dicebear.com/7.x/pixel-art/svg?seed=${user.name}`,
  }));

const mockData = getAvatar([
  { name: 'Thomas', email: 'w.kccip@bllmfbgv.dm' },
  { name: 'Chow', email: 'f.lfqljnlk@ywoefljhc.af' },
  { name: 'Bradley', email: 'd.wfovsqyo@gpkcjwjgb.fr' },
  { name: 'Davis', email: '"t.kqkoj@utlkwnpwk.nu' },
]);

function App() {
  return (
    <ul>
      {mockData.map(({ name, avatar, email }) => (
        <li key={name}>
          <img src={avatar} width={60} height={60} /> ---
          <span>{name}</span> ---
          <span>{email}</span>
        </li>
      ))}
    </ul>
  );
}

export default App;

删除多余的 css 文件,保持目录没有多余的文件:

rm src/routes/index.css

因为框架默认支持 HMR,可以看到 http://localhost:8080/ 里的内容会自动更新为:

result

此刻的页面还没有样式。下一章节将展开这部分的内容。

开启 SSR

接下来,我们修改项目中的 modern.config.ts,开启 SSR 能力:

modern.config.ts
import { appTools, defineConfig } from '@modern-js/app-tools';

export default defineConfig({
  runtime: {
    router: true,
    state: true,
  },
  server: {
    ssr: true,
  },
  plugins: [appTools()],
});

重新执行 pnpm run dev,可以发现项目已经在服务端完成了页面渲染。