链接:https://www.zhihu.com/question/56820346

遵循的模块化规范不一样

模块化规范:即为 JavaScript 提供一种模块编写、模块依赖和模块运行的方案。谁让最初的 JavaScript 是那么的裸奔呢——全局变量就是它的模块化规范。

require/exports 出生在野生规范当中,什么叫做野生规范?即这些规范是 JavaScript 社区中的开发者自己草拟的规则,得到了大家的承认或者广泛的应用。比如 CommonJS、AMD、CMD 等等。import/export 则是名门正派。TC39 制定的新的 ECMAScript 版本,即 ES6(ES2015)中包含进来。

出现的时间不同

require/exports 相关的规范由于野生性质,在 2010 年前后出生。AMD、CMD 相对命比较短,到 2014 年基本上就摇摇欲坠了。一开始大家还比较喜欢在浏览器上采用这种异步小模块的加载方式,但并不是银弹。随着 Node.js 流行和 Browsersify 的兴起,运行时异步加载逐渐被构建时模块合并分块所替代。Wrapper 函数再也不需要了。 2014 年 Webpack 还是新玩意,现在已经是前端必备神器了。

Browsersify、Webpack 一开始的目的就是打包 CommonJS 模块。

CommonJS 作为 Node.js 的规范,一直沿用至今。由于 npm 上 CommonJS 的类库众多,以及 CommonJS 和 ES6 之间的差异,Node.js 无法直接兼容 ES6。所以现阶段 require/exports 任然是必要且实必须的。出自 ES6 的 import/export 相对就晚了许多。被大家所熟知和使用也是 2015 年之后的事了。 这其实要感谢 babel(原来项目名叫做 6to5,后更名为 babel) 这个神一般的项目。由于有了 babel 将还未被宿主环境(各浏览器、Node.js)直接支持的 ES6 Module 编译为 ES5 的 CommonJS —— 也就是 require/exports 这种写法 —— Webpack 插上 babel-loader 这个翅膀才开始高飞,大家也才可以称 " 我在使用 ES6! "

这也就是为什么前面说 require/exports 是必要且必须的。因为事实是,目前你编写的 import/export 最终都是编译为 require/exports 来执行的。

require/exports 和 import/export 形式不一样

require/exports 的用法只有以下三种简单的写法:

const fs = require('fs')
exports.fs = fs
module.exports = fs

而 import/export 的写法就多种多样:

import fs from 'fs'
import {default as fs} from 'fs'
import * as fs from 'fs'
import {readFile} from 'fs'
import {readFile as read} from 'fs'
import fs, {readFile} from 'fs' export default fs
export const fs
export function readFile
export {readFile, read}
export * from 'fs'

require/exports 和 import/export 本质上的差别

形式上看起来五花八门,但本质上:

  1. CommonJS 还是 ES6 Module 输出都可以看成是一个具备多个属性或者方法的对象;
  2. default 是 ES6 Module 所独有的关键字,export default fs 输出默认的接口对象,import fs from 'fs' 可直接导入这个对象;
  3. ES6 Module 中导入模块的属性或者方法是强绑定的,包括基础类型;而 CommonJS 则是普通的值传递或者引用传递。

1、2 相对比较好理解,3 需要看个例子:

// counter.js
exports.count = 0
setTimeout(function () {
console.log('increase count to', ++exports.count, 'in counter.js after 500ms')
}, 500) // commonjs.js
const {count} = require('./counter')
setTimeout(function () {
console.log('read count after 1000ms in commonjs is', count)
}, 1000) //es6.js
import {count} from './counter'
setTimeout(function () {
console.log('read count after 1000ms in es6 is', count)
}, 1000)

分别运行 commonjs.js 和 es6.js:

➜  test node commonjs.js
increase count to 1 in counter.js after 500ms
read count after 1000ms in commonjs is 0
➜ test babel-node es6.js
increase count to 1 in counter.js after 500ms
read count after 1000ms in es6 is 1
require 值拷贝,import 值引用

