2. 开发环境搭建:Vite + Vue/React 项目初始化、安装 M3 库、配置主题 Provider

2.1 原理:为什么选择 Vite 与 M3 库的架构依赖

Material Design 3 组件库(M3)依赖现代 JavaScript 构建工具提供三项核心能力:ESM 树摇(Tree‑shaking)、HMR 热更新以及CSS‑in‑JS 运行时编译。Vite 基于原生 ESM 开发服务器,冷启动和热更新速度远超 Webpack;生产构建通过 Rollup 自动摇掉未使用的组件和样式,直接降低打包体积。

M3 库在运行时的架构分为三层:

  • 设计令牌层(Design Tokens)——颜色、字体、圆角、间距等原子变量,由 createTheme 或 createVuetify 定义。
  • 主题注入层(ThemeProvider)——通过 React Context 或 Vue Plugin 将令牌传递给组件树。
  • 组件消费层——每个组件从上下文读取令牌并映射到 CSS 变量或 Emotion 样式。

因此,正确搭建环境的核心就是打通这三层:Vite 项目 → 安装 M3 库 → 创建主题对象 → Provider 包裹应用 → 验证令牌是否生效。

关键原则:Provider 必须位于组件树的根节点或目标子树上方;任何未包裹 Provider 的组件都会回退到库的默认主题,导致自定义令牌不生效。

2.2 实现流程

2.2.1 使用 Vite 创建项目

执行以下命令创建带 TypeScript 模板的项目(React 与 Vue 二选一):

# React + TypeScript
npm create vite@latest m3-app -- --template react-ts

# Vue + TypeScript
npm create vite@latest m3-app -- --template vue-ts

cd m3-app
npm install
建议:课程后续章节使用 React + TypeScript 作为演示栈,Vue 学员可参照对比表格中的等效 API。

2.2.2 安装 M3 组件库

根据框架选择对应的 M3 库:

框架 M3 库名 核心依赖 安装命令
React @mui/material v5/v6 @emotion/react 、@emotion/styled npm install @mui/material @emotion/react @emotion/styled @mui/icons-material
Vue 3 vuetify v3 sass(可选,用于样式覆盖) npm install vuetify@latest

安装完成后,在 package.json 中确认版本号:

{
  "dependencies": {
    "@mui/material": "^6.1.0",
    "@emotion/react": "^11.13.0",
    "@emotion/styled": "^11.13.0",
    "react": "^18.3.0",
    "react-dom": "^18.3.0"
  }
}

2.2.3 配置主题 Provider

React + MUI 配置

在 src/main.tsx 或 src/App.tsx 中创建主题并包裹应用:

import React from 'react';
import ReactDOM from 'react-dom/client';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import App from './App';

const theme = createTheme({
  palette: {
    primary: { main: '#6750A4' },   // M3 推荐紫
    secondary: { main: '#625B71' },
    tertiary: { main: '#7D5260' },
  },
  typography: {
    fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
  },
  shape: {
    borderRadius: 12,                // M3 圆角风格
  },
});

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <App />
    </ThemeProvider>
  </React.StrictMode>
);

Vue + Vuetify 3 配置

在 src/main.ts 中注册 Vuetify 插件:

import { createApp } from 'vue';
import { createVuetify } from 'vuetify';
import * as components from 'vuetify/components';
import * as directives from 'vuetify/directives';
import App from './App.vue';

const vuetify = createVuetify({
  components,
  directives,
  theme: {
    defaultTheme: 'light',
    themes: {
      light: {
        colors: {
          primary: '#6750A4',
          secondary: '#625B71',
          tertiary: '#7D5260',
        },
      },
    },
  },
});

createApp(App).use(vuetify).mount('#app');
⚠ 常见陷阱:Vuetify 3 的 components 和 directives 需要显式导入,否则组件不会注册。MUI 的 CssBaseline 必须放在 ThemeProvider 内部,确保全局样式继承主题令牌。

