import...from... 和 require 如何找到模块位置?

news2024/11/28 9:41:08
import Vue from "vue"; 

为什么不用写相对地址和绝对地址就能够导出 Vue 呢?似乎也没有配置路径?也没有配置映射,那么究竟 from "vue"; 对应的究竟是那个路径呢?

先提出两个可能的方案

1.VS Code/WebStorm 这些 IDE 自己编撰的映射,并缓存了
2.Webpack/Vite 这些开发工具自带的映射

关于上面这两个方案其实很容易验证,基于终端/命令行去运行项目并且不使用 WebpackVite 这两个库

1.第一步,执行以下语句

npm init
# shelljs 是一个可以使用 node 执行 shell 脚本的库
# 例子中使用 shelljs 测试输出
npm install shelljs 

2.第二步,在 package.json 同目录下创建 index.js,内容如下

const shelljs = require("shelljs");

shelljs.exec("echo Hello World"); 

3.第三步,测试运行 node index.js,输出如下

即证与 IDEWebpack/Vite 无关

那究竟是怎么找到的呢?

node 模块

仔细观察 node index.js 是通过 node 执行的,所以有没有可能是通过 node 去找到的模块呢?

那么 node 执行 .js 文件时是按照什么规则来寻找的呢?

假设在 Y 路径执行 index.js

// index.js
const module = require(X) 

X 以 或 ‘./’ 或 ‘…/’ 开头

判断 Y + X 是文件还是目录

Y + X 是文件

1.如果 X 是一个文件,加载 X 作为 JavaScript 文本。结束
2.如果 X.js 是一个文件,加载 X.js 作为 JavaScript 文本。结束
3.如果 X.json 是一个文件,解析 X.json 成一个 JavaScript 对象。结束
4.如果 X.node 是一个文件,加载 X.node 作为二进制插件。结束

例子

// index.js
const shelljs = require("./X");

shelljs.exec("echo Hello World"); 
// X.js
module.exports = {exec: () => {console.log("Hello World");}
} 
├── index.js
└── X.js 

注意,有文档称,require(/X) 这种方式也可以找到对于的模块,但在 node@16.15.1 的版本中已经不行,是无法找到的

Y + X 是目录

判断是否有名称为 index 的文件

Y + X 目录下有名为 index 的文件

1.如果 X/index.js 是一个文件,加载 X/index.js 作为 JavaScript 文本。结束
2.如果 X/index.json 是一个文件,解析 X/index.json 成一个 JavaScript 对象。结束
3.如果 X/index.node 是一个文件,加载 X/index.node 作为二进制插件。结束

Y + X 目录下没有名为 index 的文件

根据 Y + X 目录下的 package.json"main" 字段找到对应的文件

没有 package.json 怎么办?当然是报错咯

X 是模块名称

1.先去系统模块寻找
2.系统模块没有找到就去执行环境的同目录下找 node_modules,查看有无同名的 .js 文件1.没有同名的 .js 文件就去找同名目录1.如果找到了,就查看文件夹里有没有 index.js2.没有找到就查看 package.json"main" 属性来确定2.没有同名目录,抛出错误
3.同目录找不到 node_modules 就去父目录找,父目录找不到就找父目录的父目录,直至找到全局 node_modules

关于 node 更加详细的‘寻模块’规则,可以去查阅这个文档,里面有一个伪代码,非常详细和清晰

ES Module

上面讲了 require 的寻找规则,但是没讲 ES Module 的寻找规则(即 import),其实它们的寻址方式是一致的,不过 ES Module 需要在 package.json 设置 "type" 字段为 module 才可以开启,而且找的是package.json"module" 字段对应的文件

// package.json
{"type": "module"
} 

