CommonJSモジュールとES 6モジュールの違い

23572 ワード

CommonJS 1.基本データ型については、レプリケーションに属します.モジュールによってキャッシュされます.同時に、別のモジュールでは、モジュールが出力した変数を再割り当てできます.2.複雑なデータ型の場合は、浅いコピーです.2つのモジュールが参照するオブジェクトは同じメモリ領域を指すため、そのモジュールの値を変更すると別のモジュールに影響します.3.requireコマンドを使用してモジュールをロードすると、モジュール全体のコードが実行されます.4.requireコマンドを使用して同じモジュールをロードすると、モジュールは実行されず、キャッシュ内の値が取得されます.つまり、CommonJSモジュールは、何度ロードしても、1回目のロード時に1回しか実行されず、後でロードすると、手動でシステムキャッシュをクリアしない限り、1回目の実行結果が返されます.5.ループロードの場合、ロードに属する場合に実行します.すなわち,スクリプトコードはrequireの場合,すべて実行される.モジュールが「ループロード」されると、実行された部分のみが出力され、まだ実行されていない部分は出力されません.ES 6モジュール1.ES 6モジュールの値は、【動的読取り専用参照】に属します.2.読み取り専用の場合、importの変数は、基本データ型でも複雑なデータ型でも読み取り専用です.モジュールがimportコマンドに遭遇すると、読み取り専用リファレンスが生成されます.スクリプトが本当に実行されるまで、この読み取り専用参照に基づいて、ロードされたモジュールに値を取ります.3.ダイナミックでは、元の値が変化し、importロードの値も変化します.基本データ型であれ複雑なデータ型であれ.4.循環ロードの場合、ES 6モジュールは動的参照である.2つのモジュールの間に参照がある限り、コードは実行できます.上にいくつかの重要な違いを述べた.いくつかの例を挙げて、それぞれの点を説明しましょう.
CommonJSは、基本データ型について、レプリケーションに属します.モジュールによってキャッシュされます.同時に、別のモジュールでは、モジュールが出力した変数を再割り当てできます.
// b.js
let count = 1
let plusCount = () => {
  count++
}
setTimeout(() => {
  console.log('b.js-1', count)
}, 1000)
module.exports = {
  count,
  plusCount
}

// a.js
let mod = require('./b.js')
console.log('a.js-1', mod.count)
mod.plusCount()
console.log('a.js-2', mod.count)
setTimeout(() => {
    mod.count = 3
    console.log('a.js-3', mod.count)
}, 2000)

node a.js
a.js-1 1
a.js-2 1
b.js-1 2  // 1  
a.js-3 3  // 2  

以上のコードから、bモジュールexportのcount変数は、レプリケーション動作であることがわかります.plusCountメソッド呼び出し後、aモジュール内のcountは影響を受けません.同時に、bモジュールでaモジュールの値を変更することができる.コードを同期させるには、exportでgetterを1つ出すことができます.
//       
module.exports = {
  get count () {
    return count
  },
  plusCount
}

node a.js
a.js-1 1
a.js-2 1
b.js-1 2  // 1  
a.js-3 2  // 2  ,       setter,          。      2`

1.複雑なデータ型の場合、浅いコピーです.2つのモジュールが参照するオブジェクトは同じメモリ領域を指すため、そのモジュールの値を変更すると別のモジュールに影響します.
// b.js
let obj = {
  count: 1
}
let plusCount = () => {
  obj.count++
}
setTimeout(() => {
  console.log('b.js-1', obj.count)
}, 1000)
setTimeout(() => {
  console.log('b.js-2', obj.count)
}, 3000)
module.exports = {
  obj,
  plusCount
}

// a.js
var mod = require('./b.js')
console.log('a.js-1', mod.obj.count)
mod.plusCount()
console.log('a.js-2', mod.obj.count)
setTimeout(() => {
  mod.obj.count = 3
  console.log('a.js-3', mod.obj.count)
}, 2000)

node a.js
a.js-1 1
a.js-2 2
b.js-1 2
a.js-3 3
b.js-2 3