require,import区别的更多相关文章

  1. JS 中的require 和 import 区别整理

    ES6标准发布后,module成为标准,标准的使用是以export指令导出接口,以import引入模块,但是在我们一贯的node模块中,我们采用的是CommonJS规范,使用require引入模块,使 ...

  2. require 和 import 区别

    我很懵逼啊  都是在引用模块,那到底用哪个? 参考:https://www.cnblogs.com/hwldyz/p/9145959.html 看来会明白一点的 首先这两个都是为了JS模块化编程使用. ...

  3. php中include()和require()的区别

    1.引用文件方式 对 include()来说,在include()执行时文件每次都要进行读取和评估:而对于require()来说,文件只处理一次(实际上,文件内容替换 了require()语句.这就意 ...

  4. css link和@import区别

    1.link语法结构 <link href="CSSurl路径" rel="stylesheet" type="text/css" / ...

  5. css link和@import区别用法

    这里link与@import介绍的是html引入css的语法单词.两者均是引入css到html的单词. 1.link语法结构<link rel="stylesheet" ty ...

  6. PHP中include和require的区别

    include和require的区别,其实两者没有太大的区别,如果要包含的文件不存在,include提示notice,然后继续执行下面的语句,require提示致命错误并且退出. 根据测试,win32 ...

  7. php引入文件(include 和require的区别)

    引入文件: 首先需要一个php文件: <?php class shao//类名必须和文件名相同!!! { public $xxx="666"; } $shili = new ...

  8. php require include 区别

    php提供了两种包含外部文件的方法:include()和require().include()语句是一个常规的php函数:而require() 是一种特殊的语言结构,它的使用受到一些限制.对这两者来说 ...

  9. include和require的区别误区

    面试时总会被问到include和require的区别,回答的时候一般也是有以下几种区别: 1.include引入文件的时候,如果碰到错误,会给出警告,并继续运行下边的代码. require引入文件的时 ...

  10. php include 和require的区别与转码

    php include 和require的区别相同点:include和require 都能把另外一个文件包含到当前文件中.  不同点:使用include时,当包含的文件不存在时,系统会报出警告级别的错 ...

随机推荐

  1. C#基础加强(2)之密闭类、静态类及扩展方法

    密闭类 简介 密闭类是被 sealed 关键字修饰的类,密闭类不能有子类.一般只有系统的一些基本类声明为密闭类,例如 String 类. 相关面试题 是否可以编写一个类继承自 String 类? 我们 ...

  2. align-item 和 align-content的区别

    align-content 和 align-items  : 1:共同点:它们对齐方向为交叉轴 2:不同点:align-content 应用于为 多行   而 align-items:应用于单行.

  3. grunt 打包 分解(并非原创)

    1. require('time-grunt')(grunt); Time how long tasks take. Can help when optimizing build times任务执行时 ...

  4. vscode/webstorm快捷键

    ctrl+/  单行 [alt+shift+A]  多行注释 (默认的  我已经修改了) 复制当前行:shift + alt +up/down(上下箭头)可以修改成ctrl+d(改成webstorm一 ...

  5. bzoj4195(并查集+离散化)

    题目大意:给出n个变量互相的相等或不等关系,求这些关系是否矛盾 思路:把相等的变量加入并查集,不等的查询是否合法 eg:数据很大,离散化(然而我用的是map) #include<stdio.h& ...

  6. 2017.11.18 手把手教你学51单片机-点亮LED

    In Doing We Learning 在操作中学习.如果只是光看教程,没有实际的操作,对编程语言的理解很空泛,所以决定从单片机中学习C语言. #include<reg52.h>     ...

  7. 移动端热更新方案(iOS+Android)

    PPT资源包含iOS+Android 各种方案分析:https://github.com/qiyer/Share/blob/master/%E7%83%AD%E6%9B%B4%E6%96%B0%E5% ...

  8. is 和 == 以及 编码和解码

    1.is  比较的是内存地址 a="name" b="snow" print(a is b) # False id()  获取内存地址 a=" == ...

  9. Python数据分析Numpy库方法简介(一)

    Numpy功能简介: 1.官网:www.numpy.org 2.特点:(1)高效的多维矩阵/数组; (2);复杂的广播功能 (3):有大量的内置数学统计函数 矩阵(多维数组): 一维数组:  ([ 值 ...

  10. msf下的各种生成payload命令

    Often one of the most useful (and to the beginner underrated) abilities of Metasploit is the msfpayl ...