serverless-plugin-typescript
serverless-plugin-typescript copied to clipboard
Support `tsconfig.json` files.
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.
That's a good point! Would you mind creating a PR for this?
@nickcoury, Are you helper functions referenced from handler.ts
? It should compile all files starting from handler.ts as an entrypoint.
@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 would be great if you can setup minimal reproducible sample e.g. in form of github repo.
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.
@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:
- Download repo and
npm i
- Run
serverless deploy
. Build may fail, important step is the outputted.zip
file under.serverless/
directory. Unzip and note the services folder andservices/helper.js
is not present. - Run
tsc
from root directory. Look in.build/
and notice thatservices/helper.js
was properly generated. - Step 2 can be repeated without the
tsconfig.json
present (so the plugin uses default values) with the same result.
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.
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 ;)
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.
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 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 :((
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.
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.
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
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.