vite--server对应源码

Published: · LastMod: June 11, 2022 · 659 words

vite server 🔗

3.0.0

源码位置 🔗

packages/vite/src/node/server/index.ts

createServer 🔗

步骤

  1. 解析配置文件

    1
    
    const config = await resolveConfig(inlineConfig, 'serve', 'development')
    
  2. 创建中间件的容器,使用的第三方库connect, 默认可以兼容expresskoa等第三方node服务库, 后续会把相应的中间件加入到实例中

    1
    
      const middlewares = connect() as Connect.Server
    
  3. 创建httpServer实例,使用的是node原生http

    1
    2
    3
    
     const httpServer = middlewareMode
        ? null
        : await resolveHttpServer(serverConfig, middlewares, httpsOptions)
    
  4. 创建出一个websocket实例,使用第三方库ws

    1
    
      const ws = createWebSocketServer(httpServer, config, httpsOptions)
    
  5. 创建出一个文件夹监听实例,使用第三方库chokidar, 监听目标目录下文件的变动, 也就是对应的热更新操作

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
      const watcher = chokidar.watch(path.resolve(root), {
        ignored: [
          '**/node_modules/**',
          '**/.git/**',
          ...(Array.isArray(ignored) ? ignored : [ignored])
        ],
        ignoreInitial: true,
        ignorePermissionErrors: true,
        disableGlobbing: true,
        ...watchOptions
      }) as FSWatcher
    
  6. 创建模块依赖moduleGraph,记录文件模块依赖

    构建插件容器

    1
    2
    3
    4
    
    const moduleGraph: ModuleGraph = new ModuleGraph((url, ssr) =>
    	container.resolveId(url, undefined, { ssr })
    )
    const container = await createPluginContainer(config, moduleGraph, watcher)
    
  7. 构建一个server对象,包括当前上下文的参数等等

    交给后续上下文使用

    1
    2
    3
    
     const server: ViteDevServer = {
     	// ....
     }
    
  8. 监听文件的变化、新增、删除等操作, 会进行相应的热更新操作

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    watcher.on('change', async (file) => {
        file = normalizePath(file)
        if (file.endsWith('/package.json')) {
          return invalidatePackageData(packageCache, file)
        }
        // invalidate module graph cache on file change
        // 模块依赖更新
        moduleGraph.onFileChange(file)
        if (serverConfig.hmr !== false) {
          try {
            // 热更新操作
            await handleHMRUpdate(file, server)
          } catch (err) {
            ws.send({
              type: 'error',
              err: prepareError(err)
            })
          }
        }
      })
    
      watcher.on('add', (file) => {
        handleFileAddUnlink(normalizePath(file), server)
      })
      watcher.on('unlink', (file) => {
        handleFileAddUnlink(normalizePath(file), server)
      })
    
  9. 遍历所有的插件,同步拿到配置服务的结果

    1
    2
    3
    4
    5
    6
    
      const postHooks: ((() => void) | void)[] = []
      for (const plugin of config.plugins) {
        if (plugin.configureServer) {
          postHooks.push(await plugin.configureServer(server))
        }
      }
    
  10. 在服务中间件中添加一些列的中间件,包括请求时间、跨域处理、proxy代理、根目录读取html、静态资源服务、错误处理等

  11. 启动服务

  12. 返回server给外部使用