
本文详解如何在纯浏览器环境中(无构建工具)将 Node.js 风格的 module.exports 迁移为标准 ES 模块语法,解决 Cannot use import statement outside a module 和 module is not defined 等常见错误。
本文详解如何在纯浏览器环境中(无构建工具)将 node.js 风格的 `module.exports` 迁移为标准 es 模块语法,解决 `cannot use import statement outside a module` 和 `module is not defined` 等常见错误。
在浏览器中直接运行 JavaScript 时,Node.js 的 CommonJS 模块系统(如 module.exports / require())默认不可用——它仅在 Node.js 运行时环境中生效。你当前遇到的两个核心错误:
- Uncaught SyntaxError: Cannot use import statement outside a module
- Uncaught ReferenceError: module is not defined
正是由于混用了不兼容的模块语法:index.js 使用了 import,但未声明为模块;而 test.js 使用了仅 Node.js 支持的 module.exports,在浏览器中根本无法解析。
✅ 正确做法是统一采用原生浏览器支持的 ES 模块(ESM)标准:
1. 修改 test.js:使用 export default
// test.js —— 纯前端可用的 ES 模块 export default { white: "#fff", black: "#000" };
⚠️ 注意:
- 不要写 module.exports = {…} 或 exports.xxx = …;
- 不要使用 require();
- 文件扩展名保持 .js 即可(无需 .mjs,只要加载方式正确)。
2. 修改 index.js:使用标准 import 语法 + 相对路径
// index.js import style from './test.js'; // ✅ 必须带扩展名,且为相对路径(如 './test.js' 或 '../config/colors.js') console.log(style.white); // 输出 "#fff" const btn = document.getElementById("mybtn"); btn.addEventListener("click", () => { document.getElementById("show-alert").classList.remove("d-none"); });
3. 关键:HTML 中以 type=”module” 加载脚本
在 index.html 中,必须将 <script> 标签显式声明为模块</script>:
<!-- ✅ 正确:启用 ES 模块支持 --> <script type="module" src="index.js"></script> <!-- ❌ 错误:普通脚本无法解析 import --> <!-- <script src="index.js"></script> --> <!-- 同时移除旧的非模块化引用 --> <!-- <script type="module" src="test.js"></script> → 不需要单独引入,由 import 自动处理 -->
? 补充说明:
4. 完整修正后的 HTML 片段(精简版)
<!-- index.html --> <!DOCTYPE html> <html> <head> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"/> </head> <body> <div class="d-flex align-items-center justify-content-center" id="record"> <div class="input-group mb-3 input-group-lg w-50"> <input type="text" class="form-control" id="rec-id" placeholder="Enter ID"> <button class="btn btn-success" id="mybtn" type="button">Enter</button> </div> </div> <div class="d-flex align-items-center justify-content-center d-none" id="show-alert"> <div class="alert alert-danger alert-dismissible fade show"> <button type="button" class="btn-close" data-bs-dismiss="alert"></button> <strong>Danger!</strong> Button was clicked </div> </div> <!-- ✅ 唯一需要的脚本标签:声明为 module 并指向入口 --> <script type="module" src="index.js"></script> <!-- Bootstrap JS(需在 module 之前或之后均可,但注意依赖顺序) --> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"></script> </body> </html>
✅ 总结:三大必要条件
| 项目 | 正确写法 | 错误示例 |
|---|---|---|
| 导出语法 | export default { … } 或 export const white = “#fff”; | module.exports = { … } |
| 导入语法 | import style from ‘./test.js’;(路径含扩展名) | import style from ‘test’; 或 require(‘./test’) |
| HTML 加载 | <script type="module" src="index.js"></script> | <script src="index.js"></script> |
? 提示:若未来需支持更复杂的模块(如第三方 npm 包),建议引入轻量构建工具(如 Vite 或 esbuild),但对纯静态配置对象等简单场景,原生 ESM 已完全足够,零依赖、零配置、开箱即用。