注册
web

彻底理解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之后的默认,会是主流趋势。


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


作者:天天鸭
来源:juejin.cn/post/7425135423145394213

0 个评论

要回复文章请先登录注册