serverless-plugin-typescript icon indicating copy to clipboard operation
serverless-plugin-typescript copied to clipboard

Support `tsconfig.json` files.

Open nickcoury opened this issue 6 years ago • 15 comments

The plugin appears to only compile the .ts files that contain handler functions. It should support compiling a project based on files/include/exclude in tsconfig.json.

Use case: I have my handler in handler.ts, but I organize my helper functions in files at services/*.ts. My tsconfig.json looks like this:

{
  "compilerOptions": {
    "preserveConstEnums": true,
    "strictNullChecks": true,
    "sourceMap": true,
    "target": "es5",
    "outDir": ".build",
    "moduleResolution": "node",
    "lib": ["es2015"],
    "rootDir": "./"
  },
  "include": [
    "services/**/*",
    "handler.ts"
  ]
}

If I run tsc, all files will be compiled as expected to .build/. If I build with this plugin, only handler.ts gets compiled.

nickcoury avatar Jul 31 '17 05:07 nickcoury

That's a good point! Would you mind creating a PR for this?

schickling avatar Jul 31 '17 08:07 schickling

@nickcoury, Are you helper functions referenced from handler.ts? It should compile all files starting from handler.ts as an entrypoint.

RomanHotsiy avatar Jul 31 '17 08:07 RomanHotsiy

@RomanGotsiy My handler class references the first service, which in turn references a second service. It does not traverse the tree, I've checked the emitResult.emittedFiles and it only outputs handler.js and handler.js.map. I have my tsconfig.json set up with the proper include: [] which outputs correctly if I simply run tsc. If I remove tsconfig.json and use the default file the result is the same.

Looking deeper in the code, ts.createProgram(fileNames, options) has two entries, both are my handler file. Deduping it doesn't change anything. Not sure where to go from here, started digging into the Typescript library itself but haven't found anything to help. If this has worked for others it's possible it is my setup, but I haven't seen anything that deviates from the defaults or documentation yet. I've been trying out different include/excludes in both serverless.yml and tsconfig.json thinking that might affect something, but no luck yet there either.

@schickling Happy to contribute if possible, however I've been trying to find a resolution and am yet to solve the problem. I've resorted to manually compiling and putting the files into .build/ partway through the build process which is less than ideal. If I'm able to find a solution I'm happy to PR it, but no guarantees so far.

nickcoury avatar Aug 01 '17 07:08 nickcoury

@nickcoury would be great if you can setup minimal reproducible sample e.g. in form of github repo.

RomanHotsiy avatar Aug 01 '17 07:08 RomanHotsiy

Yes, was going to say that is the next step. If I get time tomorrow I'll do that to verify if it is or isn't a problem with my setup.

nickcoury avatar Aug 01 '17 07:08 nickcoury

@RomanGotsiy Ok, set up a minimal example. Issue appears to be deeper than just not supporting tsconfig.json as the title suggests. The issue is that the use of the typescript compiler by the plugin is only compiling the root files with the handlers in them, not their dependencies.

Example: https://github.com/nickcoury/serverless-typescript-test

Example was set up by creating a fresh project from template, adding this plugin to serverless.yml, adding services/helper.ts and referencing it from handler.ts, then adding tsconfig.json.

Steps to reproduce:

  1. Download repo and npm i
  2. Run serverless deploy. Build may fail, important step is the outputted .zip file under .serverless/ directory. Unzip and note the services folder and services/helper.js is not present.
  3. Run tsc from root directory. Look in .build/ and notice that services/helper.js was properly generated.
  4. Step 2 can be repeated without the tsconfig.json present (so the plugin uses default values) with the same result.

nickcoury avatar Aug 02 '17 03:08 nickcoury

I've been digging in and attempting to find a simple fix for this but no luck yet.

My workaround in the mean time is to deploy with tsc && serverless deploy. A workaround for sure but if anyone else is encountering the same issue its a band-aid.

Not sure if it is relevant, but I'm encountering the issue on Windows. I also attempted it on MacOS with the same result so I don't think it's platform dependent.

nickcoury avatar Aug 02 '17 06:08 nickcoury

I've had no issues personally with the traversal, I've included the file and it has been emitted correctly.

I'm encountering some issues with GCP support (which doesn't use the handler definition with the file name in it) and instead uses the package.json:main field, but that's another issue ;)

wyattjoh avatar Aug 10 '17 03:08 wyattjoh

I believe I'm experiencing the same issue. I have files that are referenced as a glob and parsed at runtime. An example would be TypeORM:

 createConnection({
   type: "mysql",
   ...,
   entities: [
     __dirname + "/entities/**/*.entity.js"
    ],
});

I tried to add entities to the include paths in the tsconfig.json with no luck.

brianjd avatar Aug 12 '18 20:08 brianjd

One way to handle this might be to use the include configuration in serverless.yml to force the JS files you need to get included in the resulting bundle. A bit gross, but it should work.

thekevinbrown avatar Mar 08 '19 06:03 thekevinbrown

@thekevinbrown The problem is that we don't have the JS files, they are not compiled.

For now, the only way to make it work is to explicitly compile your .ts files before running the serverless framework.

This is so annoying, I hope this gets some attention :((

waltergalvao avatar Aug 01 '19 11:08 waltergalvao

I'm having a similar issue it seems - I'm requiring some files by reading a folder and looping through its contents like so:

fs.readdirSync(mutationsFolder).forEach(f => {
  if (f !== `index{$ext}` && path.extname(f) === ext) {
    const mut = require(path.join(mutationsFolder, f))
    Mutations = { ...Mutations, ...mut.default }
  }
})

When trying to require those files in that fashion, they don't get compiled to .build, but of course if I run tsc it works as expected and those files are compiled.

k00k avatar Nov 22 '19 18:11 k00k

I'm surprised this is still an issue several years later. This forces users to have workarounds for very legitimate cases, like Typeorm migration files, where you may have a migration handler but the migration files themselves aren't explicitly imported anywhere.

bfaulk96 avatar Jul 19 '21 22:07 bfaulk96

you may have a migration handler but the migration files themselves aren't explicitly imported anywhere

struggling with this exact use case--can't get my migration files to compile properly without some hacking

travishaby avatar Sep 02 '21 11:09 travishaby

After also struggling with the problem of not being able to import my own .ts support files and loosing a lot of time with this, I found this other plugin to work with TypeScript and Serverless, it is serverless-esbuild. It worked like a charm since the very first time so I will strongly recommend to use this one instead of serverless-plugin-typescript.

FranciscoHernandez1998 avatar May 25 '22 01:05 FranciscoHernandez1998