import { createApp } from 'vue'是如何找到'vue'

238 阅读2分钟

今天开始学习vue3源码的时候,当我看到import { createApp } from 'vue'这个import导入createApp函数时,我试着找到createApp时怎么导入的、导入的文件在哪,于是有了接下来的步骤。

npm install vue

当你执行 npm install vue 命令时,npm 会连接到 npm 仓库,查找 Vue.js 的最新版本,并将其下载到你的项目目录中。默认情况下,Vue.js 会被安装在你项目的 node_modules 文件夹中,并且相关信息会被记录在 package.json 文件中。

//   node_module/vue/package.json
{
  "name": "vue",
  "version": "3.3.4",
  "description": "The progressive JavaScript framework for building modern web UI.",
  "main": "index.js",
  "module": "dist/vue.runtime.esm-bundler.js",
  "types": "dist/vue.d.ts",
  "unpkg": "dist/vue.global.js",
  "jsdelivr": "dist/vue.global.js",
  ........
 }

如果使用的是require('vue') CommonJS这种方式导入,那么其实导入的文件是对应的main属性后面的文件也就是index.js. 如果使用的是import这种ESModule的模式导入,那么import { createApp } from 'vue'对应的文件则是"dist/vue.runtime.esm-bundler.js",那么我们接下来找到这个文件。

// node_module/vue/dist/vue.runtime.esm-bundler.js
import { initCustomFormatter, warn } from '@vue/runtime-dom';
export * from '@vue/runtime-dom';

function initDev() {
  {
    initCustomFormatter();
  }
}

if (!!(process.env.NODE_ENV !== "production")) {
  initDev();
}
const compile = () => {
  if (!!(process.env.NODE_ENV !== "production")) {
    warn(
      `Runtime compilation is not supported in this build of Vue.` + (` Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js".` )
      /* should not happen */
    );
  }
};

export { compile };

上面的js文件里面并没有CreateApp这个函数啊,那么怎么导入的呢。接下来就得说说 export * from '@vue/runtime-dom'这个语句了。

export * from '@vue/runtime-dom'

这个语句用于重新导出 @vue/runtime-dom 模块中导出的所有内容。当你这样做时,之前的vue.runtime.esm-bundler.js模块会提供与 @vue/runtime-dom 相同的 API,使得其他模块可以从你的模块中导入这些 API,就好像它们直接从 @vue/runtime-dom 导入一样。

那么createApp只有可能藏在/node_modules/@vue/runtime-dom了。

首先我们先找到/node_modules/@vue/runtime-dom/package.json里面的module属性值为 "dist/runtime-dom.esm-bundler.js"找到对应的文件

.......
/node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js
const createApp = (...args) => {

  const app = ensureRenderer().createApp(...args);

  if (!!(process.env.NODE_ENV !== "production")) {

    injectNativeTagCheck(app);

    injectCompilerOptionsCheck(app);

  }

  const { mount } = app;

  app.mount = (containerOrSelector) => {

    const container = normalizeContainer(containerOrSelector);

    if (!container)

      return;

    const component = app._component;

    if (!isFunction(component) && !component.render && !component.template) {

      component.template = container.innerHTML;

    }

    container.innerHTML = "";

    const proxy = mount(container, false, container instanceof SVGElement);

    if (container instanceof Element) {

      container.removeAttribute("v-cloak");

      container.setAttribute("data-v-app", "");

    }

    return proxy;

  };

  return app;

};
.......

找到了CreatApp的定义了,接下来可以继续看源码啦~