ARTICLE DETAIL

资讯详情

深耕网站SEO优化与搜索引擎排名提升的一线实战洞察。

模块化体系

模块化体系 1.7 模块化体系模块化是现代前端工程化的核心基石通过将代码拆分为独立、可复用的模块实现作用域隔离、依赖管理、按需加载与代码复用。ES6 推出的 ES ModulesESM是 JavaScript 官方标准化的模块化方案统一了早期 CommonJS、AMD 等多种社区规范是当前前端开发的标准模块化方式也是构建工具、框架生态的底层基础。1.7.1 ES Modulesimport /export 标准语法ES Modules 基于 import 和 export 关键字实现模块的导入与导出模块文件自动拥有独立作用域只有显式导出的成员才能被外部访问。一、export 导出语法导出分为命名导出和默认导出两种形式支持单个导出、批量导出、重命名导出与聚合导出。命名导出一个模块可以有多个命名导出导入时需与导出名严格对应。// 单个声明时直接导出 export const baseURL https://api.example.com; export function formatDate(date) { return date.toISOString().slice(0, 10); } export class User { constructor(name) { this.name name; } } // 声明后统一批量导出 const version 1.0.0; function log(msg) { console.log(msg); } export { version, log };重命名导出通过 as 关键字修改导出的对外名称。const innerFn () {}; export { innerFn as publicFn };默认导出一个模块只能有一个默认导出对应一个默认值适合导出单个核心成员如单个类、单个函数。// 导出函数 export default function add(a, b) { return a b; } // 导出对象 export default { name: utils, version: 1.0.0 };聚合导出中转导出在入口模块中统一转发其他模块的导出简化外部引用路径。// 转发所有命名导出 export * from ./utils.js; // 转发并重命名 export { default as DateUtil } from ./date.js;二、import 导入语法对应导出语法导入分为命名导入、默认导入、整体导入与重命名导入。命名导入使用花括号包裹导入名必须与导出名完全一致。import { baseURL, formatDate } from ./config.js; console.log(baseURL);重命名导入通过 as 修改导入后的变量名解决命名冲突问题。import { formatDate as format } from ./config.js;默认导入无需花括号可自定义导入名称。import add from ./add.js; console.log(add(1, 2));整体命名空间导入通过 * as 将模块所有命名导出挂载到一个对象上。import * as utils from ./utils.js; console.log(utils.version); utils.log(test);三、基础语法约束import / export 只能出现在模块顶层作用域不能嵌套在函数、条件语句等块级作用域中模块路径支持相对路径与绝对路径省略后缀时需构建工具支持导入的变量是只读引用不可在导入侧直接修改导出值1.7.2 动态 import () 按需加载静态 import 语法必须在模块顶层执行无法实现条件加载与按需加载。ES2020 引入的动态 import() 以函数形式调用返回一个 Promise 对象可在任意时机动态加载模块是性能优化的核心手段。一、基础语法import(modulePath) .then(module { // module 为模块导出对象 module.default(); }) .catch(err { console.error(模块加载失败, err); });配合 async/await 使用更简洁async function loadModule() { try { const utils await import(./utils.js); utils.doSomething(); } catch (err) { console.error(加载失败, err); } }二、典型应用场景条件加载根据运行环境、特性支持度按需加载模块if (!window.IntersectionObserver) { await import(./intersection-polyfill.js); }交互触发加载用户触发特定操作时再加载对应功能模块降低首屏体积// 点击按钮后再加载弹窗模块 modalBtn.addEventListener(click, async () { const Modal (await import(./Modal.js)).default; new Modal().show(); });路由懒加载单页应用中按路由拆分代码进入对应页面时才加载页面资源大依赖延迟加载体积较大的第三方库如图表、富文本编辑器在使用前再加载1.7.3 模块作用域与依赖机制ES Modules 拥有独立的作用域与明确的依赖执行规则从语法层面解决了全局变量污染、依赖顺序混乱等问题。一、模块作用域每个 ES Module 都拥有独立的私有作用域模块内声明的变量、函数、类默认仅在模块内部可见不会泄露到全局作用域只有通过 export 显式导出的成员才能被外部模块访问不同模块之间的同名变量不会互相冲突对比传统脚本文件多个普通 script 标签共享全局作用域容易出现变量覆盖、命名冲突模块文件天然隔离无需手动封装闭包。二、单例与引用机制单例执行同一个模块被多次导入时仅会在第一次导入时执行一次模块代码后续导入直接复用导出结果不会重复执行值的引用导入的是导出值的引用而非值的拷贝。若模块内部修改了导出的变量所有导入该模块的地方都会同步更新// counter.js export let count 0; export function increment() { count; } // a.js import { count, increment } from ./counter.js; increment(); console.log(count); // 1 // b.js import { count } from ./counter.js; console.log(count); // 1与 a.js 共享同一份引用三、依赖执行规则模块按照依赖树深度优先的顺序执行先执行当前模块的所有依赖模块再执行当前模块自身代码循环依赖场景下已执行的部分会正常导出未执行的部分为 undefined需避免复杂循环依赖四、默认严格模式所有 ES Module 自动运行在严格模式下无需手动声明 use strict因此模块内默认遵循严格模式的所有约束如禁止未声明变量赋值、禁止 with 语句等。
返回列表