javascript - 删除 tslib 作为生产依赖项

标签 javascript node.js typescript docker

我已经创建了一个 TypeScript 项目(最后是 tsconfig),并且我在 TypeScript 项目的几个样板模板上看到 tslib库被添加为 devDependency,我已经看到它们的 Dockerfile 如下:

# STAGE: Development
FROM node:14-alpine3.13 AS dev
EXPOSE 8000

WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install

COPY . /app/
CMD ["yarn", "local"]

  
# STAGE: Builder
FROM node:14-alpine3.13 AS builder
WORKDIR /app
COPY --from=dev /app /app
RUN yarn build


# STAGE: Prod Dependencies Builder
FROM node:14-alpine3.13 AS prod-dependencies
WORKDIR /app
COPY ["package.json", "yarn.lock", "./"]
RUN yarn install --prod


# STAGE: Prod Deploy Ready Image
FROM node:14-alpine3.13 AS prod
EXPOSE 8000
WORKDIR /app
COPY public /app/public
COPY --from=builder /app/dist /app/dist
COPY --from=prod-dependencies /app/node_modules /app/node_modules
CMD ["node", "dist/index.js"]

因此,本质上,我们可以看到所有 devDependency 都被删除(并注意 tslib),这是一个开发依赖项。

所以,我的问题是,TypeScript 项目转译为 JavaScript 项目后,应该不需要 tslib 来运行该项目,对吗?

但是,当我在安装了 prod 依赖项的 dist 文件夹内运行 app.js 时,为什么会出现以下错误:

node:internal/modules/cjs/loader:936
  throw err;
  ^

Error: Cannot find module 'tslib'
Require stack:
- /Users/myComputer/Desktop/newproject1/myproject-backend/dist/app.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/Users/myComputer/Desktop/newproject1/myproject-backend/dist/app.js:3:15)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/Users/myComputer/Desktop/newproject1/myproject-backend/dist/app.js'
  ]
}

我的tsconfig文件如下:

