Skip to content

Vite工程项目结构说明

这部分主要讲述vite源码工程文件结构,以及各个文件所放的内容以及作用。

vite文件结构

md
vite/
├── .github/   # github相关文件 部署执行配置文件
├── .stackblitz/ # stackblitz相关文件
├── docs/ # vite文档相关文件 vite官网的页面就是用这里面的.md生成展示的
├── packages/ # vite源码核心文件
├── patches/    #
├── playground/ # 测试相关文件 里面包含测试用例的场景
├── scripts/ # 一些脚本文件 执行工程运行打包等命令
├── .editorconfig #
├── .git-blame-ignore-revs
├── .gitignore
├── .npmrc
├── .prettierignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── eslint.config.js
├── netlify.toml
├── package.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── vitest.config.e2e.ts
└── vitest.config.ts # 项目vite配置文件

vite核心文件

packages里面有三个文件夹,分别是create-vite、plugin-legacy、vite。 create-vite是创建项目时的模板,plugin-legacy是兼容IE的插件,vite是核心源码。

md
vite/
├── packages/
    ├── create-vite/ # 创建项目时的模板
    ├── plugin-legacy/ # 兼容IE的插件
    └── vite/ # 核心源码

package.json

项目根目录package.json文件命令介绍:

json

  {
  "name": "@vitejs/vite-monorepo",
  "private": true,
  "type": "module",
  "engines": {
    "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
  },
  "homepage": "https://vite.dev/",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/vitejs/vite.git"
  },
  "keywords": [
    "frontend",
    "hmr",
    "dev-server",
    "build-tool",
    "vite"
  ],
  "scripts": {
    // preinstall是npm安装钩子函数 这里限制只能用pnpm
    "preinstall": "npx only-allow pnpm", 
    //初始化simple-git-hooks
    "postinstall": "simple-git-hooks",
    // 执行 prettier代码格式化 --write直接修改文件 --cache 缓存 .表示所有文件
    "format": "prettier --write --cache .",
    // 执行lint代码检查
    "lint": "eslint --cache .",
    // 执行ts类型检查 --noEmit不需要生成文件 
    // 并行执行子包typecheck命令 vite包和cretate-vite包都有typecheck命令
    "typecheck": "tsc -p scripts --noEmit && pnpm -r --parallel run typecheck",
    // 执行测试
    "test": "pnpm test-unit && pnpm test-serve && pnpm test-build",
    "test-serve": "vitest run -c vitest.config.e2e.ts",
    // 跟test-serve类似,VITE_TEST_BUILD=1有区别,这个参数是区分跑不同的测试用例,
    //用例里面有判断isServe
    "test-build": "VITE_TEST_BUILD=1 vitest run -c vitest.config.e2e.ts",
    // 会跑测试用例 不包含playground里面的用例
    "test-unit": "vitest run",
    "test-docs": "pnpm run docs-build",
    //这个命令同上面test命令,参数不同
    "debug-serve": "VITE_DEBUG_SERVE=1 vitest run -c vitest.config.e2e.ts",
    //这个命令同上面test命令,参数不同
    "debug-build": "VITE_TEST_BUILD=1 VITE_PRESERVE_BUILD_ARTIFACTS=1 vitest run -c vitest.config.e2e.ts",
    // 启动文档服务
    "docs": "pnpm --filter=docs run docs",
    // 打包文档
    "docs-build": "pnpm --filter=docs run docs-build",
    // 打包文档后本地预览
    "docs-serve": "pnpm --filter=docs run docs-serve",
    // 打包packages里面的子项目
    "build": "pnpm -r --filter='./packages/*' run build",
    //启动packages里面的子项目
    "dev": "pnpm -r --parallel --filter='./packages/*' run dev", 
    //发布
    "release": "tsx scripts/release.ts",
    "ci-publish": "tsx scripts/publishCI.ts",
    //打包工程和文档
    "ci-docs": "pnpm build && pnpm docs-build"
  },
  "devDependencies": {
    "@eslint/js": "^9.16.0",
    "@type-challenges/utils": "^0.1.1",
    "@types/babel__core": "^7.20.5",
    "@types/babel__preset-env": "^7.9.7",
    "@types/convert-source-map": "^2.0.3",
    "@types/cross-spawn": "^6.0.6",
    "@types/debug": "^4.1.12",
    "@types/estree": "^1.0.6",
    "@types/etag": "^1.8.3",
    "@types/less": "^3.0.7",
    "@types/node": "^22.10.1",
    "@types/picomatch": "^3.0.1",
    "@types/stylus": "^0.48.43",
    "@types/ws": "^8.5.13",
    "@vitejs/release-scripts": "^1.3.2",
    "conventional-changelog-cli": "^5.0.0",
    "eslint": "^9.16.0",
    "eslint-plugin-import-x": "^4.5.0",
    "eslint-plugin-n": "^17.14.0",
    "eslint-plugin-regexp": "^2.7.0",
    "execa": "^9.5.2",
    "globals": "^15.13.0",
    "gsap": "^3.12.5",
    "lint-staged": "^15.2.10",
    "picocolors": "^1.1.1",
    "playwright-chromium": "^1.49.0",
    "premove": "^4.0.0",
    "prettier": "3.4.2",
    "rollup": "^4.23.0",
    "rollup-plugin-esbuild": "^6.1.1",
    "simple-git-hooks": "^2.11.1",
    "tslib": "^2.8.1",
    "tsx": "^4.19.2",
    "typescript": "~5.6.2",
    "typescript-eslint": "^8.17.0",
    "vite": "workspace:*",
    "vitest": "^2.1.8"
  },
  //配置git提交时的钩子函数
  "simple-git-hooks": {
    // git提交前执行  执行本地文件代码格式校验
    "pre-commit": "pnpm exec lint-staged --concurrent false"
  },
  // lint-staged命令配置
  "lint-staged": {
    "*": [
      "prettier --write --cache --ignore-unknown"
    ],
    "packages/*/{src,types}/**/*.ts": [
      "eslint --cache --fix"
    ],
    "packages/**/*.d.ts": [
      "eslint --cache --fix"
    ],
    "playground/**/__tests__/**/*.ts": [
      "eslint --cache --fix"
    ]
  },
  "packageManager": "pnpm@9.15.0",
  "pnpm": {
    "overrides": {
      "vite": "workspace:*"
    },
    "patchedDependencies": {
      "http-proxy@1.18.1": "patches/http-proxy@1.18.1.patch",
      "sirv@3.0.0": "patches/sirv@3.0.0.patch",
      "chokidar@3.6.0": "patches/chokidar@3.6.0.patch"
    },
    "peerDependencyRules": {
      "allowedVersions": {
        "vite": "*"
      },
      "ignoreMissing": [
        "@algolia/client-search",
        "postcss",
        "search-insights"
      ]
    },
    "packageExtensions": {
      "sass-embedded": {
        "peerDependencies": {
          "source-map-js": "*"
        },
        "peerDependenciesMeta": {
          "source-map-js": {
            "optional": true
          }
        }
      }
    }
  },
  "stackblitz": {
    "startCommand": "pnpm --filter='./packages/vite' run dev"
  }
}

