无服务器堆栈:在 npm 运行 启动期间,仅在 windows 中超出了最大调用堆栈大小
Serverless stack: Maximum call stack size exceeded only in windows during npm run start
我开始使用无服务器堆栈指南,但很快就在 Windows 10 中碰壁了(相同的步骤不会在 Mac 或 Linux 中造成任何问题) .
我创建了一个简单的无服务器堆栈项目,并执行以下操作:
npm 运行 开始
我知道了:
RangeError: Maximum call stack size exceeded
at Object.resolve (path.js:153:10)
at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:38)
at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12)
at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12)
at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12)
at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12)
at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12)
at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12)
at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12)
at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12)
节点版本是v14.17.5,npm是7.21.1
由于我几乎没有实例化该项目并且它在其他平台上运行,我真的不知道如何解决这个问题。
谢谢
嗯,您通常会从检查调用堆栈中的 code/files 开始,看看是否能为您提供任何线索。从我们在那里看到的一点点看来,getManager()
一遍又一遍地调用自己。只是猜测,但这可能是配置错误或触发它执行此操作的其他错误路径。
如果你在 github 上查看 serverless-stack/core/dist/packager/packager.js,你会看到这个函数:
export function getManager(dir: string): Manager {
const lock = path.join(dir, "yarn.lock");
if (fs.existsSync(lock)) return Yarn;
if (dir === "/") return NPM;
return getManager(path.resolve(dir, ".."));
}
因此,这似乎是要查找 yarn.lock
文件。如果找到一个,return Yarn
。如果我们已经在 /
的顶级路径,那么 return NPM
。否则,递归调用自身,但在目录层次结构中上升一个级别并重新开始。因此,如果代码实际上是这样工作的,它应该在 *nix 的顶层以 dir === "/"
结束,但在 Windows 上可能不是这种情况,原因有两个:
- Windows 路径的开头可能有一个驱动器号。
- Windows 使用“\”作为路径分隔符,而不是“/”。
缩小范围的一种方法是暂时在这个 getManager()
函数中放置一些日志记录以查看它正在传递的内容(只需暂时编辑 dist 目录中的版本 - 确保你正在编辑compiled/transpiled 版本,而不是 TypeScript 版本,除非你要重新构建它。
export function getManager(dir: string): Manager {
console.log("getManager()", dir); // <== add this
const lock = path.join(dir, "yarn.lock");
if (fs.existsSync(lock)) return Yarn;
if (dir === "/") return NPM;
return getManager(path.resolve(dir, ".."));
}
查看此处传递的内容将表明上述两个问题中的哪一个可能导致问题。从代码来看,只要确保您只向它传递一条带有正斜杠的路径,它就可以工作,但是必须测试它以查看此处涉及的其他代码是否可以。
仅供参考,通过将代码更改为以下内容,可以使此代码对 Windows 世界更加宽容:
// regex that matches / or \ or d:/ or d:\
const topPath = /^(\/|\|[a-z]:[\/\]|)$/i;
export function getManager(dir: string): Manager {
console.log("getManager()", dir);
const lock = path.join(dir, "yarn.lock");
if (fs.existsSync(lock)) return Yarn;
if (topPath.test(dir)) return NPM;
return getManager(path.resolve(dir, ".."));
}
请注意,这还没有被编码来处理 Windows 上以“\\”开头的 UNC 路径,但它当然也可以为此进行调整。
再仔细考虑一下,这里有一个更简单的方法来避免到达顶部时的无限循环。如果尝试上升 ..
不会改变路径,那么您就在顶部:
export function getManager(dir: string): Manager {
const lock = path.join(dir, "yarn.lock");
if (fs.existsSync(lock)) return Yarn;
let upDir = path.resolve(dir, "..");
// if we didn't actually go up any more, then we're at the top
if (upDir === dir) {
return NPM;
}
return getManager(upDir);
}
我开始使用无服务器堆栈指南,但很快就在 Windows 10 中碰壁了(相同的步骤不会在 Mac 或 Linux 中造成任何问题) .
我创建了一个简单的无服务器堆栈项目,并执行以下操作: npm 运行 开始
我知道了:
RangeError: Maximum call stack size exceeded at Object.resolve (path.js:153:10) at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:38) at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12) at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12) at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12) at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12) at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12) at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12) at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12) at getManager (D:\Sources\demo-notes-app\node_modules@serverless-stack\core\dist\packager\packager.js:48:12)
节点版本是v14.17.5,npm是7.21.1
由于我几乎没有实例化该项目并且它在其他平台上运行,我真的不知道如何解决这个问题。
谢谢
嗯,您通常会从检查调用堆栈中的 code/files 开始,看看是否能为您提供任何线索。从我们在那里看到的一点点看来,getManager()
一遍又一遍地调用自己。只是猜测,但这可能是配置错误或触发它执行此操作的其他错误路径。
如果你在 github 上查看 serverless-stack/core/dist/packager/packager.js,你会看到这个函数:
export function getManager(dir: string): Manager {
const lock = path.join(dir, "yarn.lock");
if (fs.existsSync(lock)) return Yarn;
if (dir === "/") return NPM;
return getManager(path.resolve(dir, ".."));
}
因此,这似乎是要查找 yarn.lock
文件。如果找到一个,return Yarn
。如果我们已经在 /
的顶级路径,那么 return NPM
。否则,递归调用自身,但在目录层次结构中上升一个级别并重新开始。因此,如果代码实际上是这样工作的,它应该在 *nix 的顶层以 dir === "/"
结束,但在 Windows 上可能不是这种情况,原因有两个:
- Windows 路径的开头可能有一个驱动器号。
- Windows 使用“\”作为路径分隔符,而不是“/”。
缩小范围的一种方法是暂时在这个 getManager()
函数中放置一些日志记录以查看它正在传递的内容(只需暂时编辑 dist 目录中的版本 - 确保你正在编辑compiled/transpiled 版本,而不是 TypeScript 版本,除非你要重新构建它。
export function getManager(dir: string): Manager {
console.log("getManager()", dir); // <== add this
const lock = path.join(dir, "yarn.lock");
if (fs.existsSync(lock)) return Yarn;
if (dir === "/") return NPM;
return getManager(path.resolve(dir, ".."));
}
查看此处传递的内容将表明上述两个问题中的哪一个可能导致问题。从代码来看,只要确保您只向它传递一条带有正斜杠的路径,它就可以工作,但是必须测试它以查看此处涉及的其他代码是否可以。
仅供参考,通过将代码更改为以下内容,可以使此代码对 Windows 世界更加宽容:
// regex that matches / or \ or d:/ or d:\
const topPath = /^(\/|\|[a-z]:[\/\]|)$/i;
export function getManager(dir: string): Manager {
console.log("getManager()", dir);
const lock = path.join(dir, "yarn.lock");
if (fs.existsSync(lock)) return Yarn;
if (topPath.test(dir)) return NPM;
return getManager(path.resolve(dir, ".."));
}
请注意,这还没有被编码来处理 Windows 上以“\\”开头的 UNC 路径,但它当然也可以为此进行调整。
再仔细考虑一下,这里有一个更简单的方法来避免到达顶部时的无限循环。如果尝试上升 ..
不会改变路径,那么您就在顶部:
export function getManager(dir: string): Manager {
const lock = path.join(dir, "yarn.lock");
if (fs.existsSync(lock)) return Yarn;
let upDir = path.resolve(dir, "..");
// if we didn't actually go up any more, then we're at the top
if (upDir === dir) {
return NPM;
}
return getManager(upDir);
}