什么是javascript模块化开发【教程】

4次阅读

javaScript模块化是解决代码混乱的工程实践,强制功能分文件、限定暴露接口;用export/import而非全局变量可避免覆盖、依赖不清和tree-shaking失效;命名导出需解构导入,默认导出可重命名但每文件仅一个;浏览器ESM需type=”module”、带后缀路径、无别名;node.js中CommonJS与ESM不互通,需注意exports字段和__dirname替代方案;模块边界应按场景拆分而非盲目细化。

什么是javascript模块化开发【教程】

javascript模块化开发不是一种新语法糖,而是解决“代码越写越乱、改一处崩一片”的工程实践——它强制你把功能切分成有边界的文件,每个文件只暴露别人真正需要的东西。

为什么必须用 exportimport,而不是直接挂全局变量?

window.utils = {...} 看似简单,但会立刻引发三类问题:
• 其他脚本可能意外覆盖同名变量,比如两个库都定义了 log
• 无法知道谁依赖了谁,重构时不敢删函数;
• 打包工具没法做 tree-shaking(自动剔除没用的代码),最终 JS 包体积虚胖。

export 的两种写法,选错就埋坑

命名导出和默认导出行为完全不同,混用极易导致导入失败:

  • 命名导出(适合导出多个工具):export const add = (a, b) => a + b; → 必须用 import { add } from './math.js',名字错一个就 undefined
  • 默认导出(适合导出模块主入口):export default class ApiClient { ... } → 可用任意名导入:import Client from './api.js',但一个文件只能有一个 export default
  • 禁止这样写:export default function(){}; export const PI = 3.14; 虽然合法,但会让团队成员不确定该用哪种方式导入,typescript 类型推断也会变弱

浏览器里跑 import,三个硬性条件缺一不可

不是写了 import 就能运行,浏览器原生 ESM 有严格限制:

  • html 中引入入口脚本时必须加这个属性,否则报 Cannot use import statement outside a module
  • 路径必须带后缀:import { foo } from './utils.js'(不能写成 ./utils
  • 不能用相对路径别名:import { bar } from '@lib/config' 在浏览器中直接报 404,需靠 vite/webpack 等工具转译

Node.js 中模块系统更复杂,别想当然混用

node.js 同时支持 CommonJSrequire/module.exports)和 ESMimport/export),但二者不完全互通:

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

  • type: "module" 的项目里,require('./x') 直接报错;反过来,在 CommonJS 里 import 也不行
  • __dirname__filename 在 ESM 中不存在,要用 import.meta.url 配合 fileURLToPath()
  • 第三方包若同时提供 exports 字段(如 "exports": { ".": { "import": "./dist/index.mjs" } }),Node.js 才能正确选择 ESM 版本;否则可能加载到 CommonJS 版本导致 default 导入为 undefined

实际项目中,最常被忽略的是模块边界意识——不是“能拆就拆”,而是“谁该知道什么”。一个 utils 模块导出 20 个函数,远不如按场景拆成 dateUtils.jsstringUtils.js 并各自控制导出粒度来得可靠。

text=ZqhQzanResources