ES6: Módulo de carregamento
Diferenças entre módulos ES6 e módulos CommonJS
- A saída do CommonJS é um valor de cópia de um valor e a saída do módulo ES6 é uma referência a um valor. Ou seja, alterar a saída do valor pelo módulo CommonJS não afetará o valor do próprio módulo, enquanto ES6 afetará o mesmo O valor de uma referência de módulo.
- CommonJS é carregado em tempo de execução e ES6 é a interface de saída em tempo de compilação.
O comando import carrega o módulo CommonJS
-
No ambiente Node, use o comando import para carregar o módulo CommonJS, e o Node tratará automaticamente a propriedade module.exports como a saída padrão do módulo, que é equivalente ao padrão de exportação.
// a.js module.exports = { foo : "hello" } // 等同于 module export { foo : "hello" } // 引入 import baz from './a'; import { default as baz} from './a'; // baz === { foo : "hello"};
- 如果采用整体输入的方法,default将会取代module.exports作为输入的接口
```js
import * as baz from './a';
// baz === {
// get default(){
// return module.exports;
// },
// get foo(){
// return {this.default.foo}.bind(baz);
// }
//}
- No exemplo acima, this.default substitui module.exports e não é difícil ver que a sintaxe de importação adicionará o atributo padrão a baz.
requer comando para carregar módulo ES6
-
Ao usar exigir para carregar um módulo ES6, todas as interfaces de saída do módulo ES6 se tornarão atributos do objeto de entrada
// a.js let foo = { bar : "hello" } export default foo; // b.js const amodule = require('./a.js'); // amodule.default === {bar : "hello"}
Carregamento cíclico
- O chamado carregamento cíclico significa que dois módulos se referem um ao outro, fazendo com que o programa seja executado recursivamente, e os dois módulos lidam com isso de maneiras diferentes.
Carregamento cíclico de CommonJS
-
Princípio de carregamento do módulo CommonJS: não importa quantas vezes um módulo cjs seja carregado, ele só será executado uma vez quando for carregado pela primeira vez, e todos os carregamentos subsequentes são os resultados retornados pela primeira vez, a menos que o cache seja limpo manualmente;
// a.js export.done = false; let b = require('./b'); console.log('在a.js中,b.done = %j',b.done); export done = true; console.log('在a.js中,b.done = %j',b.done); console.log('a.js执行完毕'); // b.js export.done = false; let a = require('./a'); console.log('在b.js中,a.done = %j',a.done); export done = true; console.log('在b.js中,a.done = %j',a.done); console.log('b.js执行完毕');
-
No código acima, a execução de a.js na segunda linha executará b.js, e a execução de b.js na segunda linha executará a.js, e o sistema irá automaticamente para a.js para encontrar o valor de exportação correspondente, mas a.js ainda não foi executado, portanto, apenas os valores que foram executados podem ser extraídos do valor de exportação.
// main.js var a = require('./a'); var b = require('./b'); console.log('在main.js中,a.done = %j,b.done = %j',a.done,b.done); // 输出 在b.js中,a.done = false; b.js执行完毕; 在a.js中,b.done = true; a.js执行完毕; 在main.js中,a.done = true,b.done = true;
-
O código acima prova que a execução do arquivo principal para a segunda linha não reexecutará b.js, mas retornará diretamente seu valor final.
Carregamento cíclico de módulos ES6
-
Como os módulos ES6 são referenciados dinamicamente, as variáveis não serão armazenadas em cache, mas apontam para o objeto referenciado.
// a.js import { bar} from "./b.js"; console.log("a.js"); console.log(bar); export let foo = 'foo'; // b.js import { foo} from "./a.js"; console.log("b.js"); console.log(foo); export let bar = "bar"; // 执行a.js b.js undefined a.js bar
-
O código acima, a.js, é executado, a primeira linha do código faz referência a b.js, então b.js é executado e a primeira linha de b.js é para introduzir a.js, porque a.js já está em execução, portanto, não será carregado novamente. Uma vez, undefined é gerado e executado normalmente.
Comparação dos dois modos
// a.js
import {
bar} from "./b.js"
export function foo(){
console.log('foo');
bar();
console.log('执行完毕');
}
foo();
// b.js
import {
foo} from "./a.js"
export function bar(){
console.log('bar');
if(Math.random() > 0.5){
foo();
}
}
- O trecho de código acima não pode ser executado sob o padrão CommonJS. a carrega b e, em seguida, b carrega a. Neste momento, a execução de a não está concluída, portanto, o resultado de saída será nulo, ou seja
null
, o valor de foo para b , portanto, não pode ser executado e ocorrerá um erro ser relatado; - No padrão ES6, como a importação cria uma referência a um objeto, quando a é carregado, a primeira linha de código cria uma
bar
referência a b.js e , quando é executada na quarta linha de código, pula para b.js Execute ebar()
, em seguida, execute o console da próxima linha de código.