那么回到文章一开始提到的 import Vue from "vue";,它最终找到的模块是什么呢?因为 Vue 本身提供多种打包文件(Commen.jsES Module

如上图所示 import Vue from "vue"; 最终找的是 vue.runtime.esm.js,这也就解释了为什么导出来的 Vue 是不带编译时只有运行时的了

最后

整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。

有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享

部分文档展示:



文章篇幅有限,后面的内容就不一一展示了

有需要的小伙伴,可以点下方卡片免费领取

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/142831.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【每天学习一点新知识】nmap端口扫描

nmap所识别的6个端口状态open(开放的)应用程序正在该端口接收TCP 连接或者UDP报文。发现这一点常常是端口扫描 的主要目标。安全意识强的人们知道每个开放的端口 都是攻击的入口。攻击者或者入侵测试者想要发现开放的端口。 而管理员则试图关闭它们或者用防火墙保护它们以免妨碍…

Java封装公共Result结果返回类

前言 在使用Java开发接口请求中,我们需要对请求进行进行统一返回值,这时候我们自己封装一个统一的Result返回类,下面就介绍下我用的这种的这个类 当然,也可以使用第三方库封装的Result结果返回类,根据个人喜好选择即可…

学习笔记之Vue脚手架(三)

(三)使用Vue脚手架 使用Vue脚手架(三)使用Vue脚手架一、创建Vue脚手架1.1 说明1.2 具体步骤二、分析脚手架结构2.1 配置文件2.2 src文件夹2.3 public文件夹一、创建Vue脚手架 1.1 说明 1.Vue脚手架是Vue官方提供的标准开发工具&…

电脑技巧:分享常用的电脑快捷键

❤️作者主页:IT技术分享社区 ❤️作者简介:大家好,我是IT技术分享社区的博主,从事C#、Java开发九年,对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️个人荣誉: 数据库领域优质创作者🏆&#x…

Nutanix 替代专题 | SmartX 与 Nutanix 超融合市场、技术与性能对比

2022 年 8 月 19 日,Nutanix(路坦力)宣布中国市场自 2023 财年起将转型为合作伙伴销售主导模式,引起了广泛关注;同时结合当前 IT 基础架构的国产化趋势背景,不少正在使用和考虑使用 Nutanix 产品的企业开始…

js 跨域访问问题解决方法

什么引起了ajax不能跨域请求的问题? ajax本身实际上是通过XMLHttpRequest对象来进行数据的交互,而浏览器出于安全考虑,不允许js代码进行跨域操作,所以会警告。 有什么完美的解决方案么? 解决方案有不少,但…

数字化门店管理|如何让门店数字化管理,更加贴合日常运营细节?

在赋能品牌门店数字化管理的过程中,帷幄既注重前沿 AI 算法带来的技术驱动力,也注重基于门店管理中的真实场景与需求,让算法更贴合业务实际需求,从而带来运营优化与降本增效。 1 月,「帷幄数智空间 Whale SpaceSight」…

植物大战 动态内存——C++

这里是目录标题前言动态内存分布如何理解C语法的增加newnew用法关于struct和class的使用关于free和delete的区别。背会这句话抛异常operator new和operator delete内存池new和delete原理定位newmalloc和new的区别是什么?内存泄漏前言 总结复习前面的知识。 注意&a…

一文带你了解什么是云计算网络运维工程师,以及2023年的就业前景

作者简介:一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页​​​​​​ 目录 前言 一.云计算网络运维工程师是做什么的? 二.作为一名云计算网络运…

MyBatis(用于简化JDBC开发)

MyBatis是一款持久层框架,用于简化JDBC开发 持久层:将数据报错到数据库,持久化更改的意思 javaEE三层架构:表现层(页面)、业务层(处理逻辑)、持久层(数据永久化更改&am…

拉伯证券|人心动了?刚刚,A股、港股大涨!

昨日A股传言较多,引发波动。上一年10月底11月初,也有类似情况。换个视点看,这说明人心开端动了,至于怎样个“思变”法,市场可能现已给出了答案! 今天上午,A股大涨,北向资金净流入110…

cs231n-2022-01 Assignments1-numpy的使用

numpy的使用 Numpy是Python中科学计算的核心库。它提供了一个高性能的多维数组对象,以及处理这些数组的工具。如果你已经熟悉MATLAB,你可能会发现这个教程对开始使用Numpy很有用。 运行并阅读cs231n课程网站上提供的示例代码,感觉十分简洁&a…

TIA博途SCL学习_堆栈的入栈和出栈(后入先出)程序示例

TIA博途SCL学习_堆栈的入栈和出栈(后入先出)程序示例 如下图所示,添加一个FB块,语言选择SCL,命名为“入栈”, 如下图所示,通过FOR循环实现堆栈数组内的元素的移动,并将入栈的数据赋值给数组的第一个元素, 如下图所示,添加一个全局DB块,在该DB块中添加一个长度为10…

Visio中插入Mathtyp公式

Visio中插入Mathtype公式 打开visio软件,依次点击“插入”–“对象”–“mathtype 6.0 equation”–“确定”,也可以得到我们想要的公式。 点击“对象”,然后显示出Mathtype公式 点击“Mathtype 7.0”,然后显示公式框 Way 1&a…

win10和win11鼠标灵敏度修改和大小颜色其他等步骤

目录 一、前言 二、win10鼠标设置 1.进入鼠标设置界面 2.鼠标速度的调节 3.鼠标大小和颜色的调节 4.鼠标其他设置 三、win11鼠标设置 1.进入搜索界面 2.鼠标大小和颜色设置 3.鼠标的移动灵敏速度设置 4.鼠标图标的自定义 一、前言 在使用电脑鼠标时候,会觉…

【自然语言处理】【ChatGPT系列】WebGPT:基于人类反馈的浏览器辅助问答

WebGPT: 基于人类反馈的浏览器辅助问答《WebGPT: Browser-assisted question-answering with human feedback》论文地址:https://arxiv.org/pdf/2112.09332.pdf 相关博客 【自然语言处理】【ChatGPT系列】WebGPT:基于人类反馈的浏览器辅助问答 【自然语言…

[HTML] HTML基础知识

1.HTML简介 HTML指的是超文本标记语言(HyperText Markup Language)&#xff0c;是一种用于创建网页的标准标记语言 HTML页面基本结构 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X…

SpringMVC框架

一、什么是 SpringMVC ? SpringMVC框架是以请求为驱动&#xff0c;围绕Servlet设计&#xff0c;将请求发给控制器&#xff0c;然后通过模型对象&#xff0c;分派器来展示请求结果视图。其中核心类是DispatcherServlet&#xff0c;它是一个Servlet&#xff0c;顶层是实现的Ser…

不会指针?还不进来看看——进阶指针详解

专栏&#xff1a;C语言 每日一句&#xff1a;人贵有自知之明&#xff0c;知道什么可为和不可为。若不可为&#xff0c;怎样做才能可为&#xff0c;那何时可为。 进阶指针前言一、字符指针二、指针数组1.指针数组的介绍2.指针数组的使用三、数组指针1.数组指针的介绍2.&数组…

历史大讲堂:真那么好用?Windows前世今生

hello大家好&#xff0c;这里是每天日更哒博主。 还记得我第一次说的Microsoft Dos吗&#xff1f;那期我提到一次Windows并许诺要讲讲&#xff0c;这不来了&#xff01;今天我们就详细的盘一盘最好用的系统Windows真有那么神吗&#xff1f; 注意&#xff01;以下内容包含非常…