Node.js v20中jquery.js的module变量来源及index.js无此变量的原因
jQuery中
module变量的疑问解答 三个核心问题的答案
1. module变量是什么?
module是Node.js CommonJS模块体系里的内置对象,每个被当作CommonJS模块加载的文件,都会自动拥有这个变量。它包含当前模块的基本信息(比如文件路径、ID),最关键的是module.exports属性——用来定义模块对外导出的内容。你在jQuery里打印的结果也能看到,它记录了模块的路径、导出对象等细节。
2. 它由谁创建?
完全是Node.js运行时自动生成并注入到模块执行环境里的,不需要开发者手动定义。只要Node.js把某个文件当作CommonJS模块处理,就会自动加上这个变量。
3. 为什么jQuery里有,你的index.js里没有?
核心原因是两个文件的模块类型不一样:
- 你的
index.js是ES模块:因为项目根目录的package.json设置了"type": "module",Node.js会把项目里所有.js文件默认当成ES模块。ES模块体系里没有module、require这些CommonJS特有的内置变量,所以你直接访问module会抛出引用错误。 - jQuery的
jquery.js被当作CommonJS模块加载:jQuery的代码是跨环境兼容的(支持浏览器、CommonJS、AMD),而且它在你的node_modules目录下,不会继承你项目里的"type": "module"设置。Node.js加载它的时候,会默认按CommonJS模块处理,所以自动注入了module变量。
你的代码片段
index.js
/* eslint-disable no-unused-vars */ export {} globalThis.window = {}; globalThis.document = {}; console.log(`globalThis.module`, globalThis.module); // undefined console.log(`global.module`, global.module); // undefined console.log(`window.module`, window.module); // undefined try { console.log(`module`, module); } catch (ex) { console.log(ex); // ReferenceError: module is not defined } const dynamicImport = await import('jquery');
修改后的node_modules/jquery/dist/jquery.js
/*! * jQuery JavaScript Library v3.7.1 * https://jquery.com/ * * Copyright OpenJS Foundation and other contributors * Released under the MIT license * https://jquery.org/license * * Date: 2023-08-28T13:37Z */ ( function( global, factory ) { "use strict"; // logs added by me console.log(`globalThis.module`, globalThis.module); // undefined console.log(`global.module`, global.module); // undefined console.log(`window.module`, window.module); // undefined console.log(`module`, module); /* module { id: 'projA\\node_modules\\jquery\\dist\\jquery.js', path: 'projA\\node_modules\\jquery\\dist', exports: {}, filename: 'projA\\node_modules\\jquery\\dist\\jquery.js', loaded: false, children: [], paths: [ 'projA\\node_modules\\jquery\\dist\\node_modules', 'projA\\node_modules\\jquery\\node_modules', 'projA\\node_modules', 'projAParent\\node_modules', 'projAGrandparent\\node_modules' ] } */ console.log('typeof module === "object"', typeof module === "object"); console.log(`typeof module.exports === "object"`, typeof module.exports === "object"); if ( typeof module === "object" && typeof module.exports === "object" ) { module.exports = global.document ? factory( global, true ) : function( w ) { if ( !w.document ) { throw new Error( "jQuery requires a window with a document" ); } return factory( w ); }; } else { factory( global ); } } )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { "use strict"; // everything else deleted by me return jQuery; } );
package.json
{ // ... "main": "index.js", "type": "module", "scripts": { "test": "npm run exec && jasmine", "exec": "node index.js" }, "devDependencies": { "@types/jasmine": "^5.1.1", "@types/jquery": "^3.5.25", "@types/jsdom": "^21.1.4", "eslint": "^8.52.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-prettier": "^5.0.0", "jasmine": "^5.1.0" }, "dependencies": { "@prettier/sync": "^0.3.0", "jquery": "^3.7.1", "jsdom": "^22.1.0", "prettier": "^3.0.3" } }
内容的提问来源于stack exchange,提问作者Daniel Kaplan
相关产品推荐
相关产品推荐

