• 一级标题
  • 二级标题
  • 三级标题
  • 四级标题
  • 五级标题
  • 六级标题
  • 添加链接
  • 上传图片
  • 裁剪上传
  • 流程图
  • 时序图
  • 甘特图
  • 类图
  • 状态图
  • 饼图
  • 关系图
  • 旅程图
  • 行内公式
  • 块级公式
添加链接

Vite 源码了解

本次源码学习基于 vite 2.9.6 版本

clone 项目

https://github.com/vitejs/vite/blob/main/CONTRIBUTING.md
The Vite repo is a monorepo using pnpm workspaces. The package manager used to install and link dependencies must be pnpm.

vite 源码 clone 到本地后,需要使用 pnpm 安装依赖

To develop and test the core vite package:

  • Run pnpm i in Vite's root folder

  • Run pnpm run build in Vite's root folder.

  • If you are developing Vite itself, you can go to packages/vite and run pnpm run dev to automatically rebuild Vite whenever you change its code.

启动 playground

pnpm i
pnpm run build
# 选择一个测试项目
cd packages\playground\vue
pnpm vue

包目录结构

在 vite 源码的 packages 目录下主要有以下目录:

├── create-vite -- 用于创建新的 Vite 项目
├── playground -- demo及测试用例
├── plugin-legacy  --  官方插件,提供兼容支持
├── plugin-react  -- 官方插件,支持React
├── plugin-vue    -- 官方插件,支持Vue
├── plugin-vue-jsx  -- 官方插件,支持Vue3 JSX
└── vite  -- Vite核心包

Command Line Interface

{
  "scripts": {
    "dev": "vite", // start dev server, aliases: `vite dev`, `vite serve`
    "build": "vite build", // build for production
    "preview": "vite preview" // locally preview production build
  }
}

vite dev

在playground中运行 npm run dev 命令,即运行 vite dev 命令
实际执行的脚本是:

packages\vite\src\node\cli.ts

源码

// dev
cli
  .command('[root]', 'start dev server') // default command
  .alias('serve') // the command is called 'serve' in Vite's API
  .alias('dev') // alias to align with the script name
  .option('--host [host]', `[string] specify hostname`)
  .option('--port <port>', `[number] specify port`)
  .option('--https', `[boolean] use TLS + HTTP/2`)
  .option('--open [path]', `[boolean | string] open browser on startup`)
  .option('--cors', `[boolean] enable CORS`)
  .option('--strictPort', `[boolean] exit if specified port is already in use`)
  .option(
    '--force',
    `[boolean] force the optimizer to ignore the cache and re-bundle`
  )
  .action(async (root: string, options: ServerOptions & GlobalCLIOptions) => {
    // output structure is preserved even after bundling so require()
    // is ok here
    const { createServer } = await import('./server')
    try {
      const server = await createServer({
        root,
        base: options.base,
        mode: options.mode,
        configFile: options.config,
        logLevel: options.logLevel,
        clearScreen: options.clearScreen,
        server: cleanOptions(options)
      })

      if (!server.httpServer) {
        throw new Error('HTTP server not available')
      }

      await server.listen()

      const info = server.config.logger.info

      info(
        colors.cyan(`\n  vite v${require('vite/package.json').version}`) +
          colors.green(` dev server running at:\n`),
        {
          clear: !server.config.logger.hasWarned
        }
      )

      server.printUrls()

      // @ts-ignore
      if (global.__vite_start_time) {
        // @ts-ignore
        const startupDuration = performance.now() - global.__vite_start_time
        info(
          `\n  ${colors.cyan(`ready in ${Math.ceil(startupDuration)}ms.`)}\n`
        )
      }
    } catch (e) {
      createLogger(options.logLevel).error(
        colors.red(`error when starting dev server:\n${e.stack}`),
        { error: e }
      )
      process.exit(1)
    }
  })