2.以上のコードから分かるように、オブジェクトにとっては浅いコピーである.aモジュールを実行すると、まずobj.contの値を1に印刷し、plusCountメソッドで再度印刷すると2になります.次にaモジュールでcountの値を3に変更し,この場合bモジュールの値も3にする.
3.requireコマンドを使用してモジュールをロードすると、モジュール全体のコードが実行されます.
4.requireコマンドを使用して同じモジュールをロードすると、モジュールは実行されず、キャッシュ内の値が取得されます.つまり、CommonJSモジュールは、何度ロードしても、1回目のロード時に1回しか実行されず、後でロードすると、手動でシステムキャッシュをクリアしない限り、1回目の実行結果が返されます.
5.ループロードの場合、ロードに属する場合に実行します.すなわち,スクリプトコードはrequireの場合,すべて実行される.モジュールが「ループロード」されると、実行された部分のみが出力され、まだ実行されていない部分は出力されません.
3, 4, 5           

// b.js
exports.done = false
let a = require('./a.js')
console.log('b.js-1', a.done)
exports.done = true
console.log('b.js-2', '    ')

// a.js
exports.done = false
let b = require('./b.js')
console.log('a.js-1', b.done)
exports.done = true
console.log('a.js-2', '    ')

// c.js
let a = require('./a.js')
let b = require('./b.js')

console.log('c.js-1', '    ', a.done, b.done)

node c.js
b.js-1 false
b.js-2     
a.js-1 true
a.js-2     
c.js-1      true true

全体の過程を詳しく説明する.
1.ノード.jsでcモジュールを実行します.requireキーワードに遭遇し、a.jsのすべてのコードを実行します.2.aモジュールのexportsの後、requireによりbモジュールを導入し、bモジュールのコードを実行する.3.bモジュールのexportsの後、requireはaモジュールを導入し、このときaモジュールのコードを実行する.4.aモジュールはexports.done=falseという文のみを実行します.5.bモジュールに戻り、b.js-1、exports、b.js-2を印刷します.bモジュールの実行が完了しました.6.aモジュールに戻り、a.js-1、exports、b.js-2を印刷します.aモジュール実行完了7.cモジュールに戻り、次にrequireを実行し、bモジュールを導入する必要がある.aモジュールに導入されているので,直接値を出力することができる.8.終了.以上の結果と解析手順から,requireコマンドに遭遇すると対応するモジュールコードが実行されることが分かる.ループリファレンスの場合、モジュールコードの一部のみが出力される場合があります.同じモジュールを参照すると、再ロードするのではなくキャッシュが取得されます.
ES 6モジュール1.es 6モジュールの値は【動的読取り専用参照】に属する.複雑なデータ型のみ説明します.2.読み取り専用の場合、importの変数は、基本データ型でも複雑なデータ型でも読み取り専用です.モジュールがimportコマンドに遭遇すると、読み取り専用リファレンスが生成されます.スクリプトが本当に実行されるまで、この読み取り専用参照に基づいて、ロードされたモジュールに値を取ります.3.ダイナミックでは、元の値が変化し、importロードの値も変化します.基本データ型であれ複雑なデータ型であれ.
// b.js
export let counter = {
  count: 1
}
setTimeout(() => {
  console.log('b.js-1', counter.count)
}, 1000)

// a.js
import { counter } from './b.js'
counter = {}
console.log('a.js-1', counter)

// Syntax Error: "counter" is read-only

counterを新しいオブジェクトに再割り当てすることはできませんが、オブジェクトに属性とメソッドを追加できます.この時点ではエラーは発生しません.この動作タイプとキーワードconstの使い方.
// a.js
import { counter } from './b.js'
counter.count++
console.log(counter)

// 2

1.循環ロードの場合、ES 6モジュールは動的参照である.2つのモジュールの間に参照がある限り、コードは実行できます.
// b.js
import {foo} from './a.js';
export function bar() {
  console.log('bar');
  if (Math.random() > 0.5) {
    foo();
  }
}

// a.js
import {bar} from './b.js';
export function foo() {
  console.log('foo');
  bar();
  console.log('    ');
}
foo();

babel-node a.js
foo
bar
    

//          
foo
bar
foo
bar
    
    

両方のモジュールの間に参照があるためです.そのため、正常に実行できます.
以上です.ES 6 moduleとCommonJsmoduleについて知らない人は以下の文章を参考にしてください.
ES6 module
moduleの構文
moduleのロード実装