{
  "compilerOptions": {
    "target": "es5",
    "sourceMap": true,
    "outDir": "./dist",
    "module": "CommonJS",
    "importHelpers": true,
    "removeComments": true,
    "downlevelIteration": true,
    "lib": ["es2015", "es2016", "es2017", "dom"],

    "strict": true,
    "alwaysStrict": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "strictNullChecks": true,
    "noImplicitReturns": true,
    "noUnusedParameters": true,
    "strictFunctionTypes": true,
    "noFallthroughCasesInSwitch": true,

    "baseUrl": "./src",
    "esModuleInterop": true,
    "preserveSymlinks": true,
    "resolveJsonModule": true,
    "moduleResolution": "node",
    "types": ["node", "express", "reflect-metadata"],
    "allowSyntheticDefaultImports": true,
    "paths": {
      "*": ["node_modules/*", "src/common/types/*", "src/*"]
    },

    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  },
  "include": ["app.ts", "src", "src/**/*"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}

package.json 具有以下内容:

{
    "name": "myproject-backend",
    "version": "1.0.0",
    "description": "",
    "main": "app.js",
    "engines": {
        "node": ">= 16.13.1"
    },
    "scripts": {
        "start": "node dist/app.js",
        "start_dev": "nodemon app.ts",
        "lint:check": "eslint .",
        "build": "npx tsc --build",
        "clean": "rm -R dist",
        "rebuild": "npm run clean && npm run build",
        "lint:fix": "eslint --fix .",
        "format:check": "prettier --check .",
        "format:write": "prettier --write .",
        "seedFile1": "ts-node seeds/01_file1.ts",
        "seedFile2": "ts-node seeds/02_file2.ts",
        "seed": "npm run seedFile1 && npm run seedFile2"
    },
    "lint-staged": {
        "*.{ts,js,json}": [
            "eslint --fix {src,scripts,test}/**/*.{ts,js,json} --no-error-on-unmatched-pattern"
        ]
    },
    "husky": {
        "hooks": {
            "pre-commit": "lint-staged"
        }
    },
    "keywords": [
        "api",
        "es6",
        "node",
        "express",
        "javascript",
        "typescript"
    ],
    "author": "",
    "license": "ISC",
    "dependencies": {
        "body-parser": "^1.19.2",
        "cors": "^2.8.5",
        "dotenv": "^16.0.0",
        "express": "^4.17.3",
        "helmet": "^5.0.2",
        "http-status-codes": "^2.2.0",
        "mongoose": "^6.2.6",
        "swagger-jsdoc": "^6.1.0",
        "swagger-ui-express": "^4.3.0",
        "uuidv4": "^6.2.12"
    },
    "devDependencies": {
        "@types/cors": "^2.8.12",
        "@types/dotenv": "^8.2.0",
        "@types/express": "^4.17.13",
        "@types/express-serve-static-core": "^4.17.28",
        "@types/helmet": "^4.0.0",
        "@types/mongoose": "^5.11.97",
        "@types/node": "^17.0.23",
        "@types/reflect-metadata": "^0.1.0",
        "@types/swagger-jsdoc": "^6.0.1",
        "@types/swagger-ui-express": "^4.1.3",
        "eslint": "^8.11.0",
        "eslint-config-prettier": "^8.5.0",
        "eslint-plugin-react": "^7.29.4",
        "husky": "^7.0.4",
        "nodemon": "^2.0.15",
        "prettier": "^2.5.1",
        "ts-node": "^10.7.0",
        "tslib": "^2.3.1",
        "typescript": "^4.6.3"
    }
}

编辑:另外,如果使用像 webpackbackpack( https://www.npmjs.com/package/backpack-core ) 这样的打包器会以某种方式推迟使用 tslib 作为产品依赖项的需要,请告诉我。

最佳答案

我遇到了类似的问题,我通过将 tsconfig.json 中的 compilerOptions.importHelpers = false 设置为 @Bergi 来修复它。在评论中建议。谢谢你@Bergi 。我将这个答案发布给将来偶然发现此页面的其他编码人员。

在我的case ,详细信息为:

问题

Docker 使用开发依赖项(使用 Dockerfile 中的 RUN npm install 安装)。但是,当使用生产方式安装依赖项时,ti 会抛出以下错误:RUN npm ci --omit=dev

2023-02-26T17:04:13.091231530Z node:internal/modules/cjs/loader:1078
2023-02-26T17:04:13.091314533Z   throw err;
2023-02-26T17:04:13.091321833Z   ^
2023-02-26T17:04:13.091327133Z 
2023-02-26T17:04:13.091332233Z Error: Cannot find module 'tslib'
2023-02-26T17:04:13.091337334Z Require stack:
2023-02-26T17:04:13.091342334Z - /app/server/src/app.js
2023-02-26T17:04:13.091347434Z     at Module._resolveFilename (node:internal/modules/cjs/loader:1075:15)
2023-02-26T17:04:13.091355834Z     at Module._load (node:internal/modules/cjs/loader:920:27)
2023-02-26T17:04:13.091361034Z     at Module.require (node:internal/modules/cjs/loader:1141:19)
2023-02-26T17:04:13.091366135Z     at require (node:internal/modules/cjs/helpers:110:18)
2023-02-26T17:04:13.091371235Z     at Object.<anonymous> (/app/server/src/app.js:3:17)
2023-02-26T17:04:13.091376635Z     at Module._compile (node:internal/modules/cjs/loader:1254:14)
2023-02-26T17:04:13.091381635Z     at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
2023-02-26T17:04:13.091386835Z     at Module.load (node:internal/modules/cjs/loader:1117:32)
2023-02-26T17:04:13.091391835Z     at Module._load (node:internal/modules/cjs/loader:958:12)
2023-02-26T17:04:13.091396836Z     at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) {
2023-02-26T17:04:13.091402036Z   code: 'MODULE_NOT_FOUND',
2023-02-26T17:04:13.091407136Z   requireStack: [ '/app/server/src/app.js' ]
2023-02-26T17:04:13.091412136Z }
2023-02-26T17:04:13.091417036Z 
2023-02-26T17:04:13.091421837Z Node.js v18.14.2

问题根源

文件 build/server/src/app.js(构建后)在第 3 行需要 tslib。 但是,tslib 未在 package.json 中定义为依赖项。根据package-lock.jsontslib只是一些开发依赖的传递依赖。

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const cors_1 = tslib_1.__importDefault(require("cors"));
const express_1 = tslib_1.__importStar(require("express"));
...

修复

  • server/tsconfig.json中设置compilerOptions.importHelpers = false
  • 重建项目
  • 检查 build/server/src/app.js 是否不再 require("tslib")
  • 重建 Docker 镜像
  • 基于新的 Docker 镜像运行容器
  • 享受

关于javascript - 删除 tslib 作为生产依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71646672/

相关文章:

javascript - 当数组包含基本多语言平面之外的字符时,为什么 Array#slice 无法按预期工作?

node.js - socket.io客户端如何找到/socket.io/socket.io.js

JavaScript 推送方法改变值

javascript - nodejs - 将客户端时间戳存储在数据库中

javascript - 如何格式化仅包含日和月的给定日期?

javascript - 无法理解 addEventListener 中的 useCapture 参数

javascript - 使用 React 嵌入 JavaScript 小部件

javascript - 在客户端机器上执行webapi函数(访问客户端系统的数据库)

typescript - 如何为 mongoose 'Query<any>' 添加类型

javascript - 每 2 分钟运行一次的 Nodejs 函数会随着时间的推移而丢失