如何让list.js同时兼容前端非模块加载与Node.js模块导入?
问题
现有一个名为list.js的JS文件,内容如下:
let users = [{firstname: 'Paul', lastname:'smith'}];
该文件在客户端通过以下代码加载:
<script src="/js/list.js"></script>
同时需要在Node.js模块中加载该文件,且必须使用import(无法用require):
import { users } from '../public/js/list.js';
但如果给变量添加export语句,文件就无法在客户端正常加载:
export var users = [{firstname: 'Paul', lastname:'smith'}];
补充说明:
如果在list.js中使用CommonJS导出:
module.exports = [{firstname: 'Paul', lastname:'smith'}];
在Node.js中用require加载时:
const { users } = require('../public/js/list.js');
这种方式无效。另外,export语句不能放在条件判断中,比如:
if (true) export default testList;
会触发语法错误:
if (true) export default users; ^^^^^^ SyntaxError: Unexpected token 'export'
解决方案
这里提供几种让list.js同时支持客户端全局加载和Node.js ES模块导入的实用方法:
方法1:使用UMD(通用模块定义)模式
这是兼容多种模块规范的经典方案,能同时适配客户端全局、CommonJS和ES模块:
(function (global, factory) { if (typeof module === 'object' && typeof module.exports === 'object') { // Node.js 环境,支持CommonJS或ES模块 module.exports = factory(); } else if (typeof define === 'function' && define.amd) { // AMD模块环境(比如RequireJS) define(factory); } else { // 客户端全局环境,挂载到window上 global.users = factory(); } }(typeof window !== 'undefined' ? window : this, function () { return [{firstname: 'Paul', lastname:'smith'}]; }));
- 客户端加载后,直接通过
window.users访问数据; - Node.js中可使用
import users from '../public/js/list.js'(默认导出)或const users = require('../public/js/list.js')加载。
方法2:结合全局挂载与多环境导出
通过判断运行环境,分别给客户端暴露全局变量、给Node.js模块导出变量,避开export不能放在条件判断的限制:
const users = [{firstname: 'Paul', lastname:'smith'}]; // 客户端环境:挂载到window全局 if (typeof window !== 'undefined') { window.users = users; } // Node.js CommonJS环境导出 if (typeof module !== 'undefined' && module.exports) { module.exports = { users }; } // Node.js ES模块环境导出(顶层语句,符合语法要求) export { users };
- 客户端加载后直接用
users访问数据; - Node.js中用
import { users } from '../public/js/list.js'即可正常导入。
方法3:将客户端加载改为ES模块模式
如果你的客户端环境支持ES模块(现代浏览器基本都支持),可以直接修改客户端的script标签:
<script type="module" src="/js/list.js"></script>
然后list.js直接用ES模块导出,同时可选挂载全局:
export const users = [{firstname: 'Paul', lastname:'smith'}]; // 可选:如果需要在客户端全局访问 if (typeof window !== 'undefined') { window.users = users; }
- 客户端中可在其他模块里用
import { users } from '/js/list.js'导入,也能直接通过全局users访问; - Node.js中直接用
import { users } from '../public/js/list.js'导入。
内容的提问来源于stack exchange,提问作者Fifi
相关产品推荐
相关产品推荐

