Skip to content

第 1 章:创建项目

1. 环境搭建

开发环境

本项目默认使用 Node.js 22,如果使用其他组合如 Deno 或 Bun 也可以运行本项目,但是需要自行修改配置文件。在搭建环境之前,请确保已经安装了 Git、VS Code 等基础开发工具,本文使用 VS Code 开发。

1.1 安装 Node.js

NVM 是 Node.js 的版本管理工具,可以方便的切换 Node.js 的版本。可以使用如下命令安装 NVM:

bash
winget install CoreyButler.NVMforWindows

Windows 用户也可以到 NVM for Windows 下载安装包 nvm-setup.exe 手动安装。

本项目默认使用 Node.js 22,下面安装 Node.js 22:

bash
nvm install 22 --lts
nvm use 22

如果没有安装 pnpm,请继续安装 pnpm

bash
corepack enable
corepack install -g pnpm@latest
pnpm setup

如果 corepack install 命令失败,则可以更新 corepack

bash
npm i -g corepack

然后重新运行上述命令。

1.2 安装 Rust

本项目使用 Tauri 开发移动端和桌面端应用,需要安装 Rust:

bash
winget install -e Rustlang.Rustup

1.3 安装 Android 开发环境

首先需要安装 Rust 的 Android 交叉编译工具链:

bash
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android

下载并安装 Android Studio,安装 Android SDK 和 NDK。

首先需要配置环境变量,例如,在 Windows 上需要配置如下的 Android SDK 路径和 NDK 路径:

properties
ANDROID_HOME=%LOCALAPPDATA%\Android\Sdk
NDK_HOME=%LOCALAPPDATA%\Android\Sdk\ndk\28.0.12674087

1.4 安装 iOS 开发环境(可选)

本节需要在 MacOS 上进行操作,确保你的 MacOS 版本在 15.0 以上。并且已经初始化 Xcode 开发环境:

bash
sudo xcode-select --install

安装 Rust 的 iOS 交叉编译工具链:

bash
rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios

在 MacOS 上安装 Xcode,然后安装 iOS SDK 和模拟器等环境。

2. 创建项目

2.1 初始化 Nuxt 项目

本项目全部使用 pnpm 来管理依赖,创建一个空的 Nuxt 项目:

bash
pnpm dlx nuxi@latest init nuxt-chat-im

配置代理

如果此时出现错误,则需要代理访问,开启代理后可设置终端变量 HTTP_PROXYHTTPS_PROXY 来访问。

出现提示后,选择 pnpm 作为包管理工具,然后回车确认创建 Git 仓库。

安装完成后,测试项目是否正常运行:

bash
cd nuxt-chat-im
pnpm dev -o

等待几秒钟后,看到 Welcome to Nuxt! 代表项目创建成功。

2.2 安装 Tailwind CSS

Tailwind CSS 是一个原子化 CSS 框架,可以快速构建页面,编写容易维护的样式。

安装 Tailwind CSS 和相关插件:

bash
pnpm add -D tailwindcss@3 @nuxtjs/tailwindcss @tailwindcss/typography daisyui

@nuxtjs/tailwindcss 是 Nuxt 的 Tailwind CSS 插件,可自动配置项目。@tailwindcss/typography 是 Tailwind CSS 的排版插件,用于文章等信息排版。daisyui 是一个 Tailwind CSS 的 UI 库,提供了一些常用的组件。

Tailwind CSS 4

本项目并未采用最新的 Tailwind CSS 4,因为生态中的各类插件尚未完全支持最新版本,故当前采用 Tailwind CSS 3。

新建 tailwind.config.ts 文件:

ts
import type { Config } from 'tailwindcss'
import typography from '@tailwindcss/typography'
import daisyui from 'daisyui'
import { commonUtilities } from './config/tailwindcss'

export default <Config>{
  content: [
  ],
  plugins: [
    daisyui,
    typography(),
    commonUtilities,
  ],
  daisyui: {
    logs: false,
    themes: false,
  },
}

注意还需要配置 nuxt.config.ts 文件,这样 Nuxt 就会进行自动配置:

ts
export default defineNuxtConfig({
  modules: [
    '@nuxtjs/tailwindcss',
  ],
})

此时,项目已经配置好了 Tailwind CSS。

2.3 安装 ESLint

ESLint 是一个 JavaScript 代码检查工具,可以帮助我们规范代码风格。

使用 ESLint 并禁用 Prettier

