不够理解import和require导入的区别被diss惨了

举报
yd_244540595 发表于 2024/10/22 18:05:29 2024/10/22
【摘要】 作者:天天鸭前言在真实工作中,估计import和require大家经常见到,如果做前端业务代码,那么import更是随处可见了。但我们都是直接去使用,但是这两种方式的区别是什么呢?应用场景有什么区别呢?大部分能说出来import是ES6规范,而require是CommonJS规范,然后面试官深入问你两者编译规则有啥不一样?然后就不知道了本文一次性对import和require的模块基本概念、...

作者:天天鸭

前言


在真实工作中,估计importrequire大家经常见到,如果做前端业务代码,那么import更是随处可见了。但我们都是直接去使用,但是这两种方式的区别是什么呢?应用场景有什么区别呢?

大部分能说出来importES6规范,而requireCommonJS规范,然后面试官深入问你两者编译规则有啥不一样?然后就不知道了

本文一次性对importrequire模块基本概念编译规则基本用法差异生态支持性能对比5个方面一次理清总结好,下次遇到这种问题直接举一反三。

(顺便吆喝一句,技术大厂,前后端测试捞人,感兴趣来看这里


一、模块基本概念
require: 是CommonJS模块规范,主要应用于Node.js环境。
import:是ES6模块规范,主要应用于现代浏览器和现代js开发(适用于例如各种前端框架)。


二、编译规则
require
require 执行时会把导入的模块进行缓存,下次再调用会返回同一个实例。
CommonJS模块规范中,require默认是同步的。当我们在某个模块中使用require调用时,会等待调用完成才接着往下执行,如下例子所示。


模块A代码

console.log('我是模块A的1...');
const moduleB = require('./myModuleB');
console.log('我是模块A的2');


模块B代码

console.log('我是模块B...');


打印顺序,会按顺序同步执行

// 我是模块A的1...
// 我是模块B...
// 我是模块A的2...


注意require并非绝对是同步执行,例如在Webpack中能使用 require.ensure 来进行异步加载模块。

import

ES6模块规范中,import默认是静态编译的,也就是在编译过程就已经确认了导入的模块是啥,因此默认是同步的。import有引用提升置顶效果,也就是放在何处都会默认在最前面。

但是...., 通过import()动态引入是异步的哦,并且是在执行中加载的。 import()在真实业务中是很常见的,例如路由组件的懒加载component: () => import('@/components/dutest.vue')和动态组件const MyTest = await import('@/components/MyTest.vue');等等,import() 执行返回的是一个 Promise,所以经常会配合async/await一起用。

三、基本用法差异
require
一般不直接用于前端框架,是用于 Node.js 环境和一些前端构建工具(例如:Webpack)中

1. 导入模块(第三方库)
Node.js中经常要导入各种模块,用require可以导入模块是最常见的。例如导入一个os模块

const os = require('os');

// 使用
os.platform()


2. 导入本地写好的模块
假设我本地项目有一个名为 utils.js 的本地文件,文件里面导出一个add函数

module.exports = {
  add: (a, b) => a + b,
};


在其它文件中导入并使用上面的模块

const { add } = require('../test/utils');

// 使用
add(2, 3);


import
一般都是应用于现在浏览器和各种主流前端框架(例如:Vue\react

1. 静态引入(项目中最常用)
这种情况一般适用于确定的模块关系,是在编译时解析

<script setup>
 import { ref } from 'vue';
 import test from '@/components/test.vue';
</script>


2. 动态引入
其实就是使用import()函数去返回一个 Promise,在Promise回调函数里面处理加载相关,例如路由的懒加载。

{
  path: '/',
  name: 'test',
  component: () => import('@/components/dutest.vue')
},


或者动态引入一些文件(或者本地的JSON文件)

<script setup>
 const MyTest = await import('@/components/MyTest.vue');
</script>


四、生态支持
require

Node.js14 之前是默认模块系统。目前的浏览器基本是不原生支持 CommonJS,都是需要通过构建工具(如 Webpack )转换才行。并且虽然目前市面上CommonJS依然广泛使用,但基本都是比较老的库,感觉被逐渐过渡了。

import

importES6规范,并且Node.jsNode.js12开始支持ES6Node.js14 之后是默认选项。目前现代浏览器和主流的框架(Vue、React)都支持原生ES6,大多数现代库也是,因此import是未来主流。

五、性能对比

ES6 支持 Tree Shaking摇树优化,因此可以更好地去除一些没用的代码,能很好减小打包体积。 所以import有更好的性能。

import()能动态导入模块性能更好,而require不支持动态导入。

小结

对比下来发现,import不但有更好性能,而且还是Node.js14之后的默认,会是主流趋势。

至此我感觉足够能举一反三了,如有哪里写的不对或者有更好建议欢迎大佬指点一二啊。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。