什么是模块化以及如何用javascript实现它?【教程】

10次阅读

模块化是组织代码的思路而非语法特性,解决变量污染、依赖混乱和复用困难;Commonjs 同步执行、适合服务端,ES Modules 静态解析、支持 tree-shaking,二者在环境、语法和加载机制上存在根本差异。

什么是模块化以及如何用javascript实现它?【教程】

模块化不是一种语法特性,而是组织代码的思路——它解决的是变量污染、依赖混乱和复用困难这三个实际问题。javaScript 本身没有“模块”这个运行时概念,所有模块方案都是构建时或规范层面的约定。

CommonJS 是 node.js 默认的模块系统

它用 require() 加载,module.exportsexports 导出,同步执行,天然适合服务端。

  • require() 每次调用都会缓存结果,重复引入不会重复执行模块代码
  • exportsmodule.exports 的引用,直接赋值 exports = {...} 会断开连接,必须用 module.exports = {...}
  • 不能在条件语句里动态 require(),否则打包工具(如 webpack)无法静态分析依赖

ES Modules(ESM)是浏览器和现代 Node 的标准模块语法

它用 import/export,静态编译期解析,支持 tree-shaking,但不支持运行时加载路径变量。

  • import 必须写在顶层作用域,不能放在 if 或函数里(除非用 import() 动态导入)
  • export default 只能有一个,命名导出可多个;对应 import x fromimport { a, b } from
  • Node 中启用 ESM 需满足任一条件:.mjs 后缀、package.json 中设置 "type": "module"、或命令行加 --experimental-modules(旧版本)

浏览器中直接使用 ESM 要注意路径和 MIME 类型

html 中通过 加载,此时路径必须是相对或绝对 URL,不能是纯模块名(如 lodash)。

立即学习Java免费学习笔记(深入)”;

  • 本地文件协议(file://)下,ESM 会因 CORS 被拒,必须起一个本地服务(如 npx serve
  • 导入路径末尾不能省略扩展名(./utils.js 可,./utils 不可),除非服务器配置了自动映射
  • 动态导入 import('./foo.js') 返回 promise,可用于按需加载、条件加载或错误降级

真正难的不是写 exportimport,而是搞清当前环境(Node 版本、打包工具、是否启用实验特性)到底走哪条模块解析逻辑——同一份代码,在 node -r esmts-nodevite 和 Webpack 下行为可能完全不同。

text=ZqhQzanResources