ES6 模块系统为 JavaScript 提供了强大的代码组织和重用能力。
// math.js
export const PI = 3.14159
export function add(a, b) {
return a + b
}
export function multiply(a, b) {
return a * b
}
export class Calculator {
static add(a, b) {
return a + b
}
}
// 默认导出
export default function subtract(a, b) {
return a - b
}
// 重命名导出
export { add as sum, multiply as product }// main.js
import { add, multiply, PI } from './math.js'
import subtract from './math.js'
import { sum, product } from './math.js'
import * as MathModule from './math.js'
console.log(add(2, 3)) // 5
console.log(multiply(4, 5)) // 20
console.log(PI) // 3.14159
console.log(subtract(10, 3)) // 7
console.log(sum(1, 2)) // 3
console.log(MathModule.add(2, 3)) // 5// 条件导入
if (condition) {
import('./module.js').then(module => {
// 使用模块
})
}
// 异步函数中的导入
async function loadModule() {
const module = await import('./module.js')
return module
}
// 按需加载
const button = document.getElementById('loadButton')
button.addEventListener('click', async () => {
const { heavyFunction } = await import('./heavy-module.js')
heavyFunction()
})// 立即执行函数表达式 (IIFE)
const Module = (function() {
let privateVariable = 'secret'
function privateFunction() {
console.log('This is private')
}
return {
publicVariable: 'public',
publicFunction() {
privateFunction()
return privateVariable
}
}
})()
console.log(Module.publicVariable) // 'public'
Module.publicFunction() // 'This is private' and returns 'secret'// utils.js
let privateCounter = 0
export function increment() {
privateCounter++
return privateCounter
}
export function getCounter() {
return privateCounter
}
// main.js
import { increment, getCounter } from './utils.js'
console.log(getCounter()) // 0
increment()
increment()
console.log(getCounter()) // 2class ModuleLoader {
constructor() {
this.modules = new Map()
this.loading = new Map()
}
async loadModule(name) {
if (this.modules.has(name)) {
return this.modules.get(name)
}
if (this.loading.has(name)) {
return this.loading.get(name)
}
const loadPromise = this._loadModule(name)
this.loading.set(name, loadPromise)
try {
const module = await loadPromise
this.modules.set(name, module)
this.loading.delete(name)
return module
} catch (error) {
this.loading.delete(name)
throw error
}
}
async _loadModule(name) {
// 模拟异步加载
const response = await fetch(`/modules/${name}.js`)
const code = await response.text()
// 创建模块作用域
const module = { exports: {} }
const require = (dep) => this.loadModule(dep)
// 执行代码
const wrapper = new Function('module', 'exports', 'require', code)
wrapper(module, module.exports, require)
return module.exports
}
}
// 使用加载器
const loader = new ModuleLoader()
async function main() {
const math = await loader.loadModule('math')
console.log(math.add(2, 3))
}
main()class ModuleBundler {
constructor() {
this.modules = new Map()
this.bundle = ''
}
addModule(name, code, dependencies = []) {
this.modules.set(name, { code, dependencies })
}
generateBundle(entryModule) {
const processed = new Set()
const ordered = []
function processModule(name) {
if (processed.has(name)) return
processed.add(name)
const module = this.modules.get(name)
if (!module) throw new Error(`Module ${name} not found`)
// 处理依赖
for (let dep of module.dependencies) {
processModule.call(this, dep)
}
ordered.push(name)
}
processModule.call(this, entryModule)
// 生成打包代码
this.bundle = `
(function(modules) {
const cache = {}
function require(name) {
if (cache[name]) return cache[name]
const module = { exports: {} }
modules[name](module, module.exports, require)
cache[name] = module.exports
return module.exports
}
require('${entryModule}')
})({
${ordered.map(name => {
const module = this.modules.get(name)
return ` '${name}': function(module, exports, require) {
${module.code}
}`
}).join(',\n')}
})
`
return this.bundle
}
}
// 使用打包器
const bundler = new ModuleBundler()
bundler.addModule('math', `
exports.add = function(a, b) { return a + b }
exports.multiply = function(a, b) { return a * b }
`)
bundler.addModule('app', `
const math = require('math')
console.log('2 + 3 =', math.add(2, 3))
console.log('4 * 5 =', math.multiply(4, 5))
`, ['math'])
const bundle = bundler.generateBundle('app')
console.log(bundle)ES6 模块系统为 JavaScript 带来了现代化的代码组织方式:
模块化开发提高了代码的可维护性和重用性。