require/exports與import/export,有啥不同的??

歷史背景

  • require/exports瀏覽器

    • 來自野生規範當中,即這些規範是JavaScript社區中的開發者本身草擬的規則,獲得了你們的認可和普遍的應用,好比CommonJSAMDCMD等等。而Node遵循CommonJS規範,requireJS遵循AMDseaJS遵循CMD
    • 由於Node沒法直接兼容ES6語法,因此現階段require/exports仍然是必要且是必須的。
  • import/export緩存

    • 來自ES6的新規範,即TC39 制定的新的 ECMAScript 版本。
    • babel誕生後,它能將還未被宿主環境(各大瀏覽器、Node)直接支持的ES6語法編譯爲ES5,也就是能將ES6 Moduleimport/export編譯爲CommonJSrequire/exports這種寫法。

差別

寫法差別

require/exports

/* 導出 */
exports.fs = fs;      // 單個特性導出,可導出多個
module.exports = fs;   // 整個模塊導出,每一個模塊只包含一個

/* 引入 */
const fs = require('fs');   // 引入整個模塊

import/export

/* 導出 */
export default fs;     // 默認導出 每一個模塊包含一個 每次導出都會覆蓋前一個導出
export const fs;       // 導出單個特性 每一個模塊包括多個
export function readFile;    // 導出單個特性 每一個模塊包括多個
export { readFile, read };   // 導出列表
export * from 'fs';     // 導出模塊合集

/* 引入 */
import fs from 'fs';       // 引入整個模塊的內容
import '/fs.js';          // 僅爲反作用而引入一個模塊 不導入模塊中的任何接口
import * as fs from 'fs';    // 引入整個模塊的內容
import { readFile } from 'fs';   // 引入readFile單個接口
import { readFile as read } from 'fs';   // 引入模塊中read接口,並重命名爲readFile
import fs , { readFile } from 'fs';   // 引入整個模塊的內容和readFile接口

輸出差別

require/exports

require/exports 輸出的是一個值的拷貝,也就是說,當你引入一個值,模塊內部的變化是影響不到這個值的。babel

// test.js
let num = 0;
function addNum(){
  num++;
};
module.exports = {
  num: num,
  addNum: addNum
}

// main.js
const test = require('./test.js');

console.log(test.num);     // output: 0
test.addNum();
console.log(test.num);     // output: 0

import/export

import/export輸出的是值的索引,也就是說,該引用實際上是一個動態引用,並不會緩存值,當模塊內部發生變化,你的引入值也會隨之更新。異步

// test.js
export let num = 0;
export function addNum(){
  num++;
};

// main.js
import { num, addNum } from './test.js';

console.log(num);     // output: 0
addNum();
console.log(num);     // output: 1

加載差別

require/exports

CommonJS模塊是運行時加載。優化

由於CommonJS模塊加載的是一個對象,即module.exports屬性,該對象只有在腳本運行完才生成,也所以沒辦法再編譯時作「靜態優化」。ui

const { test1, test2, test3 } = require('test');

/* 等同於 */
const _test = require('test');   // 實質上加載了整個模塊,再從中讀取這三個方法
const test1 = _test.test1;
const test2 = _test.test2;
const test3 = _test.test3;

import/export

ES6模塊是編譯時輸出接口。code

ES6模塊不是對象,它對外接口只是一個靜態定義,在代碼靜態解析階段纔會生成,所以效率要比CommonJS模塊加載高。對象

import { test1, test2, test3 } from 'test';   // 只從模塊中加載這三個方法,其餘的不加載

異步差別

require/exports

CommonJS模塊中的require是同步加載模塊。索引

import/export

ES6模塊的import命令是異步加載的,有一個獨立的模塊依賴的解析階段。接口

相關文章
相關標籤/搜索