当执行vite dev 不带任何参数时,
root 为 undefined, options为 { '--': [] }, 即:

 const server = await createServer({
  root: undefined,
  base: undefined,
  mode: undefined,
  configFile: undefined,
  logLevel: undefined,
  clearScreen: undefined,
  server: undefined,
});
await server.listen();
<h1 data-line="0" id="Vite 源码了解">Vite 源码了解</h1> <p data-line="2"><strong>本次源码学习基于 vite 2.9.6 版本</strong></p> <h2 data-line="4" id="clone 项目">clone 项目</h2> <blockquote data-line="6"> <p>https://github.com/vitejs/vite/blob/main/CONTRIBUTING.md<br> The Vite repo is a monorepo using pnpm workspaces. The package manager used to install and link dependencies must be pnpm.</p> </blockquote> <p data-line="9">vite 源码 clone 到本地后,需要使用 pnpm 安装依赖</p> <p data-line="11">To develop and test the core vite package:</p> <ul data-line="13"> <li> <p>Run <code>pnpm i</code> in Vite's root folder</p> </li> <li> <p>Run pnpm <code>run build</code> in Vite's root folder.</p> </li> <li> <p>If you are developing Vite itself, you can go to packages/vite and run <code>pnpm run dev</code> to automatically rebuild Vite whenever you change its code.</p> </li> </ul> <h2 data-line="19" id="启动 playground">启动 playground</h2> <pre data-line="21"><code class="language-shell" language=shell><span class="code-block">pnpm i pnpm run build # 选择一个测试项目 cd packages\playground\vue pnpm vue</span></code></pre> <h2 data-line="29" id="包目录结构">包目录结构</h2> <p data-line="31"><strong>在 vite 源码的 packages 目录下主要有以下目录:</strong></p> <pre data-line="33"><code class="language-shell" language=shell><span class="code-block">├── create-vite -- 用于创建新的 Vite 项目 ├── playground -- demo及测试用例 ├── plugin-legacy -- 官方插件,提供兼容支持 ├── plugin-react -- 官方插件,支持React ├── plugin-vue -- 官方插件,支持Vue ├── plugin-vue-jsx -- 官方插件,支持Vue3 JSX └── vite -- Vite核心包</span></code></pre> <h2 data-line="43" id="Command Line Interface">Command Line Interface</h2> <pre data-line="45"><code class="language-javascript" language=javascript><span class="code-block">{ &quot;scripts&quot;: { &quot;dev&quot;: &quot;vite&quot;, // start dev server, aliases: `vite dev`, `vite serve` &quot;build&quot;: &quot;vite build&quot;, // build for production &quot;preview&quot;: &quot;vite preview&quot; // locally preview production build } }</span></code></pre> <h2 data-line="55" id="vite dev">vite dev</h2> <p data-line="56">在playground中运行 <code>npm run dev</code> 命令,即运行 <code>vite dev</code> 命令<br> 实际执行的脚本是:</p> <pre data-line="58"><code class="language-shell" language=shell><span class="code-block">packages\vite\src\node\cli.ts</span></code></pre> <p data-line="61">源码</p> <pre data-line="62"><code class="language-typescript" language=typescript><span class="code-block">// dev cli .command('[root]', 'start dev server') // default command .alias('serve') // the command is called 'serve' in Vite's API .alias('dev') // alias to align with the script name .option('--host [host]', `[string] specify hostname`) .option('--port &lt;port&gt;', `[number] specify port`) .option('--https', `[boolean] use TLS + HTTP/2`) .option('--open [path]', `[boolean | string] open browser on startup`) .option('--cors', `[boolean] enable CORS`) .option('--strictPort', `[boolean] exit if specified port is already in use`) .option( '--force', `[boolean] force the optimizer to ignore the cache and re-bundle` ) .action(async (root: string, options: ServerOptions &amp; GlobalCLIOptions) =&gt; { // output structure is preserved even after bundling so require() // is ok here const { createServer } = await import('./server') try { const server = await createServer({ root, base: options.base, mode: options.mode, configFile: options.config, logLevel: options.logLevel, clearScreen: options.clearScreen, server: cleanOptions(options) }) if (!server.httpServer) { throw new Error('HTTP server not available') } await server.listen() const info = server.config.logger.info info( colors.cyan(`\n vite v${require('vite/package.json').version}`) + colors.green(` dev server running at:\n`), { clear: !server.config.logger.hasWarned } ) server.printUrls() // @ts-ignore if (global.__vite_start_time) { // @ts-ignore const startupDuration = performance.now() - global.__vite_start_time info( `\n ${colors.cyan(`ready in ${Math.ceil(startupDuration)}ms.`)}\n` ) } } catch (e) { createLogger(options.logLevel).error( colors.red(`error when starting dev server:\n${e.stack}`), { error: e } ) process.exit(1) } })</span></code></pre> <p data-line="128">当执行<code>vite dev</code> 不带任何参数时,<br> root 为 undefined, options为 { '--': [] }, 即:</p> <pre data-line="130"><code class="language-typescript" language=typescript><span class="code-block"> const server = await createServer({ root: undefined, base: undefined, mode: undefined, configFile: undefined, logLevel: undefined, clearScreen: undefined, server: undefined, }); await server.listen();</span></code></pre>