11

image.pngimage.png

Accidentally discovered that the two of them had different ways of introducing modules. Driven by curiosity, they began to find out.

1. vue.config method

Open the project's package.json and find the scripts location.
image.png

Find the vue-cli-service command, usually the commands are located in the .bin folder under the node_modules of the current project (the global command is not here)

image.png
image.png

Find @vue/cli-service/bin/vue-cli-service.js under node_modules
image.png

The most important is the statement in the red box. Keep looking down.
image.png

The service.js file is relatively long, and the important thing is the following sentence.
image.png

open loadFileConfig
image.png

This file is very short, only 38 lines, but it is very important.

The general idea is to first find out whether there is a custom configuration file path, and if so, load the custom configuration file;
If not, use the default vue.config.xx.

After finding the configuration file, use the is-file-esm module to determine whether the configuration file is loaded in the es module mode or the commonjs module mode.

And is-file-esm judges nothing else. It is judged by the file extension officially defined by nodejs and the type in package.json. If you are interested here, you can read the official support and definition of commonjs and esm by nodejs .

The is-file-esm module will first judge by the file extension,

 .mjs 为esm , 
.js, .cjs为commonjs模块,

如果没有扩展名,则通过判断package.json的type判断
"type":"module",   为esm,
"type":"commonjs",   为esm,

如果扩展名和type同时出现,则扩展名优先级高。

Therefore, if the type is not specified, and vue.config.js ends with js, then commonjs is loaded, vue.config.js is started in commonjs mode, and module introduction can only be done with require, not import. If it is changed to import, then will report an error.
image.png

We can try changing the extension to .mjs (the type can also be specified in package.json, we just pick one, if you are interested, you can try it)
image.png
image.png

After startup, it is found that import is recognized normally, but require is not defined. It means that vue.config.mjs is started as an es module.

2, vite.config method

Open the project's package.json and find the scripts location.
image.png

Similarly, find the .bin directory under node_module
image.png
image.png

Find bin.vite.js under the vite module
image.png
image.png

Find dist/node/cli again
image.png

In the file cli.js, find /chunks/dep-c9998dc6.js (the name may vary depending on the version, but it must be located at the createServer location)
image.png
image.png

In the dep-c9998dc6.js file, find the loadConfigFromFile method.
image.png
image.png

It can be found that the isESM variable here is not judged by the module, but directly judged by the type of package.json or the extension of vite.config.xx in the code. Just an extra ts, if the extension is ts, it is also an es module.

If the configuration file is vite.config.js. Then isESM is false, userConfig is undefined, and then the bundleConfigFile method is executed to translate the es module into a commonjs module (see comments)

 // Bundle config file and transpile it to cjs using esbuild.
const bundled = await bundleConfigFile(resolvedPath);

That's why vite.config.js can use import in it even if it's not an es module. because it was translated.

Of course, it is also possible to modify vite.config.js to vite.config.mjs.

The final result is similar to vue.config.js, which is to judge the module type first, and then load it in through different loaders.


寒水寺一禅
2.3k 声望119 粉丝

人生短短急个球!