最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Removing tslib as a production dependency - Stack Overflow

programmeradmin2浏览0评论

I've created a TypeScript project (tsconfig at the end) and I've seen on several boilerplate templates for TypeScript projects that tslib library is added as a devDependency, and I've seen the Dockerfile for these as:

# 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"]

so, essentially, we can see that all the devDependencies are being removed(and note tslib) was a dev dependency.

So, my question is, after a TypeScript project is transpiled to a JavaScript project, there should be no need for tslib to run the project, right?

Yet, why do I get the following error when I run app.js inside of the dist folder with the prod dependencies installed:

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._pile (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'
  ]
}

My tsconfig file is as follows:

{
  "pilerOptions": {
    "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/mon/types/*", "src/*"]
    },

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

The package.json has the following contents:

{
    "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-mit": "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"
    }
}

EDIT: Also, do let me know if using a bundler like webpack or backpack() defers the need to use tslib as a prod dependency somehow.

I've created a TypeScript project (tsconfig at the end) and I've seen on several boilerplate templates for TypeScript projects that tslib library is added as a devDependency, and I've seen the Dockerfile for these as:

# 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"]

so, essentially, we can see that all the devDependencies are being removed(and note tslib) was a dev dependency.

So, my question is, after a TypeScript project is transpiled to a JavaScript project, there should be no need for tslib to run the project, right?

Yet, why do I get the following error when I run app.js inside of the dist folder with the prod dependencies installed:

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._pile (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'
  ]
}

My tsconfig file is as follows:

{
  "pilerOptions": {
    "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/mon/types/*", "src/*"]
    },

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

The package.json has the following contents:

{
    "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-mit": "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"
    }
}

EDIT: Also, do let me know if using a bundler like webpack or backpack(https://www.npmjs./package/backpack-core) defers the need to use tslib as a prod dependency somehow.

Share Improve this question edited Mar 28, 2022 at 11:44 juztcode asked Mar 28, 2022 at 11:24 juztcodejuztcode 1,3632 gold badges29 silver badges65 bronze badges 10
  • 1 You can't. It's "a runtime library". Note that the install instructions don't show it being installed as a dev dependency. But why do you want to? – jonrsharpe Commented Mar 28, 2022 at 11:26
  • 1 Looks like a bug in those boilerplate templates… – Bergi Commented Mar 28, 2022 at 11:27
  • 1 Yes, and that's wrong. So why don't you just move it to the correct category? – jonrsharpe Commented Mar 28, 2022 at 11:35
  • 1 Then raise this with whoever maintains the boilerplate – jonrsharpe Commented Mar 28, 2022 at 11:40
  • 3 According to the docs of tslib that you've linked, using "importHelpers": false, means that the generated code will no longer depend on tslib and you can remove the dependency entirely (both dev and prod). Either way, raise this issue with the boilerplate template. – Bergi Commented Mar 28, 2022 at 12:23
 |  Show 5 more ments

1 Answer 1

Reset to default 5

I had a similar issue and I fixed it by setting pilerOptions.importHelpers = false in tsconfig.json as @Bergi suggests in the ments. So thanks for that @Bergi. I'm posting this answer for fellow coders who stumble upon this page in the future.

In my case, the details were:

Problem

Docker works with dev dependencies (installed using RUN npm install in the Dockerfile). However, ti throws the error below when dependencies are installed using the production way: 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._pile (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

Source of the problem

File build/server/src/app.js (after being built) requires tslib on line 3. However, tslib is not defined as a dependency in package.json. According to package-lock.json, tslib is just a transitive dependency of some development dependency.

"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"));
...

Fix

  • In server/tsconfig.json set pilerOptions.importHelpers = false
  • Rebuild the project
  • Check that build/server/src/app.js doesn't require("tslib") anymore
  • Rebuild the Docker image
  • Run a container based on the new Docker image
  • Enjoy
发布评论

评论列表(0)

  1. 暂无评论