CommonJs
dalam artikel yang lepas Jika anda belum membacanya, anda boleh mencari ruangan di mana artikel ini berada untuk belajar. CommonJs
mempunyai banyak ciri yang sangat baik, mari kita semak secara ringkasnya di bawah: Kod modul hanya dijalankan selepas dimuatkan;
Modul hanya boleh dimuatkan sekali sahaja;
Modul boleh meminta untuk memuatkan modul lain;
Menyokong kebergantungan pekeliling;
Modul boleh mentakrifkan antara muka awam, dan modul lain boleh memerhati dan berinteraksi berdasarkan antara muka awam ini >
Es Module
Es module
dan Es Module
CommonJs
AMD
Lalai Dilaksanakan dalam mod ketat; tidak berkongsi ruang nama global; 🎜> ialah Es Module
(Skrip biasa ialah
. Perintah Es Module
Es Module
this
Penggunaan asas eksportundefined
window
var
window
Sudah tentu, anda juga boleh menulisnya seperti berikut Borang:
Es Module
mengeksport objek dan fungsi
exports
import
export
Eksport lalai perlu diambil perhatian bahawa modul hanya boleh mempunyai satu eksport lalai: import
export const nickname = "moment"; export const address = "广州"; export const age = 18;
const nickname = "moment"; const address = "广州"; const age = 18; export { nickname, address, age };
export function foo(x, y) { return x + y; } export const obj = { nickname: "moment", address: "广州", age: 18, }; // 也可以写成这样的方式 function foo(x, y) { return x + y; } const obj = { nickname: "moment", address: "广州", age: 18, }; export { foo, obj };
export
as
const address = "广州"; const age = 18; export { nickname as name, address as where, age as old };
export default "foo"; export default { name: 'moment' } export default function foo(x,y) { return x+y } export { bar, foo as default };
Assignment to constant variable
的类型错误。import
语句中同时取得它们。可以依次列出特定的标识符来取得,也可以使用 *
来取得:// foo.js export default function foo(x, y) { return x + y; } export const bar = 777; export const baz = "moment"; // main.js import { default as foo, bar, baz } from "./foo.js"; import foo, { bar, baz } from "./foo.js"; import foo, * as FOO from "./foo.js";
import
导入的模块是静态的,会使所有被导入的模块,在加载时就被编译(无法做到按需编译,降低首页加载速度)。有些场景中,你可能希望根据条件导入模块或者按需导入模块,这时你可以使用动态导入代替静态导入。import
可以像调用函数一样来动态的导入模块。以这种方式调用,将返回一个 promise
。import("./foo.js").then((module) => { const { default: foo, bar, baz } = module; console.log(foo); // [Function: foo] console.log(bar); // 777 console.log(baz); // moment});复制代码
await
必须在带有 async
的异步函数中使用,否则会报错:import("./foo.js").then((module) => { const { default: foo, bar, baz } = module; console.log(foo); // [Function: foo] console.log(bar); // 777 console.log(baz); // moment });
Top-level await
:const p = new Promise((resolve, reject) => { resolve(777); });const result = await p;console.log(result); // 777正常输出
import
是静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构。// 错误 import { 'b' + 'ar' } from './foo.js'; // 错误 let module = './foo.js'; import { bar } from module; // 错误 if (x === 1) { import { bar } from './foo.js'; } else { import { foo } from './foo.js'; }
type
属性设置为 module
用来告知浏览器将 script
标签视为模块。<script></script><script></script>
defer
的方式延迟你的 nomodule
脚本:<script> console.log("模块情况下的"); </script> <script></script> <script> console.log("正常 script标签"); </script>
nomodule
脚本会被执行多次,而模块只会被执行一次:<script></script> <script></script> <script></script> <script></script> <script></script>
nomodule
脚本会阻塞 HTML
解析。你可以通过添加 defer
属性来解决此问题,该属性是等到 HTML
解析完成之后才执行。defer
dan async
adalah atribut pilihan mereka hanya boleh memilih salah satu daripadanya Di bawah skrip nomodule
, defer
tidak akan menghuraikan skrip semasa sehingga HTML
dihuraikan, manakala <.> akan dihuraikan selari dengan async
dan tidak akan menyekat penghuraian HTML
Skrip modul boleh menentukan atribut HTML
, tetapi ia tidak sah untuk async
kerana modul ditangguhkan secara lalai. defer
async
Es Module
berbeza sepenuhnya daripada Es Module
mempunyai tiga mata yang berbeza sama sekali: Commonjs
CommonJS
mengeluarkan rujukan kepada nilai; modul dimuatkan pada masa jalan, Es Module
ialah antara muka output masa kompilasi. Modul CommonJS
Es Module
adalah untuk memuatkan modul secara serentak, dan perintah CommonJS
require()
import
Perbezaan kedua ialah kerana CommonJS
module.exports
Apa itu output ialah salinan nilai, maksudnya, apabila nilai dikeluarkan, perubahan dalam modul tidak akan menjejaskan nilai. Untuk butiran, sila lihat artikel sebelum ini. Es Module
Commonjs
. Es Module
ialah paip sambungan Jika nilai asal berubah, nilai yang dimuatkan oleh CommonJS
juga akan berubah dengan sewajarnya. Oleh itu, JS引擎
ialah rujukan dinamik dan nilai tidak akan dicache Pembolehubah dalam modul terikat pada modul di mana ia berada. import
import
import
Konsep berkaitan prinsip kerja Modul EsEs Module
Module Record
Realm
Environment
Namespace
dan memerlukan maklumat tambahan untuk dikaitkan dengan modul. HostDefined
Rekod Persekitaran Modulhost environments
import
Ikatan tidak berubah bermakna modul semasa memperkenalkan modul lain, dan pembolehubah yang diperkenalkan tidak boleh diubah suai Ini ialah pengikatan tidak berubah unik bagi modul. Construction
), cari fail js
mengikut alamat, muat turun melalui rangkaian, dan huraikan fail modul ke Module Record
;Instantiation
), instantiate modul, peruntukkan ruang memori, huraikan penyataan import dan eksport modul, dan halakan modul ke alamat memori yang sepadan; >), jalankan kod, Kira nilai dan isikan nilai ke dalam alamat memori; modul. Mula-mula kita mengubah suai fail masukan, yang biasanya merupakan tag Evaluation
loader
, dan terdapat pengecam pengisytiharan modul (HTML
) dalam <script type="module"></script>
pernyataan pengisytiharan, yang Beritahu import
Setiap nombor pengenalan modul sepadan dengan import
dan setiap ModuleSpecifier
termasuk loader
, , ,
. Di mana nilai模块记录(Module Record)
, 模块记录
, JavaScript代码
ialah jenis 执行上下文
. ImportEntries
LocalExportEntries
IndirectExportEntries
Rekod ImportEntryStarExportEntries
ImportEntries
ImportEntry Records
A LocalExportEntries
mengandungi tiga medan IndirectExportEntries
, StarExportEntries
, ExportEntry Records
;ImportEntry Records
ImportName: nama pengikatan yang diperlukan yang dieksport oleh modul dengan pengecam modul ModuleRequest
. Nilai ImportName
menunjukkan bahawa permintaan import adalah untuk objek ruang nama modul sasaran; >LocalName
ModuleSpecifier
yang diimport menggunakan ModuleRequest
namespace-object
ExportEntry Records
mengandungi empat medan ExportName
, ModuleRequest
, ImportName
, LocalName
, perbezaan daripada ImportEntry Records
ialah terdapat satu lagi ExportName
. Jadual berikut merekodkan contoh medan export
yang dieksport menggunakan ExportEntry Records
:
导出声明 | 导出名 | 模块标识符 | 导入名 | 本地名 |
---|---|---|---|---|
export var v; | "v" | null | null | "v" |
export default function f() {} | "default" | null | null | "f" |
export default function () {} | "default" | null | null | "default" |
export default 42; | "default" | null | null | "default" |
export {x}; | "x" | null | null | "x" |
export {v as x}; | "x" | null | null | "v" |
export {x} from "mod"; | "x" | "mod" | "x" | null |
export {v as x} from "mod"; | "x" | "mod" | "v" | null |
export * from "mod"; | null | "mod" | all-but-default | null |
export * as ns from "mod"; | "ns | "mod" | all | null |
Kembali ke topik
Hanya selepas menghuraikan semasa Module Record
boleh anda tahu submodul yang mana modul semasa bergantung, dan kemudian anda perlu resolve
Sub-modul, dapatkan sub-modul, kemudian huraikan sub-modul, teruskan kitaran proses ini menyelesaikan -> menguraikan -> >
Proses ini juga dipanggil
dan tidak menjalankan kod JavaScript Ia hanya mengenali kata kunci静态分析
tidak boleh. digunakan dalam skop bukan global , kecuali import dinamik. export
import
Bagaimana jika berbilang fail bergantung pada satu fail serentak? import
loader
sekali, dan akan ada Peta Modul bebas dalam setiap skop global. Module Map
MOdule Record
fetch
fasa pemautan pemautan
Module Record
untuk mengurus pembolehubah dalam Module Record
. Terdapat Module Record
dalam Module Environment Record
Module Record
Module Environment Record
dieksport pada modul Binding
, dan akan terdapat Module Record
dalam main.js
dalam count
Pada masa ini, ia bersamaan dengan fasa kompilasi Module Environment Record
, mewujudkan a objek contoh modul , tambahkan atribut dan kaedah yang sepadan, nilainya ialah Binding
atau count
pada masa ini, dan peruntukkan ruang memori untuknya. V8
undefined
menggunakan kata kunci null
dalam submodul count.js
import
dan main.js
's count.js
adalah konsisten, sekali gus menghubungkan hubungan antara modul ibu bapa dan anak. Seperti yang ditunjukkan dalam gambar di bawah:import
main.js
export
export
导出的为父模块,import
引入的为子模块,父模块可以对变量进行修改,具有读写权限,而子模块只有读权限。Es Module
中有5种状态,分别为 unlinked
、linking
、linked
、evaluating
和 evaluated
,用循环模块记录(Cyclic Module Records
)的 Status
字段来表示,正是通过这个字段来判断模块是否被执行过,每个模块只执行一次。这也是为什么会使用 Module Map
来进行全局缓存 Module Record
的原因了,如果一个模块的状态为 evaluated
,那么下次执行则会自动跳过,从而包装一个模块只会执行一次。 Es Module
采用 深度优先
的方法对模块图进行遍历,每个模块只执行一次,这也就避免了死循环的情况了。深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。这个算法会尽可能深地搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。
// main.js import { bar } from "./bar.js"; export const main = "main"; console.log("main"); // foo.js import { main } from "./main.js"; export const foo = "foo"; console.log("foo"); // bar.js import { foo } from "./foo.js"; export const bar = "bar"; console.log("bar");
node
运行 main.js
,得出以下结果:Atas ialah kandungan terperinci Satu artikel untuk memahami modularisasi es6 secara menyeluruh. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!