release命令

执行tsx scripts/release.ts发布代码过程,logRecentCommits打印提交记录,generateChangelog 生成更新日志changelog,extendCommitHash短hash替换成git rev-parse ${shortHash}生成的长hash

scripts/release.ts
js
release({
  repo: 'vite',
  packages: ['vite', 'create-vite', 'plugin-legacy'],
  toTag: (pkg, version) =>
    pkg === 'vite' ? `v${version}` : `${pkg}@${version}`,
    // 执行 git rev-list -n 1 v${version} 获取最近一次版本的提交记录并取到其hash值
    // 执行 git --no-pager log hash..HEAD --oneline -- packages/vite // 打印v${version}
    // 到最新的提交记录之间的记录
  logChangelog: (pkg) => logRecentCommits(pkg),
  generateChangelog: async (pkgName) => {
    if (pkgName === 'create-vite') await updateTemplateVersions()
    console.log(colors.cyan('\nGenerating changelog...'))
    const changelogArgs = [
      'conventional-changelog',
      '-p',
      'angular',
      '-i',
      'CHANGELOG.md',
      '-s',
      '--commit-path',
      '.',
    ]
    if (pkgName !== 'vite') changelogArgs.push('--lerna-package', pkgName)
    // 执行 npx conventional-changelog -p angular -i CHANGELOG.md -s --commit-path .
    // 生成更新日志
    await run('npx', changelogArgs, { cwd: `packages/${pkgName}` })
    // 把conventional-changelog生成的数字短hash替换成git rev-parse ${shortHash}生成的长hash
    extendCommitHash(`packages/${pkgName}/CHANGELOG.md`)
  },
})

release函数里面执行logChangelog和 generateChangelog回调函数后,执行了git相关操作 git add / git commit / git tag / git push等。同时更新了package.json的版本号。这样就完成了发布。release可以简单理解为git操作的封装。

publish命令

发布执行tsx scripts/publishCI.ts命令

scripts/publishCI.ts
js
const tag = process.argv.slice(2)[0] ?? ''
const provenance = !tag.includes('@')

publish({ defaultPackage: 'vite', provenance, packageManager: 'pnpm' })

publish里面执行 pnpm publish --access public --tag ${tag} --provenance --no-git-checks发布npm包。--access public 包访问级别为public,npm所有用户可用。--no-git-checks跳过git检查。

MIT Licensed | thanks vue team