彻底理解import和require区别和用法
前言
在真实工作中,估计import
和require
大家经常见到,如果做前端业务代码,那么import
更是随处可见了。但我们都是直接去使用,但是这两种方式的区别是什么呢?应用场景有什么区别呢?
大部分能说出来import
是ES6
规范,而require
是CommonJS
规范,然后面试官深入问你两者编译规则有啥不一样?然后就不知道了
本文一次性对import
和require
的模块基本概念
、编译规则
、基本用法差异
、生态支持
和性能对比
等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
:
import
是ES6
规范,并且Node.js
在Node.js12
开始支持ES6
,Node.js14
之后是默认选项。目前现代浏览器和主流的框架(Vue、React
)都支持原生ES6
,大多数现代库也是,因此import
是未来主流。
五、性能对比
ES6
支持 Tree Shaking
摇树优化,因此可以更好地去除一些没用的代码,能很好减小打包体积。
所以import
有更好的性能。
import()
能动态导入模块性能更好,而require
不支持动态导入。
小结
对比下来发现,import
不但有更好性能,而且还是Node.js14
之后的默认,会是主流趋势。
至此我感觉足够能举一反三了,如有哪里写的不对或者有更好建议欢迎大佬指点一二啊。
来源:juejin.cn/post/7425135423145394213