javascript模块化开发怎样进行【教程】

JavaScript模块化需按环境选系统并正确配置:ESM为现代标准,浏览器中需type="module"且路径带扩展名,Node.js需package.json设"type":"module";CJS仅限Node.js,浏览器需打包器转换;动态import()跨环境兼容但须try/catch。

JavaScript 模块化开发不是“选一种写法就完事”,而是根据运行环境(浏览器 / Node.js)、构建工具(Vite / Webpack / 无构建)和目标兼容性,选择匹配的模块系统并正确配置加载方式。

ESM 是现代浏览器和 Node.js 的默认标准,但 import 不能直接在普通 script 中用

你在 HTML 里写 会报 Uncaught SyntaxError: Cannot use import statement outside a module。必须显式声明为模块:

  • 或外部脚本:
  • 此时 import 路径必须带扩展名(如 ./utils.js),不能写 ./utils
  • 模块脚本自动启用严格模式,且顶层 thisundefined

Node.js 里 ESM 需要明确标识,package.json"type": "module" 很关键

不加这个字段,即使文件后缀是 .mjs 或用 node --experimental-modules 启动,也会因依赖的第三方包是 CommonJS 而出错(比如 require is not definedCannot mix named and default exports):

  • 项目根目录 packag

    e.json
    "type": "module",所有 .js 文件按 ESM 解析
  • 若想混用 CJS(例如某些老库只能 require),可用 .cjs 后缀,或在 package.json 中对子路径单独设 "exports"
  • 动态导入用 await import('./foo.js'),返回 Promise,可在 CJS 文件中安全调用

CommonJS 在 Node.js 里仍广泛存在,但浏览器中必须靠打包器才能用

const fs = require('fs') 这种写法,在浏览器里根本不存在 require 函数。直接运行会报 require is not defined

  • Vite / Webpack / Rollup 等工具会在构建时把 require 转成 ESM 的 import 或内联逻辑
  • 纯前端项目尽量避免写 require,除非你确定只走打包流程且不打算用原生 ESM 调试
  • 注意 module.exports = {}export default {} 不等价:前者在 ESM 中会被包装成 { default: {} },解构需写 import mod from 'x',而非 import { x } from 'x'

动态 import() 是跨环境的兼容方案,但要注意加载时机和错误处理

它不依赖模块类型,CJS、ESM、浏览器、Node.js 全支持,常用于路由懒加载或条件加载:

  • const mod = await import('./math.js') 返回命名空间对象,mod.sum;若导出是 export default,则用 mod.default
  • 路径可以是变量或表达式:import(`./locales/${lang}.js`),但 Webpack/Vite 会静态分析,只打包匹配的文件
  • 务必 try/catch:网络失败、路径错误、语法错误都会让 import() 拒绝 Promise,不捕获会导致白屏或静默失败

真正卡住人的往往不是语法,而是模块解析规则——比如 ESM 的路径必须完整、Node.js 的 "exports" 字段优先级高于 "main"、Vite 开发服务器对裸模块(import React from 'react')的自动重写机制。这些细节不查文档,光看 import 示例很容易跑不通。