修复本地Node.js低版本报错,修复不能在web中设置证书验证为0 (#106)
* 修复兼容层不支持动态导入 * 修复不能在web中设置证书验证为0 * 使用更严谨的正则和注入 * 使用更安全的注入
This commit is contained in:
1 parent
995d5f10e0
commit
c7afee82e1
2 files changed
+72
-31
No files matched your search
@@ -243,7 +243,7 @@ export class Envs {
|
||||
'DEPLOY_PLATFROM_ACCOUNT': { category: 'system', type: 'text', description: '部署平台账号ID' },
|
||||
'DEPLOY_PLATFROM_PROJECT': { category: 'system', type: 'text', description: '部署平台项目名称' },
|
||||
'DEPLOY_PLATFROM_TOKEN': { category: 'system', type: 'text', description: '部署平台访问令牌' },
|
||||
'NODE_TLS_REJECT_UNAUTHORIZED': { category: 'system', type: 'number', description: '在建立 HTTPS 连接时是否验证服务器的 SSL/TLS 证书,0表示忽略' },
|
||||
'NODE_TLS_REJECT_UNAUTHORIZED': { category: 'system', type: 'number', description: '在建立 HTTPS 连接时是否验证服务器的 SSL/TLS 证书,0表示忽略,默认为1', min: 0, max: 1 },
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
+71
-30
@@ -97,32 +97,7 @@ try {
|
||||
throw err;
|
||||
}
|
||||
|
||||
// ------------------- _compile hook -------------------
|
||||
const origCompile = Module.prototype._compile;
|
||||
Module.prototype._compile = function (content, filename) {
|
||||
try {
|
||||
if (
|
||||
typeof filename === 'string' &&
|
||||
filename.startsWith(projectRoot) &&
|
||||
!filename.includes('node_modules') &&
|
||||
/\b(?:import|export)\b/.test(content)
|
||||
) {
|
||||
console.log(`[esm-shim] Transforming ESM syntax in: ${path.relative(projectRoot, filename)}`);
|
||||
const out = esbuild.transformSync(content, {
|
||||
loader: 'js',
|
||||
format: 'cjs',
|
||||
target: 'es2018',
|
||||
sourcemap: 'inline',
|
||||
});
|
||||
return origCompile.call(this, out.code, filename);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[esm-shim] esbuild transform failed:', filename, e.message || e);
|
||||
}
|
||||
return origCompile.call(this, content, filename);
|
||||
};
|
||||
|
||||
// ------------------- _load hook for node-fetch v3 -------------------
|
||||
// =============== node-fetch v3 兼容层 ===============
|
||||
let fetchCache = null;
|
||||
let fetchPromise = null;
|
||||
|
||||
@@ -199,7 +174,42 @@ function createFetchCompat() {
|
||||
return syncFetch;
|
||||
}
|
||||
|
||||
// 拦截 node-fetch 的 require 调用
|
||||
// =============== 处理动态导入 ===============
|
||||
// 将动态 import() 转换为 require(),并修复 import.meta.url
|
||||
function preprocessESMFeatures(content, filename) {
|
||||
let modified = content;
|
||||
|
||||
// 修复 1: 动态 import() - 统一处理所有模式
|
||||
// 匹配: import(...) 不管有没有 await,不管是字符串还是表达式
|
||||
modified = modified.replace(
|
||||
/(await\s+)?import\s*\(((?:[^()]|\([^)]*\))*)\)/g,
|
||||
(match, awaitKeyword, importArg) => {
|
||||
console.log(`[esm-shim] Converting dynamic import in ${path.basename(filename)}`);
|
||||
// 如果有 await,保持 await;如果没有,也不加
|
||||
return `${awaitKeyword || ''}Promise.resolve(require(${importArg}))`;
|
||||
}
|
||||
);
|
||||
|
||||
// 修复 2: import.meta.url
|
||||
if (content.includes('import.meta.url')) {
|
||||
// 检查是否已经处理过
|
||||
if (content.includes('__importMetaUrl')) {
|
||||
console.log(`[esm-shim] __importMetaUrl already exists in ${path.basename(filename)}, skipping injection`);
|
||||
// 只做替换,不注入
|
||||
modified = modified.replace(/import\.meta\.url/g, '__importMetaUrl');
|
||||
} else {
|
||||
console.log(`[esm-shim] Fixing import.meta.url in ${path.basename(filename)}`);
|
||||
// 注入 + 替换
|
||||
const metaUrlFix = `const __importMetaUrl = require('url').pathToFileURL(__filename).href;\n`;
|
||||
modified = metaUrlFix + modified;
|
||||
modified = modified.replace(/import\.meta\.url/g, '__importMetaUrl');
|
||||
}
|
||||
}
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
// =============== Module Hooks ===============
|
||||
const origLoad = Module._load;
|
||||
Module._load = function (request, parent, isMain) {
|
||||
if (request === 'node-fetch') {
|
||||
@@ -212,7 +222,38 @@ Module._load = function (request, parent, isMain) {
|
||||
return origLoad.call(this, request, parent, isMain);
|
||||
};
|
||||
|
||||
// 导出加载函数
|
||||
global.loadNodeFetch = loadNodeFetchV3;
|
||||
const origCompile = Module.prototype._compile;
|
||||
Module.prototype._compile = function (content, filename) {
|
||||
try {
|
||||
if (
|
||||
typeof filename === 'string' &&
|
||||
filename.startsWith(projectRoot) &&
|
||||
!filename.includes('node_modules') &&
|
||||
/\b(?:import|export)\b/.test(content)
|
||||
) {
|
||||
console.log(`[esm-shim] Transforming ESM syntax in: ${path.relative(projectRoot, filename)}`);
|
||||
|
||||
// 预处理 ESM 特性
|
||||
const preprocessed = preprocessESMFeatures(content, filename);
|
||||
|
||||
// esbuild 转换
|
||||
const out = esbuild.transformSync(preprocessed, {
|
||||
loader: 'js',
|
||||
format: 'cjs',
|
||||
target: 'es2018',
|
||||
sourcemap: 'inline',
|
||||
});
|
||||
|
||||
// 确保 exports 同步(简化版)
|
||||
const fixedCode = out.code + `\n;(function(){if(exports!==module.exports&&typeof exports==='object'){Object.keys(exports).forEach(k=>{if(k!=='__esModule'&&!(k in module.exports))module.exports[k]=exports[k]})};if(typeof module.exports==='object'&&Object.keys(module.exports).length===0){Object.keys(exports).forEach(k=>{if(k!=='__esModule')module.exports[k]=exports[k]})}})();`;
|
||||
|
||||
return origCompile.call(this, fixedCode, filename);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[esm-shim] esbuild transform failed:', filename, e.message || e);
|
||||
}
|
||||
return origCompile.call(this, content, filename);
|
||||
};
|
||||
|
||||
console.log('[esm-shim] ESM compatibility shim active with hooks installed');
|
||||
global.loadNodeFetch = loadNodeFetchV3;
|
||||
console.log('[esm-shim] ESM compatibility shim active with hooks installed');
|
||||
Reference in new issue
Block a user