javascript模块化是什么_ES6模块如何导入导出【教程】

9次阅读

javaScript模块化关键是正确使用es6 import/export:需script加type=”module”、路径带扩展名;命名/默认导出语法须匹配;动态import()返回promise用于按需加载;node中混用Commonjs需注意双模式限制和createrequire

javascript模块化是什么_ES6模块如何导入导出【教程】

javascript 模块化不是“要不要用”的问题,而是“怎么用对”的问题。ES6 模块(import/export)是当前标准方案,但直接在浏览器中运行、打包工具配置错误、循环依赖或动态路径写错,都会导致 Uncaught SyntaxError: Cannot use import statement outside a moduleModule not found

为什么 importhtml 里直接写会报错

浏览器默认把 当作传统脚本执行,不启用模块解析。必须显式声明类型:

  • HTML 中的 才启用 ES6 模块语法
  • type="module" 脚本自动启用严格模式、顶层 thisundefined、支持顶层 await
  • 模块路径必须是相对路径(如 ./utils.js)、绝对路径(/src/index.js)或完整 URL;不能省略扩展名(import { foo } from './utils' ❌)
  • 非模块脚本无法 import,模块脚本也无法被 (无 type="module")导入

export 的三种写法和对应 import 方式

导出方式决定导入语法,混用会导致绑定失败或 undefined

  • 命名导出(named export):可多次,必须用大括号 import { foo, bar } from './mod.js';重命名用 import { foo as myFoo } from './mod.js'
  • 默认导出(default export):每个模块最多一个,导入时名称任意:import anything from './mod.js'(无需大括号)
  • 混合导出:允许同时有 export default 和多个 export const x = ...;导入时需分开处理:import def, { named } from './mod.js'

注意:export { foo as default } 不等于 export default foo —— 前者是命名导出的别名,后者是真正的默认导出,动态 import() 返回对象结构不同。

动态 import() 解决什么问题

import() 是函数调用,返回 Promise,用于按需加载、条件加载或打破静态依赖图:

  • 避免首屏加载大模块:比如只在用户点击“编辑”按钮后 import('./editor.js')
  • 根据环境导入不同实现:const mod = await import(`./api/${API_ENV}.js`)(注意:路径不能是完全动态变量,需有静态前缀)
  • 绕过静态 import 的限制:可在函数内、if 块中、try/catch 里调用
  • 不触发 webpack工具的预打包——除非路径可静态分析,否则会单独生成 chunk

CommonJS 和 ES6 模块混用的坑

Node.js 14+ 支持双模式,但行为不一致:

  • require('./mod.mjs') 会报错,因为 .mjs 强制 ES 模块;import 无法直接加载 .cjs 或无 type: "module".js
  • exportsmodule.exports 在 ES 模块中不可用;反过来,import 不能在 CommonJS 文件中直接使用(除非用 Babel 或 Node 的 --experimental-modules
  • 第三方包若同时发布 exports 字段中的 importrequire 入口,要注意字段优先级(如 "import" > "require"

最稳妥的做法:项目统一用 type: "module" + .mjs 后缀,或全用构建工具(如 vite、webpack)接管解析逻辑。手动混用时,createRequire(import.meta.url) 是 Node 环境下从 ES 模块中调用 require 的唯一合规方式。

text=ZqhQzanResources