Typescript 构建 "Cannot find module",但仅在 ubuntu 服务器上
Typescript build "Cannot find module", but only on a ubuntu server
我正在研究节点脚本并用打字稿编写它。我在笔记本电脑 (mac) 或 raspberry pi 运行ning raspbian.
上构建 运行ning 没有遇到任何问题
我已经到了想要在 运行ning ubuntu 的数字海洋服务器上设置代码库的地步。我向上移动了代码库和 运行 我的构建脚本。构建成功完成,但是当我启动节点进程时出现错误:
node dist/server/source-server/index.js
internal/modules/cjs/loader.js:883
throw err;
^
Error: Cannot find module 'express'
Require stack:
- /var/www/binary-operations-presentation/multi-player-server/dist/server/source-server/index.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
at Function.Module._load (internal/modules/cjs/loader.js:725:27)
at Module.require (internal/modules/cjs/loader.js:952:19)
at require (internal/modules/cjs/helpers.js:88:18)
at Object.<anonymous> (/var/www/binary-operations-presentation/multi-player-server/dist/server/source-server/index.js:6:35)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/var/www/binary-operations-presentation/multi-player-server/dist/server/source-server/index.js'
]
}
这很奇怪。我在多个服务器上 运行 这个代码库并且 none 有这个问题。我四处搜索了一下,但我找到的所有答案都是“运行 npm install express”或“运行 npm install @types/express”,这两个我都有:
此外,如果我没有安装它们,typescript 编译器构建将会失败。
我将 ubuntu 服务器上的文件结构与我的 raspberry pi 服务器进行了比较,除了代码库实际 运行 时生成的文件外,目录是相同的:
两个服务器都有相同的tsconfig.json文件:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"sourceMap": true,
"outDir": "../dist/server",
"rootDirs": ["./", "../project-common/"],
"strict": true,
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true
}
}
并且两者具有相同的依赖版本:
// from package.json
{
...
"devDependencies": {
"@types/uuid": "^8.3.0",
"@types/ws": "^7.4.0",
"killport": "^1.0.1",
"nodemon": "^2.0.7",
"tsc-watch": "^4.2.9",
"tslint": "^6.1.3",
"typescript": "^4.1.3"
},
"dependencies": {
"@types/express": "^4.17.11",
"@types/lodash.clonedeep": "^4.5.6",
"@types/websocket": "^1.0.1",
"express": "^4.17.1",
"lodash.clonedeep": "^4.5.0",
"uuid": "^8.3.2",
"ws": "^7.4.2"
}
}
dist
文件夹都没有 node_modules 文件夹,当我查看服务器的 t运行spiled index.js
文件时,它们都导入表示同样的方法:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const http_1 = __importDefault(require("http"));
并且两个 index.js.map 文件引用相同的相对源目录:
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../source-server/index.ts"]
所以我不确定为什么一台服务器能够返回到 node_modules 文件夹,而另一台服务器却不能。
我看到的唯一大区别(除了OS版本,服务器是运行ning Ubuntu 20.04)是我的raspberry pi是运行ning 节点 15.x 而 ubuntu 是 运行ning 节点 14.x,虽然我不知道那一定会导致这个问题。
有什么想法吗?
更新:相同版本的节点
我试过让node的版本一样。我在 raspberry pi 上安装了 nvm,引入了 14.6.0(与数字海洋服务器相同的版本),重建了项目,并启动了服务器 -> 工作正常。
所以节点版本似乎不是一个因素:/
所以这是障碍和解决方案:
要点是索引文件的编译版本正在触发一个常规节点 require()
函数来拉入模块:
这意味着它要经过很多步骤才能找到模块。 When it comes to possible node_modules modules,它在当前目录中寻找node_modules
文件夹。如果 node 没有找到它,node 将步进到父目录并在那里查找,如果找不到 node_modules 个目录,则继续步回到根目录。
就我而言,我之前将所有服务器和客户端代码都放在同一目录级别(新子文件夹现在所在的目录)。当我将代码分成子文件夹时,我忘记在本地吹走旧的 node_modules 文件夹,这就是为什么 dist
文件夹仍然找到现在位于父目录的 node_modules
文件夹的原因dist
个。当我在我的 raspberry pi 上执行 git pull
时,文件夹更新了,但是因为 node_modules
是我的 .gitignore
的一部分,父级别的文件夹并没有被吹走。
但是,在较新的存储库克隆中,当然不会在该父目录或任何其他父目录中有 node_modules,因此它们被炸毁了。
在与@cefn 交谈时,我意识到我确实想让 dist
成为“运行 这个项目所需的一切”目录,所以我在我的 npm build
脚本:
"scripts": {
"build": "tsc --build tsconfig.json && npm run build:move-indexes && npm run build:move-node_modules",
"build:move-indexes": "rsync -avz indexes ../dist/server/source-server",
"build:move-node_modules": "rsync -avz node_modules ../dist/server/source-server",
这样,每次我重新构建源代码时,服务器都会将 dist
目录中的 node_modules
与我的源目录中的 node_modules
同步。
试过了,很有效:)
我正在研究节点脚本并用打字稿编写它。我在笔记本电脑 (mac) 或 raspberry pi 运行ning raspbian.
上构建 运行ning 没有遇到任何问题我已经到了想要在 运行ning ubuntu 的数字海洋服务器上设置代码库的地步。我向上移动了代码库和 运行 我的构建脚本。构建成功完成,但是当我启动节点进程时出现错误:
node dist/server/source-server/index.js
internal/modules/cjs/loader.js:883
throw err;
^
Error: Cannot find module 'express'
Require stack:
- /var/www/binary-operations-presentation/multi-player-server/dist/server/source-server/index.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
at Function.Module._load (internal/modules/cjs/loader.js:725:27)
at Module.require (internal/modules/cjs/loader.js:952:19)
at require (internal/modules/cjs/helpers.js:88:18)
at Object.<anonymous> (/var/www/binary-operations-presentation/multi-player-server/dist/server/source-server/index.js:6:35)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/var/www/binary-operations-presentation/multi-player-server/dist/server/source-server/index.js'
]
}
这很奇怪。我在多个服务器上 运行 这个代码库并且 none 有这个问题。我四处搜索了一下,但我找到的所有答案都是“运行 npm install express”或“运行 npm install @types/express”,这两个我都有:
此外,如果我没有安装它们,typescript 编译器构建将会失败。
我将 ubuntu 服务器上的文件结构与我的 raspberry pi 服务器进行了比较,除了代码库实际 运行 时生成的文件外,目录是相同的:
两个服务器都有相同的tsconfig.json文件:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"sourceMap": true,
"outDir": "../dist/server",
"rootDirs": ["./", "../project-common/"],
"strict": true,
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true
}
}
并且两者具有相同的依赖版本:
// from package.json
{
...
"devDependencies": {
"@types/uuid": "^8.3.0",
"@types/ws": "^7.4.0",
"killport": "^1.0.1",
"nodemon": "^2.0.7",
"tsc-watch": "^4.2.9",
"tslint": "^6.1.3",
"typescript": "^4.1.3"
},
"dependencies": {
"@types/express": "^4.17.11",
"@types/lodash.clonedeep": "^4.5.6",
"@types/websocket": "^1.0.1",
"express": "^4.17.1",
"lodash.clonedeep": "^4.5.0",
"uuid": "^8.3.2",
"ws": "^7.4.2"
}
}
dist
文件夹都没有 node_modules 文件夹,当我查看服务器的 t运行spiled index.js
文件时,它们都导入表示同样的方法:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const http_1 = __importDefault(require("http"));
并且两个 index.js.map 文件引用相同的相对源目录:
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../source-server/index.ts"]
所以我不确定为什么一台服务器能够返回到 node_modules 文件夹,而另一台服务器却不能。
我看到的唯一大区别(除了OS版本,服务器是运行ning Ubuntu 20.04)是我的raspberry pi是运行ning 节点 15.x 而 ubuntu 是 运行ning 节点 14.x,虽然我不知道那一定会导致这个问题。
有什么想法吗?
更新:相同版本的节点
我试过让node的版本一样。我在 raspberry pi 上安装了 nvm,引入了 14.6.0(与数字海洋服务器相同的版本),重建了项目,并启动了服务器 -> 工作正常。
所以节点版本似乎不是一个因素:/
所以这是障碍和解决方案:
要点是索引文件的编译版本正在触发一个常规节点 require()
函数来拉入模块:
这意味着它要经过很多步骤才能找到模块。 When it comes to possible node_modules modules,它在当前目录中寻找node_modules
文件夹。如果 node 没有找到它,node 将步进到父目录并在那里查找,如果找不到 node_modules 个目录,则继续步回到根目录。
就我而言,我之前将所有服务器和客户端代码都放在同一目录级别(新子文件夹现在所在的目录)。当我将代码分成子文件夹时,我忘记在本地吹走旧的 node_modules 文件夹,这就是为什么 dist
文件夹仍然找到现在位于父目录的 node_modules
文件夹的原因dist
个。当我在我的 raspberry pi 上执行 git pull
时,文件夹更新了,但是因为 node_modules
是我的 .gitignore
的一部分,父级别的文件夹并没有被吹走。
但是,在较新的存储库克隆中,当然不会在该父目录或任何其他父目录中有 node_modules,因此它们被炸毁了。
在与@cefn 交谈时,我意识到我确实想让 dist
成为“运行 这个项目所需的一切”目录,所以我在我的 npm build
脚本:
"scripts": {
"build": "tsc --build tsconfig.json && npm run build:move-indexes && npm run build:move-node_modules",
"build:move-indexes": "rsync -avz indexes ../dist/server/source-server",
"build:move-node_modules": "rsync -avz node_modules ../dist/server/source-server",
这样,每次我重新构建源代码时,服务器都会将 dist
目录中的 node_modules
与我的源目录中的 node_modules
同步。
试过了,很有效:)