偶尔一次发现,他们两个的引入模块的形式不一样,在好奇心的驱使下,便开始一探到底。
1、vue.config形式
关上我的项目的package.json,找到 scripts地位。
找到 vue-cli-service 命令,通常命令都位于以后我的项目的node_modules下的 .bin文件夹中(全局命令不在此处)
在node_modules下找到 @vue/cli-service/bin/vue-cli-service.js
最重要是红色框内语句。持续往下找。
service.js文件比拟长,重要的是上面这句。
关上 loadFileConfig
这个文件很短,只有38行,却十分重要。
粗心是首先去找是否有自定义配置文件门路,如果有,就加载自定义配置文件;
如果没有,就用默认的 vue.config.xx。
找到配置文件后,通过 is-file-esm 模块来判断配置文件是用es模块形式,还是 commonjs模块形式加载。
而 is-file-esm判断没有别的。就是通过nodejs官网定义的文件 拓展名 和 package.json中的 type 去判断。这里感兴趣,能够浏览nodejs官网对于 commonjs 和 esm 的反对和定义。
is-file-esm模块会先通过文件扩展名判断,
.mjs 为esm , .js, .cjs为commonjs模块,如果没有扩展名,则通过判断package.json的type判断"type":"module", 为esm,"type":"commonjs", 为esm,如果扩展名和type同时呈现,则扩展名优先级高。
所以,如果type没指定,vue.config.js以 js 结尾,那么加载的就是 commmonjs,vue.config.js是以 commonjs 形式启动,模块引入只能用 require,而不是import,如果改成import,就会报错.
咱们能够将扩展名换成 .mjs试试 (同样能够在package.json中指定type,咱们只是挑一种,你有趣味,能够去试试)
启动后,发现import失常辨认,然而 require没有被定义。阐明 vue.config.mjs是以 es模块的形式启动的。
2、vite.config形式
关上我的项目的package.json,找到 scripts地位。
同样,找到 node_module下的 .bin 目录
找到 vite模块下的 bin.vite.js
再找到dist/node/cli
在cli.js这个文件中,找到 /chunks/dep-c9998dc6.js(名称可能版本不同会变,但必定是位于 createServer 地位处)
在 dep-c9998dc6.js文件中,找到 loadConfigFromFile办法。
能够发现,这里的 isESM 变量,并不是通过模块去判断,而是间接在代码中通过 package.json的type或者 vite.config.xx 的扩展名判断的。只不过多了个额定的ts, 如果扩展名是ts,则也是es模块。
如果配置文件是 vite.config.js。那么isESM为false, userConfig 为undefined, 之后执行 bundleConfigFile 办法将 es模块转译为 commonjs模块(看正文)
// Bundle config file and transpile it to cjs using esbuild.const bundled = await bundleConfigFile(resolvedPath);
这就是为什么,vite.config.js 即便不是 es 模块,也能够在外面应用import的起因。因为被转译了。
当然批改 vite.config.js 为 vite.config.mjs也是能够的。
最终后果和 vue.config.js大同小异,都是先判断模块类型后,再通过不同的加载器,将其加载进来。