serverless / typescript

TypeScript definitions for Serverless Framework service configuration
140 stars 24 forks source link

Question: using typescript template in an nx monorepo #40

Closed DaveLo closed 3 years ago

DaveLo commented 3 years ago

I think this is somewhat related to #28 ,

I'm getting initialization errors when I try to run serverless commands in the nx app directory. This happens whether I cd into the the directory and run manually or use nx run commands.

What I've noticed is if I point serverless webpack at tsconfig.app.json, but there is a tsconfig.json file in the same directory I get an initialization error. If I rename the tsconfig file to something else then the serverless.ts file will initialize and run serverless commands, but I lose my paths info from the monorepo context.

I feel like there is probably a setting (or there should be) to tell serverless to use exactly this tsconfig file only and ignore others?

code

tsconfig files ```jsonc /* tsconfig.app.json */ { "extends": "./tsconfig.json", "compilerOptions": { "target": "ES2020", "types": ["node"], "lib": ["esnext"], "skipLibCheck": true }, "exclude": [ "**/*.spec.ts", "node_modules/**/*", ".serverless/**/*", ".webpack/**/*", "_warmup/**/*", ".vscode/**/*" ], "include": ["src/**/*.ts", "serverless.ts"], "ts-node": { "require": ["tsconfig-paths/register"] } } /* tsconfig.json */ { "extends": "../../../tsconfig.base.json", "files": [], "include": [], "references": [ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.spec.json" } ] } /* tsconfig.base.json */ { "compileOnSave": false, "compilerOptions": { "rootDir": ".", "sourceMap": true, "declaration": false, "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, "importHelpers": true, "target": "esnext", "module": "esnext", "lib": ["esnext", "dom"], "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".", "paths": {/* lots of paths */} }, "exclude": ["node_modules", "tmp"] } ```
serverless file ```typescript /** serverless.ts */ import type * as sls from "@serverless/typescript"; import hello from "./src/hello"; const slsWebpackConfig = { webpackConfig: "./webpack.config.js", includeModules: { forceExclude: ["aws-sdk"], }, }; const prunePluginConfig = { automatic: true, number: 3, }; const serverlessConfiguration: sls.AWS = { service: "cloud-api", org: "southtreebot", app: "cloud-backup", frameworkVersion: "2", custom: { stage: '${opt:stage, "Dev"}', webpack: slsWebpackConfig, prune: prunePluginConfig, }, /** removed some deployment bucket info */ plugins: ["serverless-prune-plugin", "serverless-webpack"], provider: { name: "aws", runtime: "nodejs14.x", region: "us-east-1", logRetentionInDays: 731, apiGateway: { minimumCompressionSize: 1024, shouldStartNameWithService: true, }, lambdaHashingVersion: "20201221", iam: { role: { managedPolicies: [ { "Fn::Sub": "arn:aws:iam::${AWS::AccountId}:policy/PutEventBridgeEventsPolicy", }, ], }, }, environment: { AWS_NODEJS_CONNECTION_REUSE_ENABLED: "1", ENV_STAGE: "${self:custom.stage}", }, }, package: { individually: true, exclude: ["*.json", "*.md"], }, functions: { hello, }, // resources: {}, }; module.exports = serverlessConfiguration; ```

error text

Cannot load "serverless.ts": Initialization error: /Users/**/**/apps/cloud/api/serverless.ts:59
  export {};
  ^^^^^^

  SyntaxError: Unexpected token 'export'
      at wrapSafe (internal/modules/cjs/loader.js:979:16)
      at Module._compile (internal/modules/cjs/loader.js:1027:27)
      at Module.m._compile (/Users/**/**/node_modules/ts-node/src/index.ts:1056:23)
      at Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
      at Object.require.extensions.<computed> [as .ts] (/Users/**/**/node_modules/ts-node/src/index.ts:1059:12)
      at Module.load (internal/modules/cjs/loader.js:928:32)
      at Function.Module._load (internal/modules/cjs/loader.js:769:14)
      at Module.require (internal/modules/cjs/loader.js:952:19)
      at require (internal/modules/cjs/helpers.js:88:18)
      at /Users/**/.nvm/versions/node/v14.15.0/lib/node_modules/serverless/lib/configuration/read.js:121:18
      at parseConfigurationFile (/Users/**/.nvm/versions/node/v14.15.0/lib/node_modules/serverless/lib/configuration/read.js:136:9)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)
      at module.exports (/Users/**/.nvm/versions/node/v14.15.0/lib/node_modules/serverless/lib/configuration/read.js:163:23)
      at /Users/**/.nvm/versions/node/v14.15.0/lib/node_modules/serverless/scripts/serverless.js:112:22
      at /Users/**/.nvm/versions/node/v14.15.0/lib/node_modules/serverless/scripts/serverless.js:110:11

interestingly it is compiling, because line 59 of the ts file is not the export statement.

If I run a tsc in the directory it compiles to js and adds an export {} on line 59; however, if I add the --project flag with tsconfig.app.json it compiles correctly and serverless will run that compiled js file with no issue.

env

Your Environment Information ---------------------------
     Operating System:          darwin
     Node Version:              14.15.0
     Framework Version:         2.34.0
     Plugin Version:            4.5.3
     SDK Version:               4.2.2
     Components Version:        3.8.2
fredericbarthelet commented 3 years ago

Hi @DaveLo and thanks for reporting your issue.

I feel like there is probably a setting (or there should be) to tell serverless to use exactly this tsconfig file only and ignore others?

Indeed, the result from #28 shows that using env variable TS_NODE_CONFIG=./tsconfig.app.json does the trick of letting serverless know which file you'd like to use -> https://github.com/serverless/serverless/tree/master/lib/plugins/create/templates/aws-nodejs-typescript#advanced-usage

Is this solution compatible with your monorepo usage (you'd have to specify a dedicated env variable for each module I believe) ?

DaveLo commented 3 years ago

I did try that, but it seems to still latch onto there being a tsconfig.json in the directory?

I thought it was interesting that running the same command (with the env var) would fail with a tsconfig.json in the lib and succeed if I changed that to tsconfig.lib.json. If that didn't break typescript references inside the directory it would be workable , but sadly it seems to (probably something with how Nx works behind the scenes?).

To get unblocked I've switched the app to using a yaml file and that seems to mostly work (although sad because I love the way the ts template is structured and having type hints).

fredericbarthelet commented 3 years ago

Hi @DaveLo, if you want to get involved in this, we're currently reworking the way serverless framework loads service file defined in TS in this issue https://github.com/serverless/serverless/issues/9311 In the meantime, I'm closing this. Thanks for your feedbacks :)!