vite 原理源码 - 启动开发服务器

vite 5.0.12

当在命令行输入 vite,就可以在当前目录下启动 Vite 开发服务器。 在vite的 package.json 文件中,有

json 复制代码
  "bin": {
    "vite": "bin/vite.js"
  }

vite 命令对应的可执行文件为 bin 子目录下的 vite.js。Npm会寻找这个文件,在node_modules/.bin/目录下建立符号链接。在上面的例子中,vite.js会建立符号链接node_modules/.bin/vite。由于node_modules/.bin/目录会在运行时加入系统的PATH变量,因此在运行npm时,就可以不带路径,直接通过命令来调用脚本。这个被调用的脚本就是 vite/bin/vite.js

通过 vite --debug命令,开启调试,进入vite/bin/vite.js,会走到start函数

js 复制代码
// vite/bin/vite.js

function start() {
  return import('../dist/node/cli.js')
}

进入 cli.js这个文件

js 复制代码
// /vite/dist/node/cli.js

class CAC extends EventEmitter {
     parse(){
        this.runMatchedCommand();
     }
     runMatchedCommand() {
       return command.commandAction.apply(this, actionArgs);
     }
}

const cac = (name = "") => new CAC(name);
const cli = cac('vite');

// 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`, { type: [convertHost] })
    .option('--port <port>', `[number] specify port`)
    .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, options) => {
      // 回调
      // 调用command.commandAction触发此回调
      const { createServer } = await import('./chunks/dep-9A4-l-43.js').then(function (n) { return n.A; });  
      try {
        const server = await createServer({
            root,
            base: options.base,
            mode: options.mode,
            configFile: options.config,
            logLevel: options.logLevel,
            clearScreen: options.clearScreen,
            optimizeDeps: { force: options.force },
            server: cleanOptions(options),
        });        
       }
       // 启动服务器
       await server.listen();
    // ...   
    } 
 //... 
 cli.parse();

在命令行执行 vite,会执行cli.parse(),在parse()里面执行this.runMatchedCommand()

js 复制代码
  runMatchedCommand() {
    return command.commandAction.apply(this, actionArgs);
  }

command.commandAction就是传入action的回调,在回调里面创建server,启动监听

createServer

js 复制代码
// /vite/dist/node/chunks/dep-9A4-l-43.js

function createServer(inlineConfig = {}) {
    return _createServer(inlineConfig, { ws: true });
}
async function _createServer(inlineConfig = {}, options) {
    const middlewares = connect$1(); 
    const httpServer = await resolveHttpServer(serverConfig, middlewares, httpsOptions);
    let server = {
        httpServer,
        // 监听启动
        async listen(port, isRestart) {
           // 调用 startServer,监听启动
            await startServer(server, port);
            return server;
        },
    }
    return server
}

async function resolveHttpServer({ proxy }, app, httpsOptions) {
    if (!httpsOptions) {
        const { createServer } = await import('node:http');
        return createServer(app);
    }
}

async function startServer(server, inlinePort) {
    const httpServer = server.httpServer;
    // 调用 httpServerStart
    const serverPort = await httpServerStart(httpServer, {
        port,
        strictPort: options.strictPort,
        host: hostname.host,
        logger: server.config.logger,
    });  
}

async function httpServerStart(httpServer, serverOptions) {
    let { port, strictPort, host, logger } = serverOptions;
    return new Promise((resolve, reject) => {
        // node:http 创建的httpServer启动listen
        httpServer.listen(port, host, () => {
            httpServer.removeListener('error', onError);
            resolve(port);
        });
    });
}

参考

vite官网

github.com/vitejs/vite

相关推荐
咸虾米2 分钟前
在uniCloud云对象中定义dbJQL的便捷方法
前端·javascript
梨子同志3 分钟前
JavaScript Proxy 和 Reflect
前端·javascript
汤圆炒橘子7 分钟前
状态策略模式的优势分析
前端
90后的晨仔23 分钟前
解析鸿蒙 ArkTS 中的 Union 类型与 TypeAliases类型
前端·harmonyos
IT_陈寒40 分钟前
Element Plus 2.10.0 重磅发布!新增Splitter组件
前端·人工智能·后端
挑战者66688840 分钟前
vue入门环境搭建及demo运行
前端·javascript·vue.js
贩卖纯净水.41 分钟前
Webpack的基本使用 - babel
前端·webpack·node.js
用户882093216671 小时前
Vue组件通信全攻略:从父子传参到全局状态管理,一篇搞定!
前端
Canmick1 小时前
JavaScript 异步函数健身操
前端·javascript
一曝十寒1 小时前
那些常见的 HTTP 状态码
前端·http