Node在使用Import引入第三方模块时所经历的过程

序言

在写前端应用时总是需要import去引入第三包。

我们知道,当import ... from ... 来引入第三方包的时候,会在编译和打包的过程中加载node_modules文件夹下相对应的包。这个工作是由Node来完成。

以引入vuex为例。

当执行import Vuex from "vuex"时,Node会到node_modules文件夹下找到vuex文件夹并引入对应的包。

但这背后大致经历了哪些事情,就说不上来了。

所以借此文,我想说说我对Import第三方模块时所经历的过程的整理和理解。

说明符

对于我们自己写的模块,大多以相对路径或绝对路径的方式来引用,比如:

js 复制代码
import { ... } from './folder/folder/module_name.js'; // 相对路径
import { ... } from '/folder/folder/module_name.js'   // 绝对路径

这就说到了今天第一个主角------说明符。

import的语句中位于from后面的字符串被称为*说明符(specifier) *。

说明符有三种形式:

  1. 相对说明符 像"./startup.js", "./config.mjs"。相对于当前Import的文件路径引用。而且必须要有扩展名
  2. 裸说明符 像"some-package""some-package/shuffle"。
  3. 绝对说明符 : 像"'file:///opt/nodejs/config.js'","/path/some-package",直接和明确的引用一个完整路径。

显然,对于自己所写的模块,基本上都是相对说明符绝对说明符 ,而第三方包如vuex则属于裸说明符

模块加载算法

概括来说,import Vuex from 'vuex'会经历六个阶段

第一阶段:区分说明符 ,确认说明符为裸说明符。

第二阶段:进一步区分裸说明符 格式,确认说明符为第三方包。

第三阶段:获取node_modules 目录下找到第三方包的package.json文件。

第四阶段:获取package.json 文件中exports对象以"."开头的属性值(值为一个对象)。

第五阶段:解析exports对象中的值,并返回解析过后得到的url字符串。

第六阶段:解析得到的url字符串经过层层返回,最终交由第一阶段的函数来使用,通过url与url的文件后缀名确定格式后完成包的加载。

补充说明

在第二阶段中,何为"进一步区分裸说明符"?

裸说明符除了如"vuex"这样的第三方模块说明符外,还有内建模块如"fs","http"的说明符,还有以@开头的模块的说明符。

在第四阶段中,exports对象中以"."开头的对象是什么意思?

package.json中的exports字段定义了包的入口,作为原来main字段的替代。 "."代表着包的主入口,还可以用语法糖写成

json 复制代码
{
  "exports": "./index.js"
}

并且vuex中还用了一个条件exports(conditional exports), 它定义了包在不同环境下的入口

json 复制代码
    ".": {
      "module": "./dist/vuex.esm-bundler.js",
      "require": "./dist/vuex.cjs.js",
      "import": "./dist/vuex.mjs"
    }
    (在这个条件exports中,module字段只被webpack,rollup, wmr支持)

在第六阶段中,什么叫做确定格式?

这里的确定格式就是去确定被导入的模块属于ES标准模块还是commonjs标准模块,亦或是个json文件。

结语

到这里,我想说的东西大致已表述完。这一块内容比较零碎,并不是所有知识点都被覆盖,而且也不是那么容易整合上来,文中的错误和疏漏还希望被指出。人对真理的认识就是这样盘旋且曲折,但相信有了这些许的知识体系储备,以后再写import语句时就会更加自信从容。

参考

Modules: ECMAScript modules

Modules: Packages

webpack:模块解析

webpack:Package exports

相关推荐
南知意-1 分钟前
从零搭建 Live2D 看板娘教程(自建API避墙版)
服务器·前端·vue.js·开源·博客·美化·看板娘
来杯三花豆奶8 分钟前
Vue 2 中 Store (Vuex) 从入门到精通
前端·javascript·vue.js
Lethehong9 分钟前
React构建实时股票分析系统:蓝耘MaaS平台与DeepSeek-V3.2的集成实践
前端·react.js·前端框架·蓝耘mcp·蓝耘元生代·蓝耘maas
LSL666_10 分钟前
1 验证码
java·服务器·前端·redis·验证码
少油少盐不要辣26 分钟前
前端如何处理AI模型返回的流数据
前端·javascript·人工智能
IT_陈寒29 分钟前
Java21新特性实战:5个杀手级改进让你的开发效率提升40%
前端·人工智能·后端
跟着珅聪学java29 分钟前
以下是使用JavaScript动态拼接数组内容到HTML的多种方法及示例:
开发语言·前端·javascript
BD_Marathon32 分钟前
NPM_配置的补充说明
前端·npm·node.js
巴拉巴拉~~37 分钟前
KMP 算法通用图表组件:KmpChartWidget 多维度可视化 + PMT 表渲染 + 性能对比
前端·javascript·microsoft
智算菩萨43 分钟前
基于spaCy的英文自然语言处理系统:低频词提取与高级文本分析
前端·javascript·easyui