import 和 require区别

import和require分别是不同模块化规范下引入模块的语句。

1.时间

年份 出处
require/exprots 2009 Commonjs
improt/exprot 2015 ECMAScript2015(ES6)

2. 不同端(客户端/服务器)的使用限制

CommonJS 模块化方案 require/exports 是为服务器端开发设计的。服务器模块系统同步读取模块文件内容,编译执行后得到模块接口。(Node.js 是 CommonJS 规范的实现)。

在浏览器端,因为其异步加载脚本文件的特性,CommonJS 规范无法正常加载。所以出现了 RequireJS、SeaJS 等(兼容 CommonJS )为浏览器设计的模块化方案。
两种方案各有各的限制,需要注意以下几点:

  • 原生浏览器不支持 require/exports,可使用支持 CommonJS 模块规范的 Browsersify、webpack 等打包工具,它们会将 require/exports 转换成能在浏览器使用的代码。
  • import/export 在浏览器中无法直接使用,我们需要在引入模块的 <script> 元素上添加type="module属性。
  • 即使 Node.js 13.2+ 已经支持 import/export,Node.js官方不建议在正式环境使用,目前可以使用 babel 将 ES6 的模块系统编译成 CommonJS 规范(注意:语法一样,但具体实现还 是require/exports)。
  1. require/exports 是运行时动态加载,import/export 是静态编译

CommonJS 加载的是一个对象(即 module.exports 属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。- 阮一峰

4. require/exports 输出的是一个值的拷贝,import/export 模块输出的是值的引用

require/exports 输出的是值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。

import/export 模块输出的是值的引用。JS 引擎对脚本静态分析的时候,遇到模块加载命令import,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。

若文件引用的模块值改变,require 引入的模块值不会改变,而 import 引入的模块值会改变。

  1. 用法不一致
    (1). require/exports 的用法
const fs = require('fs')
exports.fs = fs
module.exports = fs

exports 是对 module.exports 的引用,相当于

exports = module.exports = {};

在不改变 exports 指向的情况下,使用exports 和 module.exports 没有区别;如果将 exports 指向了其他对象,exports 改变不会改变模块输出值。示例如下:

//utils.js
let a = 100;

exports.a = 200;
console.log(module.exports) //{a : 200}
exports = {a:300}; //exports 指向其他内存区

//test.js

var a = require('./utils');
console.log(a) // 打印为 {a : 200}

在验证代码的时候遇到如下报错

access to script from origin 'null' has been blocked by CORS policy

因为 module 不支持 file:// 文件协议,只支持 HTTP 协议,需要使用 http-server 等本地网络服务器打开网页文件。
(2). import/export 的写法
import fs from 'fs'

import {readFile} from 'fs' //从 fs 导入 readFile 模块
import {default as fs} from 'fs' //从 fs 中导入使用 export default 导出的模块
import * as fileSystem from 'fs' //从 fs 所有导出模块,引用对象名为 fileSystem
import {readFile as read} from 'fs' //从 fs 导入 readFile 模块,引用对象名为 read
import('/modules/my-module.js') //动态导入
  .then((module) => {
    // Do something with the module.
});

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

建议1:建议明确列出我们要引用的内容。,使用 * 虽然很方便,但是不利于现代的构建工具检测未被使用的函数,影响代码优化。
建议2: 请不要滥用动态导入 import()(只有在必要情况下采用)。静态框架能更好的初始化依赖,而且更有利于静态分析工具和 tree shaking 发挥作用

引入 export default 导出的模块不用加 {},引入非export default 导出的模块需要加 {}。

import fileSystem, {readFile} from 'fs'

一个文件只能导出一个 default 模块。

(3). import/export 不能对引入模块重新赋值/定义
当我尝试给 import 的模块重新赋值时

import {e1} from './webUtils.js';
  e1=234;

浏览器显示

Uncaught TypeError: Assignment to constant variable.

当我重新定义引用的模块

import {e1} from './webUtils.js';
 var e1=1;

浏览器显示

(index):17 Uncaught SyntaxError: Identifier 'e1' has already been declared

(4). ES6 模块可以在 import 引用语句前使用模块,CommonJS 则需要先引用后使用
ES6 模块

//webUtils.js
export var e='export';
console.log(e) //export
  import {e} from './webUtils.js';
  console.log(e) //export

CommonJS

//utils.js
exports.e = 'export';
console.log(a) 
a = require('./utils');
console.log(a)

程序报错

ReferenceError: a is not defined

  1. 是否采用严格模式

严格模式是采用具有限制性JavaScript变体的一种方式

import/export 导出的模块默认调用严格模式。

var fun=()=>{
    mistypedVaraible = 17; //报错,mistypedVaraible is not defined
};
export default fun;

require/exports 默认不使用严格模式,可以自定义是否使用严格模式。 例如

exports.fun = ()=>{
 mistypedVaraible = 17; //没有调用严格模式,不会报错
};
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266