2.3 调试与验证

  1. 检查 Provider 是否包裹:在浏览器 React DevTools 中选中任意 M3 组件,查看其上下文是否包含 ThemeProvider 或 VuetifyPlugin。
  2. 验证令牌生效:在页面中渲染一个 <Button variant="contained">Test</Button>,其背景色应与 primary.main 一致(#6750A4)。
  3. 查看 CSS 变量(MUI v6 支持 CSS 变量模式):打开开发者工具 → Elements → Styles,搜索 --mui-palette-primary-main 确认值已注入。
  4. 终端日志:Vite 开发服务器启动后无报错,且浏览器控制台无“MUI: The `styles` argument provided is invalid”等错误。
快速验证命令:
npm run dev
# 终端输出类似:
# VITE v5.4.0  ready in 320ms
# ➜  Local:   http://localhost:5173/
打开浏览器,页面应正常渲染,无白屏或控制台报错。

2.4 常见错误与解决方案

错误现象 根因 解决方案
组件样式丢失,回退为默认蓝色 ThemeProvider 未包裹目标组件 将 <ThemeProvider> 提升到 App 或 main.tsx 根节点
Emotion 报错:@emotion/react 版本冲突 项目中存在多个 Emotion 实例 删除 node_modules 和 package-lock.json,执行 npm install 重新解析
Vite 构建时报 Unsupported URL Type MUI 的 ESM 导入路径与 Vite 解析冲突 在 vite.config.ts 中添加 resolve.alias 或升级 Vite ≥ 5.4
TypeScript 找不到 @mui/material 类型 未安装 @types/react 或 @mui/material 类型未导出 执行 npm install -D @types/react,确保 tsconfig.json 包含 "moduleResolution": "bundler"
Vuetify 组件渲染为纯 HTML 无样式 未导入 vuetify/styles 或 Sass 编译器缺失 在 main.ts 中添加 import 'vuetify/styles';安装 sass 依赖

2.5 性能与稳定性优化

  • 按需加载组件:MUI 和 Vuetify 都支持 ESM 树摇,只需 import { Button } from '@mui/material' 即可自动摇掉未引用组件。避免使用 import * as 全量导入。
  • 缓存主题对象:将 createTheme() 调用放在模块顶层或使用 useMemo,防止每次渲染重新创建对象导致子组件全部重渲染。
  • 使用 CssBaseline / reset.css:消除浏览器默认样式差异,减少样式覆盖带来的选择器优先级调试成本。
  • 生产构建优化:Vite 自动对 M3 库进行代码分割和压缩;可额外开启 rollupOptions.output.manualChunks 将 @mui/material 分离为独立 chunk,利用浏览器缓存。
生产环境配置示例(vite.config.ts):
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          mui: ['@mui/material', '@emotion/react', '@emotion/styled'],
        },
      },
    },
  },
});
分离后 mui chunk 约 80 KB(gzip),长期缓存,增量更新时用户只需下载业务代码。
M3 开发环境搭建流程 创建 Vite 项目 npm create vite 安装 M3 库 @mui/material 配置 Provider ThemeProvider 引入 M3 组件 TopAppBar 验证运行 npm run dev 💡 核心原则 ThemeProvider 必须包裹所有使用 M3 组件的子树,否则组件将使用默认主题

2.6 完整 checklist

  • ☐ Vite 项目已创建,npm run dev 可正常启动
  • ☐ M3 库已安装,package.json 中版本无误
  • ☐ ThemeProvider / VuetifyPlugin 已在入口文件注册
  • ☐ CssBaseline 或 vuetify/styles 已导入
  • ☐ 主题颜色与 M3 令牌一致(primary: #6750A4)
  • ☐ 浏览器控制台无红色报错
  • ☐ 生产构建可通过 npm run build 且分离 MUI chunk

完成以上步骤后,你的项目已具备 M3 组件库的开发能力。下一环节将使用已配置的 Provider 环境,正式实现 TopAppBar 组件及其交互行为。