Selamat siang teman!Saya mempersembahkan kepada Anda terjemahan artikel “Memahami (semua) format dan alat modul JavaScript” oleh Dixin.Saat membuat aplikasi, sering kali ada keinginan untuk membagi kode menjadi beberapa bagian, blok logis atau fungsional (modul). Namun, JavaScript pada awalnya tidak memiliki dukungan modul. Ini telah menyebabkan munculnya berbagai teknologi modular. Artikel ini membahas semua konsep dasar, templat, pustaka, sintaksis dan alat untuk bekerja dengan modul dalam JavaScript.Modul IIFE: Templat modul JS
Dengan mendefinisikan variabel dalam JS, kami mendefinisikannya sebagai variabel global. Ini berarti bahwa variabel tersebut akan tersedia di semua file JS yang dimuat di halaman saat ini:
let count = 0
const increase = () => ++count
const reset = () => {
count = 0
console.log(' .')
}
increase()
reset()
Untuk menghindari polusi namespace global, Anda dapat menggunakan fungsi anonim: (() => {
let count = 0
})
Voila, tidak ada lagi variabel global. Namun, kode di dalam fungsi tidak dieksekusi.IIFE: ekspresi fungsi langsung
Untuk menjalankan kode di dalam suatu fungsi f
, ia harus dipanggil menggunakan ()
cara f()
. Untuk menjalankan kode di dalam fungsi anonim (() => {})
juga harus digunakan ()
. Ini terlihat seperti ini (() => {})()
: (() => {
let count = 0
})()
Ini disebut IIFE (langsung disebut ekspresi fungsi). Modul dapat didefinisikan sebagai berikut:
const iifeCounterModule = (() => {
let count = 0
return {
increase: () => ++count,
reset: () => {
count = 0
console.log(' .')
}
}
})()
iifeCounterModule.increase()
iifeCounterModule.reset()
Kami membungkus kode modul dalam IIFE. Fungsi anonim mengembalikan objek. Ini menggantikan antarmuka ekspor. Hanya ada satu variabel global - nama modul (atau ruang namanya). Selanjutnya, nama modul dapat digunakan untuk menyebutnya (ekspor). Ini disebut templat modul JS.Kotoran impor
Saat mendefinisikan modul, beberapa dependensi mungkin diperlukan. Saat menggunakan template modular, setiap modul dependen adalah variabel global. Modul dependen dapat didefinisikan di dalam fungsi anonim atau diteruskan sebagai argumen:
const iifeCounterModule = ((dependencyModule1, dependencyModule2) => {
let count = 0
return {
increase: () => ++count,
reset: () => {
count = 0
console.log(' .')
}
}
})(dependencyModule1, dependencyModule2)
Versi sebelumnya dari pustaka populer seperti jQuery menggunakan templat ini (versi jQuery terbaru menggunakan modul UMD).Buka modul: buka templat modul JS
Template modul terbuka diciptakan oleh Christian Heilmann. Template ini juga IIFE, tetapi penekanannya adalah pada mendefinisikan semua antarmuka sebagai variabel lokal di dalam fungsi anonim:
const revealingCounterModule = (() => {
let count = 0
const increase = () => ++count
const reset = () => {
count = 0
console.log(' .')
}
return {
increase,
reset
}
})()
revealingCounterModule.increase()
revealingCounterModule.reset()
Sintaks ini membuatnya lebih mudah untuk memahami apa yang bertanggung jawab untuk masing-masing antarmuka (atau apa fungsinya).Modul CJS: Modul CommonJS atau modul Node.js
CommonJS, awalnya bernama ServerJS, adalah templat untuk mendefinisikan dan menggunakan modul. Itu dibangun ke Node.js. Secara default, setiap file JS adalah CJS. Variabel module
juga exports
menyediakan ekspor modul (file). Fungsi ini require
menyediakan memuat dan menggunakan modul. Kode berikut menunjukkan definisi modul penghitung dalam sintaks CommonJS:
const dependencyModule1 = require('./dependencyModule1')
const dependencyModule2 = require('./dependencyModule2')
let count = 0
const increase = () => ++count
const reset = () => {
count = 0
console.log(' .')
}
exports.increase = increase
exports.reset = reset
module.exports = {
increase,
reset
}
Begini cara modul ini digunakan:
const {
increase,
reset
} = require('./commonJSCounterModule')
increase()
reset()
const commonJSCounterModule = require('./commonJSCounterModule')
commonJSCounterModule.increase()
commonJSCounterModule.reset()
Dalam runtime Node.js (engine), templat ini digunakan dengan membungkus kode di dalam file ke dalam suatu fungsi, ke mana variabel exports, module
dan fungsi dilewatkan sebagai parameter require
:
(function(exports, require, module, __filename, __dirname) {
const dependencyModule1 = require('./dependencyModule1')
const dependencyModule2 = require('./dependencyModule2')
let count = 0
const increase = () => ++count
const reset = () => {
count = 0
console.log(' .')
}
module.exports = {
increase,
reset
}
return module.exports
}).call(thisValue, exports, require, module, filename, dirname)
(function(exports, require, module, __filename, __dirname) {
const commonJSCounterModule = require('./commonJSCounterModule')
commonJSCounterModule.increase()
commonJSCounterModule.reset()
}).call(thisValue, exports, require, module, filename, dirname)
Modul AMD atau modul RequireJS
AMD ( definisi modul asinkron ) adalah templat untuk mendefinisikan dan menggunakan modul. Ini digunakan di perpustakaan RequireJS . AMD berisi fungsi define
definisi modul yang menerima nama modul, nama dependensi, dan fungsi pabrik:
define('amdCounterModule', ['dependencyModule1', 'dependencyModule2'], (dependencyModule1, dependencyModule2) => {
let count = 0
const increase = () => ++count
const reset = () => {
count = 0
console.log(' .')
}
return {
increase,
reset
}
})
Ini juga berisi fungsi require
untuk menggunakan modul:
require(['amdCounterModule'], amdCounterModule => {
amdCounterModule.increase()
amdCounterModule.reset()
})
require
AMD berbeda dari require
CommonJS karena AMD mengambil nama modul dan modul itu sendiri sebagai argumen untuk fungsi tersebut.Pemuatan dinamis
Fungsi tersebut define
juga memiliki tujuan yang berbeda. Dibutuhkan fungsi callback dan meneruskan require
fungsi seperti CommonJS ke fungsi ini. Di dalam fungsi panggilan balik, mengharuskan dipanggil untuk memuat modul secara dinamis:
define(require => {
const dynamicDependencyModule1 = require('dependencyModule1')
const dynamicDependencyModule2 = require('dependencyModule2')
let count = 0
const increase = () => ++count
const reset = () => {
count = 0
console.log(' .')
}
return {
increase,
reset
}
})
Modul AMD dari modul CommonJS
Fungsi di atas define
, di samping itu require
, dapat mengambil variabel exports
dan sebagai argumen module
. Karenanya, define
kode dari CommonJS dapat dieksekusi di dalam :
define((require, exports, module) => {
const dependencyModule1 = require('dependencyModule1')
const dependencyModule2 = require('dependencyModule2')
let count = 0
const increase = () => ++count
const reset = () => {
count = 0
console.log(' .')
}
exports.increase = increase
exports.reset = reset
})
define(require => {
const counterModule = require('amdCounterModule')
counterModule.increase()
counterModule.reset()
})
Modul UMD: definisi modul universal atau modul UmdJS
UMD ( universal module definition ) - satu set templat untuk memastikan operasi modul dalam lingkungan runtime yang berbeda.UMD untuk AMD (RequireJS) dan browser
Kode berikut menyediakan modul dalam AMD (RequireJS) dan browser:
((root, factory) => {
if (typeof define === 'function' && define.amd) {
define('umdCounterModule', ['dependencyModule1', 'dependencyModule2'], factory)
} else {
root.umdCounterModule = factory(root.dependencyModule1, root.dependencyModule2)
}
})(typeof self !== undefined ? self : this, (dependencyModule1, dependencyModule2) => {
let count = 0
const increase = () => ++count
const reset = () => {
count = 0
console.log(' ')
}
return {
increase,
reset
}
})
Terlihat rumit, tapi itu hanya IIFE. Fungsi anonim menentukan apakah ada fungsi define
dari AMD / RequireJS.- Jika
define
terdeteksi, fungsi pabrik dipanggil melaluinya. - Jika
define
tidak ditemukan, fungsi pabrik dipanggil langsung. Pada titik ini, argumennya root
adalah objek Window browser. Ini menerima modul tergantung dari variabel global (properti dari objek Window). Ketika factory
modul kembali, itu juga menjadi variabel global (properti dari objek Window).
UMD untuk AMD (RequireJS) dan CommonJS (Node.js)
Kode berikut menyediakan modul dalam AMD (RequireJS) dan CommonJS (Node.js): (define => define((require, exports, module) => {
const dependencyModule1 = require("dependencyModule1")
const dependencyModule2 = require("dependencyModule2")
let count = 0
const increase = () => ++count
const reset = () => {
count = 0
console.log("Count is reset.")
}
module.export = {
increase,
reset
}
}))(
typeof module === 'object' && module.exports && typeof define !== 'function'
?
factory => module.exports = factory(require, exports, module)
:
define)
Jangan takut, itu hanya IIFE lagi. Ketika fungsi anonim dipanggil, argumennya "dievaluasi". Menilai argumen untuk menentukan lingkungan eksekusi (ditentukan oleh keberadaan variabel module
dan exports
CommonJS / Node.js, dan fungsi define
AMD / RequireJS).- Jika runtime adalah CommonJS / Node.js, argumen fungsi anonim secara manual membuat fungsi
define
. - Jika runtime adalah AMD / RequireJS, argumen ke fungsi anonim adalah fungsi
define
dari lingkungan itu. Melakukan fungsi anonim memastikan bahwa fungsi tersebut berfungsi define
. Di dalam fungsi anonim, fungsi dipanggil untuk membuat modul define
.
Modul ES: modul ECMAScript2015 atau ES6
Pada 2015, versi 6 dari spesifikasi JS memperkenalkan sintaksis modular baru. Ini disebut ECMAScript 2015 (ES2015) atau ECMAScript 6 (ES6). Dasar dari sintaks baru adalah kata kunci import
dan export
. Kode berikut menunjukkan penggunaan modul ES untuk impor / ekspor bernama dan default (default):
import dependencyModule1 from './dependencyModule1.mjs'
import dependencyModule2 from './dependencyModule2.mjs'
let count = 0
export const increase = () => ++count
export const reset = () => {
count = 0
console.log(' .')
}
export default {
increase,
reset
}
Untuk menggunakan file modul dalam browser, menambahkan tag <script>
dan mengidentifikasinya sebagai modul: <script type="module" src="esCounterModule.js"></script>
. Untuk menggunakan modul ini di Node.js, ubah ekstensinya menjadi .mjs
:
import {
increase,
reset
} from './esCounterModule.mjs'
increase()
reset()
import esCounterModule from './esCounterModule.mjs'
esCounterModule.increase()
esCounterModule.reset()
Untuk kompatibilitas mundur di browser, Anda dapat menambahkan tag <script>
dengan atribut nomodule
: <script nomodule>
lansiran ('Tidak didukung.')
</script>
Modul dinamis ES: Modul dinamis ECMAScript2020 atau ES11
Versi 11 terbaru dari spesifikasi JS 2020 memperkenalkan fungsi bawaan import
untuk penggunaan dinamis modul ES. Fungsi ini mengembalikan janji, sehingga Anda dapat menggunakan modul dengan then
:
import('./esCounterModule.js').then(({
increase,
reset
}) => {
increase()
reset()
})
import('./esCounterModule.js').then(dynamicESCounterModule => {
dynamicESCounterModule.increase()
dynamicESCounterModule.reset()
})
Karena fakta bahwa fungsi import
mengembalikan janji, ia dapat menggunakan kata kunci await
:
(async () => {
const {
increase,
reset
} = await import('./esCounterModule.js')
increase()
reset()
const dynamicESCounterModule = await import('./esCounterModule.js')
dynamicESCounterModule.increase()
dynamicESCounterModule.reset()
})
Modul Sistem: Modul SystemJS
SystemJS adalah pustaka untuk mendukung modul ES di browser lama. Misalnya, modul berikut ditulis menggunakan sintaks ES6:
import dependencyModule1 from "./dependencyModule1.js"
import dependencyModule2 from "./dependencyModule2.js"
dependencyModule1.api1()
dependencyModule2.api2()
let count = 0
export const increase = function() {
return ++count
}
export const reset = function() {
count = 0
console.log("Count is reset.")
}
export default {
increase,
reset
}
Kode ini tidak akan berfungsi di browser yang tidak mendukung sintaks ES6. Salah satu solusi untuk masalah ini adalah menerjemahkan kode menggunakan System.register
antarmuka perpustakaan SystemJS:
System.register(['./dependencyModule1', './dependencyModule2'], function(exports_1, context_1) {
'use strict'
var dependencyModule1_js_1, dependencyModule2_js_1, count, increase, reset
var __moduleName = context_1 && context_1.id
return {
setters: [
function(dependencyModule1_js_1_1) {
dependencyModule1_js_1 = dependencyModule1_js_1_1
},
function(dependencyModule2_js_1_1) {
dependencyModule2_js_1 = dependencyModule2_js_1_1
}
],
execute: function() {
dependencyModule1_js_1.default.api1()
dependencyModule2_js_1.default.api2()
count = 0
exports_1('increase', increase = function() {
return ++count
})
exports_1('reset', reset = function() {
count = 0
console.log(' .')
})
exports_1('default', {
increase,
reset
})
}
}
})
Sintaks ES6 modular baru hilang. Tetapi kode ini akan berfungsi dengan baik di browser lama. Transpilasi ini dapat dilakukan secara otomatis menggunakan Webpack, TypeScript, dll.Memuat modul dinamis
SystemJS juga berisi fungsi import
untuk impor dinamis:
System.import('./esCounterModule.js').then(dynamicESCounterModule => {
dynamicESCounterModule.increase()
dynamicESCounterModule.reset()
})
Modul Webpack: kompilasi dan perakitan modul CJS, AMD dan ES
Webpack adalah pembangun modul. Transpilernya menggabungkan modul CommonJS, AMD dan ES ke dalam template modular tunggal yang seimbang dan mengumpulkan semua kode ke dalam satu file. Misalnya, dalam 3 file berikut, 3 modul didefinisikan menggunakan sintaks yang berbeda:
define('amdDependencyModule1', () => {
const api1 = () => {}
return {
api1
}
})
const dependencyModule2 = require('./commonJSDependencyModule2')
const api2 = () => dependencyModule1.api1()
exports.api2 = api2
import dependencyModule1 from './amdDependencyModule1'
import dependencyModule2 from './commonJSDependencyModule2'
let count = 0
const increase = () => ++count
const reset = () => {
count = 0
console.log(' .')
}
export default {
increase,
reset
}
Kode berikut menunjukkan penggunaan modul ini:
import counterModule from './esCounterModule'
counterModule.increase()
counterModule.reset()
Webpack dapat menggabungkan file-file ini, meskipun faktanya mereka adalah sistem modular yang berbeda, menjadi satu file main.js
: akar
dist
main.js (kumpulan file yang terletak di folder src)
src
amdDependencyModule1.js
commonJSDependencyModule2.js
esCounterModule.js
index.js
webpack.config.js
Karena Webpack didasarkan pada Node.js, ia menggunakan sintaksis modular CommonJS. Dalam webpack.config.js
: const path = require('path')
module.exports = {
entry: './src/index.js',
mode: 'none',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
}
Untuk mengkompilasi dan membangun, Anda harus menjalankan perintah berikut: npm instal webpack webpack-cli --save-dev
npx webpack --config webpack.config.js
Akibatnya, Webpack akan membuat file main.js
. Kode berikut main.js
diformat untuk meningkatkan keterbacaan: (function(modules) {
var installedModules = {}
function require(moduleId) {
if (installedModules[moduleId]) {
return installedModules[moduleId].exports
}
var module = installedModules[moduleId] = {
i: moduleId,
l: false,
exports: {}
}
modules[moduleId].call(module.exports, module, module.exports, require)
module.l = true
return module.exports
}
require.m = modules
require.c = installedModules
require.d = function(exports, name, getter) {
if (!require.o(exports, name)) {
Object.defineProperty(exports, name, {
enumerable: true,
get: getter
})
}
}
require.r = function(exports) {
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, {
value: 'Module'
})
}
Object.defineProperty(exports, '__esModule', {
value: true
})
}
require.t = function(value, mode) {
if (mode & 1) value = require(value)
if (mode & 8) return value
if ((mode & 4) && typeof value === 'object' && value && value.__esModule) return value
var ns = Object.create(null)
require.r(ns)
Object.defineProperty(ns, 'default', {
enumerable: true,
value: value
})
if (mode & 2 && typeof value !== 'string')
for (var key in value) require.d(ns, key, function(key) {
return value[key]
}.bind(null, key))
return ns
}
require.n = function(module) {
var getter = module && module.__esModule ?
function getDefault() {
return module['default']
} :
function getModuleExports() {
return module
}
require.d(getter, 'a', getter)
return getter
}
require.o = function(object, property) {
return Object.prototype.hasOwnProperty.call(object, property)
}
require.p = ''
return require(require.s = 0)
})([
function(module, exports, require) {
'use strict'
require.r(exports)
var esCounterModule = require(1)
esCounterModule['default'].increase()
esCounterModule['default'].reset()
},
function(module, exports, require) {
'use strict'
require.r(exports)
var amdDependencyModule1 = require.n(require(2))
var commonJSDependencyModule2 = require.n(require(3))
amdDependencyModule1.a.api1()
commonJSDependencyModule2.a.api2()
let count = 0
const increase = () => ++count
const reset = () => {
count = 0
console.log(' .')
}
exports['default'] = {
increase,
reset
}
},
function(module, exports, require) {
var result!(result = (() => {
const api1 = () => {}
return {
api1
}
}).call(exports, require, exports, module),
result !== undefined && (module.exports = result))
},
function(module, exports, require) {
const dependencyModule1 = require(2)
const api2 = () => dependencyModule1.api1()
exports.api2 = api2
}
])
Dan lagi, ini hanya IIFE. Kode dari 4 file dikonversi menjadi 4 fungsi array. Dan array ini diteruskan ke fungsi anonim sebagai parameter.Modul Babel: transpilasi modul ES
Babel adalah transporter lain untuk mendukung kode ES6 + di browser lama. Modul ES6 + di atas dapat dikonversi ke modul Babel sebagai berikut:
Object.defineProperty(exports, '__esModule', {
value: true
})
exports['default'] = void 0
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
'default': obj
}
}
var dependencyModule1 = _interopRequireDefault(require('./amdDependencyModule1'))
var dependencyModule2 = _interopRequireDefault(require('./commonJSDependencyModule2'))
dependencyModule1['default'].api1()
dependencyModule2['default'].api2()
var count = 0
var increase = function() {
return ++count
}
var reset = function() {
count = 0
console.log(' .')
}
exports['default'] = {
increase: increase,
reset: reset
}
Dan ini adalah kodenya index.js
, yang menunjukkan penggunaan modul ini:
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
'default': obj
}
}
var esCounterModule = _interopRequireDefault(require('./esCounterModule.js'))
esCounterModule['default'].increase()
esCounterModule['default'].reset()
Ini adalah transpilasi default. Babel juga tahu cara bekerja dengan alat lain.Babel dan SystemJS
SystemJS dapat digunakan sebagai plugin untuk Babel: npm instal --save-dev @ babel / plugin-transform-modules-systemjs
Plugin ini harus ditambahkan ke babel.config.json
: {
'plugins': ['@ babel / plugin-transform-modules-systemjs'],
'preset': [
[
'@ babel / env',
{
'target': {
'ie': '11'
}
}
]
]
}
Sekarang Babel dapat bekerja dengan SystemJS untuk mentransformasikan modul CommonJS / Node.js, AMD / RequireJS dan ES: npx babel src --out-dir lib
Hasil: akar
Lib
amdDependencyModule1.js (dialihkan menggunakan SystemJS)
commonJSDependencyModule2.js (dialihkan menggunakan SystemJS)
esCounterModule.js (dialihkan menggunakan SystemJS)
index.js (dialihkan menggunakan SystemJS)
src
amdDependencyModule1.js
commonJSDependencyModule2.js
esCounterModule.js
index.js
babel.config.json
Seluruh sintaks modul AMD, CommonJS dan ES ditransformasikan ke dalam sintaksis SystemJS:
System.register([], function(_export, _context) {
'use strict'
return {
setters: [],
execute: function() {
define('amdDependencyModule1', () => {
const api1 = () => {}
return {
api1
}
})
}
}
})
System.register([], function(_export, _context) {
'use strict'
var dependencyModule1, api2
return {
setters: [],
execute: function() {
dependencyModule1 = require('./amdDependencyModule1')
api2 = () => dependencyModule1.api1()
exports.api2 = api2
}
}
})
System.register(['./amdDependencyModule1', './commonJSDependencyModule2'], function(_export, _context) {
var dependencyModule1, dependencyModule2, count, increase, reset
return {
setters: [function(_amdDependencyModule) {
dependencyModule1 = _amdDependencyModule.default
}, function(_commonJSDependencyModule) {
dependencyModule2 = _commonJSDependencyModule.default
}],
execute: function() {
dependencyModule1.api1()
dependencyModule1.api2()
count = 0
increase = () => ++count
reset = () => {
count = 0
console.log(' .')
}
_export('default', {
increase,
reset
})
}
}
})
System.register(['./esCounterModule'], function(_export, _context) {
var esCounterModule
return {
setters: [function(_esCounterModule) {
esCounterModule = _esCounterModule.default
}],
execute: function() {
esCounterModule.increase()
esCounterModule.reset()
}
}
})
Modul TypeScript: transpilasi modul CJS, AMD, ES dan SystemJS
TypeScript mendukung semua rasa sintaks JS, termasuk ES6. Selama transpilasi, sintaks modul ES6 dapat disimpan atau dikonversi ke format lain, termasuk CommonJS / Node.js, AMD / RequireJS, UMD / UmdJS atau SystemJS sesuai dengan pengaturan transpilasi di tsconfig.json
: {
'compilerOptions': {
'modul': 'ES2020' // Tidak ada, CommonJS, AMD, System,
UMD, ES6, ES2015, ESNext
}
}
Contohnya:
import dependencyModule from './dependencyModule'
dependencyModule.api()
let count = 0
export const increase = function() {
return ++count
}
var __importDefault = (this && this.__importDefault) || function(mod) {
return (mod && mod.__esModule) ? mod : {
'default': mod
}
}
exports.__esModule = true
var dependencyModule_1 = __importDefault(require('./dependencyModule'))
dependencyModule_1['default'].api()
var count = 0
exports.increase = function() {
return ++count
}
var __importDefault = (this && this.__importDefault) || function(mod) {
return (mod && mod.__esModule) ? mod : {
'default': mod
}
}
define(['require', 'exports', './dependencyModule'], function(require, exports, dependencyModule_1) {
'use strict'
exports.__esModule = true
dependencyModule_1 = __importDefault(dependencyModule_1)
dependencyModule_1['default'].api()
var count = 0
exports.increase = function() {
return ++count
}
})
var __importDefault = (this & this.__importDefault) || function(mod) {
return (mod && mod.__esModule) ? mod : {
'default': mod
}
}
(function(factory) {
if (typeof module === 'object' && typeof module.exports === 'object') {
var v = factory(require, exports)
if (v !== undefined) module.exports = v
} else if (typeof define === 'function' && define.amd) {
define(['require', 'exports', './dependencyModule'], factory)
}
})(function(require, exports) {
'use strict'
exports.__esModule = true
var dependencyModule_1 = __importDefault(require('./dependencyModule'))
dependencyModule_1['default'].api()
var count = 0
exports.increase = function() {
return ++count
}
})
System.register(['./dependencyModule'], function(exports_1, context_1) {
'use strict'
var dependencyModule_1, count, increase
car __moduleName = context_1 && context_1.id
return {
setters: [
function(dependencyModule_1_1) {
dependencyModule_1 = dependencyModule_1_1
}
],
execute: function() {
dependencyModule_1['default'].api()
count = 0
exports_1('increase', increase = function() {
return ++count
})
}
}
})
Sintaks ES modular yang didukung oleh TypeScript disebut modul eksternal.Modul Internal dan Namespace
TypeScript juga memiliki kata kunci module
dan namespace
. Mereka disebut modul internal: module Counter {
let count = 0
export const increase = () => ++count
export const reset = () => {
count = 0
console.log(' .')
}
}
namespace Counter {
let count = 0
export const increase = () => ++count
export const reset = () => {
count = 0
console.log(' .')
}
}
Keduanya ditransformasikan menjadi objek JS: var Counter;
(function(Counter) {
var count = 0
Counter.increase = function() {
return ++count
}
Counter.reset = function() => {
count = 0
console.log(' .')
}
})(Counter || (Counter = {}))
Modul dan namespace TypeScript dapat memiliki beberapa tingkat bersarang melalui pemisah .
: module Counter.Sub {
let count = 0
export const increase = () => ++count
}
namespace Counter.Sub {
let count = 0
export const increase = () => ++count
}
Sub modul dan sub namespace dipindahkan ke properti objek: var Counter;
(function(Counter) {
var Sub;
(function(Sub) {
var count = 0
Sub.increase = function() {
return ++count
}
})(Sub = Counter.Sub || (Counter.Sub = {}))
})(Counter || (Counter = {}))
Modul dan namespace TypeScript juga dapat digunakan dalam pernyataan export
: module Counter {
let count = 0
export module Sub {
export const increase = () => ++count
}
}
module Counter {
let count = 0
export namespace Sub {
export const increase = () => ++count
}
}
Kode di atas juga diterjemahkan ke dalam sub module dan sub namespace: var Counter;
(function(Counter) {
var count = 0
var Sub;
(function(Sub) {
Sub.increase = function() {
return ++count
}
})(Sub = Counter.Sub || (Counter.Sub = {}))
})(Counter || (Counter = {}))
Kesimpulan
Selamat datang di JS, yang memiliki 10+ sistem / format modulasi / namespaces:- Modul IIFE: Templat modul JS
- Buka modul: buka templat modul JS
- Modul CJS: Modul CommonJS atau modul Node.js
- Modul AMD: definisi modul asinkron atau modul RequireJS
- Modul UMD: definisi modul universal atau modul UmdJS
- Modul ES: modul ECMAScript2015 atau ES6
- Modul dinamis ES: Modul dinamis ECMAScript2020 atau ES11
- Modul Sistem: Modul SystemJS
- Modul Webpack: kompilasi dan perakitan modul CJS, AMD dan ES
- Modul Babel: transpilasi modul ES
- Modul TypeScript dan namespace
Untungnya, JS saat ini memiliki alat bawaan bawaan untuk bekerja dengan modul yang didukung oleh Node.js dan semua peramban modern. Untuk browser yang lebih lama, Anda dapat menggunakan sintaks ES modular baru, menerjemahkannya ke dalam sintaks yang kompatibel menggunakan Webpack / Babel / SystemJS / TypeScript.Terima kasih atas waktu Anda. Saya harap itu dihabiskan dengan baik.