本项目使用 ESLint 来检查代码风格,并同时使用 ESLint 来格式化代码,禁用 Prettier。可参阅 为什么我不使用 Prettier 以及使用 @stylistic/eslint-plugin 来进行风格化。

安装 @antfu 的 ESLint 配置:

bash
pnpm add -D eslint @antfu/eslint-config eslint-plugin-format eslint-plugin-tailwindcss

为了实现格式化,我们需要安装 eslint-plugin-format 插件。为了支持 Tailwind CSS 的样式检查,我们需要安装 eslint-plugin-tailwindcss 插件,这可以帮助我们检查是否有拼写错误或者未使用的样式。

配置 eslint.config.mjs 文件:

js
import antfu from '@antfu/eslint-config'
import tailwind from 'eslint-plugin-tailwindcss'

export default antfu(
  {
    formatters: true,
    markdown: false,
    typescript: {},
    vue: true,
    ignores: [
      'src-tauri/**',
    ],
    stylistic: {
      indent: 2,
      quotes: 'single',
    },
  },
  ...tailwind.configs['flat/recommended'],
)

配置 src-tauri/** 是为了添加 Tauri 项目,Rust 项目暂时不使用 ESLint 来格式化。

添加命令到 package.json 文件:

json
{
  "scripts": {
    "lint": "eslint .",
    "lint:fix": "eslint . --fix"
  }
}

至此 ESLint 配置完成,可以使用 pnpm lint 来检查代码风格。

2.4 配置 Git 钩子

Git 钩子是在 Git 执行特定操作时触发的脚本,可以用来检查代码风格、运行测试等。本项目使用 Simple Git Hooks 来管理 Git 钩子,并在提交时检查代码样式和提交信息是否符合规范。

安装 Git 钩子相关依赖:

bash
pnpm add -D simple-git-hooks lint-staged

更新 package.json 文件:

json
{
  "scripts": {
    "prepare": "simple-git-hooks"
  },
  "simple-git-hooks": {
    "pre-commit": "pnpm lint-staged"
  },
  "lint-staged": {
    "*": "pnpm lint"
  }
}

下面配置 commitlint,用于检查 Git 提交信息是否符合规范:

bash
pnpm add -D @commitlint/cli @commitlint/config-conventional @commitlint/types

编写配置文件 commitlint.config.ts

ts
import type { UserConfig } from '@commitlint/types'
import { RuleConfigSeverity } from '@commitlint/types'

export default <UserConfig>{
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [
      RuleConfigSeverity.Error,
      'always',
      [
        'build',
        'feat',
        'fix',
        'docs',
        'style',
        'refactor',
        'perf',
        'test',
        'revert',
        'ci',
        'config',
        'chore',
      ],
    ],
  },
}

这是最常见的提交类型,可以根据实际情况修改。

更新 package.json 文件:

json
{
  "scripts": {
    "commitlint": "commitlint -e -V"
  },
  "simple-git-hooks": {
    "commit-msg": "pnpm commitlint"
  }
}

这样就配置好了 Git 钩子和提交信息检查,要想立即应用需要重新初始化项目:

bash
pnpm i

2.5 配置 VS Code

VS Code 配置

本节配置直接复制即可使用,无需深入研究。

下面配置 VS Code 自动格式化,首先配置 .vscode/settings.json 文件:

json
{
  "workbench.iconTheme": "material-icon-theme",
  "css.customData": [
    ".vscode/tailwind.json"
  ],
  // Disable the default formatter, use eslint instead
  "prettier.enable": false,
  "editor.formatOnSave": false,
  // Auto fix
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit",
    "source.organizeImports": "never"
  },
  // Silent the stylistic rules in you IDE, but still auto fix them
  "eslint.rules.customizations": [
    {
      "rule": "style/*",
      "severity": "off",
      "fixable": true
    },
    {
      "rule": "format/*",
      "severity": "off",
      "fixable": true
    },
    {
      "rule": "*-indent",
      "severity": "off",
      "fixable": true
    },
    {
      "rule": "*-spacing",
      "severity": "off",
      "fixable": true
    },
    {
      "rule": "*-spaces",
      "severity": "off",
      "fixable": true
    },
    {
      "rule": "*-order",
      "severity": "off",
      "fixable": true
    },
    {
      "rule": "*-dangle",
      "severity": "off",
      "fixable": true
    },
    {
      "rule": "*-newline",
      "severity": "off",
      "fixable": true
    },
    {
      "rule": "*quotes",
      "severity": "off",
      "fixable": true
    },
    {
      "rule": "*semi",
      "severity": "off",
      "fixable": true
    }
  ],
  // Enable eslint for all supported languages
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact",
    "vue",
    "html",
    "markdown",
    "json",
    "jsonc",
    "yaml",
    "toml",
    "xml",
    "gql",
    "graphql",
    "astro",
    "svelte",
    "css",
    "less",
    "scss",
    "pcss",
    "postcss"
  ],
  "files.eol": "\n"
}

这样,保存时即可自动格式化并保存文件。

为了支持 Tailwind CSS 指令的提示,需要添加 .vscode/tailwind.json

json
{
  "version": 1.1,
  "atDirectives": [
    {
      "name": "@tailwind",
      "description": "Use the `@tailwind` directive to insert Tailwind's `base`, `components`, `utilities` and `screens` styles into your CSS.",
      "references": [
        {
          "name": "Tailwind Documentation",
          "url": "https://tailwindcss.com/docs/functions-and-directives#tailwind"
        }
      ]
    },
    {
      "name": "@apply",
      "description": "Use the `@apply` directive to inline any existing utility classes into your own custom CSS. This is useful when you find a common utility pattern in your HTML that you’d like to extract to a new component.",
      "references": [
        {
          "name": "Tailwind Documentation",
          "url": "https://tailwindcss.com/docs/functions-and-directives#apply"
        }
      ]
    },
    {
      "name": "@responsive",
      "description": "You can generate responsive variants of your own classes by wrapping their definitions in the `@responsive` directive:\n```css\n@responsive {\n  .alert {\n    background-color: #E53E3E;\n  }\n}\n```\n",
      "references": [
        {
          "name": "Tailwind Documentation",
          "url": "https://tailwindcss.com/docs/functions-and-directives#responsive"
        }
      ]
    },
    {
      "name": "@screen",
      "description": "The `@screen` directive allows you to create media queries that reference your breakpoints by **name** instead of duplicating their values in your own CSS:\n```css\n@screen sm {\n  /* ... */\n}\n```\n…gets transformed into this:\n```css\n@media (min-width: 640px) {\n  /* ... */\n}\n```\n",
      "references": [
        {
          "name": "Tailwind Documentation",
          "url": "https://tailwindcss.com/docs/functions-and-directives#screen"
        }
      ]
    },
    {
      "name": "@variants",
      "description": "Generate `hover`, `focus`, `active` and other **variants** of your own utilities by wrapping their definitions in the `@variants` directive:\n```css\n@variants hover, focus {\n   .btn-brand {\n    background-color: #3182CE;\n  }\n}\n```\n",
      "references": [
        {
          "name": "Tailwind Documentation",
          "url": "https://tailwindcss.com/docs/functions-and-directives#variants"
        }
      ]
    }
  ]
}

新建 .vscode/extensions.json,配置了本项目的推荐插件:

json
{
  "recommendations": [
    "PKief.material-icon-theme",
    "dbaeumer.vscode-eslint",
    "antfu.iconify",
    "antfu.goto-alias",
    "bradlc.vscode-tailwindcss",
    "Vue.volar",
    "naumovs.color-highlight",
    "rust-lang.rust-analyzer",
    "dustypomerleau.rust-syntax",
    "tamasfe.even-better-toml",
    "fill-labs.dependi",
    "Prisma.prisma",
    "nuxtr.nuxtr-vscode"
  ]
}

这样,打开此项目,点击确认即可自动安装推荐插件。

2.6 Nuxt 项目常见配置

为了支持 Sass,一种非常流行的样式表预处理语言,我们添加 sass 依赖:

bash
pnpm add -D sass

配置 Vite 使得 Vite 兼容最新的样式表预处理技术,在 nuxt.config.ts 文件中添加如下配置:

ts
export default defineNuxtConfig({
  vite: {
    css: {
      preprocessorOptions: {
        scss: { api: 'modern-compiler' },
      },
    },
  },
})

支持 Nuxt 最新特性:

ts
export default defineNuxtConfig({
  future: {
    compatibilityVersion: 4,
  },

  compatibilityDate: '2024-11-01',

  devtools: {
    enabled: true,
  },
}

最新配置建议将 app.vue 等客户端文件放在 app/ 目录下,这样可以更好的组织项目。因此需要将 app.vue 移动到 app/app.vue

添加环境变量的类型支持 types/env.d.ts

ts
/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly MODE: string
  readonly BASE_URL: string
  readonly PROD: boolean
  readonly DEV: boolean
  readonly SSR: boolean
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}

这样,在编写项目时环境变量拥有类型提示。