Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to load .graphql files. how to add custom loader for graphq files? #1829

Open
deathemperor opened this issue Oct 23, 2024 · 6 comments

Comments

@deathemperor
Copy link

Bug Report

Before I use serverless-esbuild to config loader for .graphql files but with serverless v4 it doesn't work.

Current Behavior

Offline [http for lambda] listening on http://localhost:3002
Function names exposed for local invocation by aws-sdk:
   * hello: my-service-dev-hello

   ┌─────────────────────────────────────────────────────────────────────────┐
   │                                                                         │
   │   GET  | http://localhost:3000/dev/hello                                │
   │   POST | http://localhost:3000/2015-03-31/functions/hello/invocations   │
   │                                                                         │
   └─────────────────────────────────────────────────────────────────────────┘

Server ready: http://localhost:3000 🚀


GET /dev/hello (λ: hello)
✖ Unhandled exception in handler 'hello'.
✖ Runtime.UserCodeSyntaxError: SyntaxError: Unexpected identifier 'mutation_root'
    at _loadUserApp (/Users/deathemperor/papaya/slsv4-offline/node_modules/serverless-offline/src/lambda/handler-runner/in-process-runner/aws-lambda-ric/UserFunction.js:239:13)
    at async module.exports.load (/Users/deathemperor/papaya/slsv4-offline/node_modules/serverless-offline/src/lambda/handler-runner/in-process-runner/aws-lambda-ric/UserFunction.js:311:19)
    at async InProcessRunner.run (file:///Users/deathemperor/papaya/slsv4-offline/node_modules/serverless-offline/src/lambda/handler-runner/in-process-runner/InProcessRunner.js:41:21)
    at async MessagePort.<anonymous> (file:///Users/deathemperor/papaya/slsv4-offline/node_modules/serverless-offline/src/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js:24:14)
✖ SyntaxError: Unexpected identifier 'mutation_root'

Sample Code

https://github.com/papaya-insurtech/slsv4-offline

Expected behavior/code

Environment

  • serverless version: 4.4.7
  • serverless-offline version: 14.3.3
  • node.js version: v22.9.0
  • OS: macOS 15.1

Possible Solution

N/A

@DorianMazur
Copy link
Collaborator

DorianMazur commented Nov 6, 2024

Hi @deathemperor,

You can still use serverless-esbuild. Just configure it like this:

plugins:
  - serverless-esbuild

build:
  esbuild: false

We could definitely add support for .graphql files.

You could create a PR for this yourself. What I'm thinking is to use something like graphql-tag/loader, and the main change would be in this part of the code:

https://github.com/dherault/serverless-offline/blob/master/src/lambda/handler-runner/in-process-runner/aws-lambda-ric/UserFunction.js#L185

  // If still not loaded, try .js, .mjs, .cjs and .ts in that order.
  // Files ending with .js are loaded as ES modules when the nearest parent package.json
  // file contains a top-level field "type" with a value of "module".
  const loaded =
    (pjHasModule && (await _tryAwaitImport(lambdaStylePath, ".js"))) ||
    (await _tryAwaitImport(lambdaStylePath, ".mjs")) ||
    _tryRequireFile(lambdaStylePath, ".cjs") ||
    tsxRequire(`${lambdaStylePath}.ts`, `${lambdaStylePath}.ts`)

So, you would just need to add another loader here to handle .graphql files correctly. It’s not too complicated, but I don’t have time to do it right now. If it's urgent for you, it would be awesome if you could submit a PR!

@deathemperor
Copy link
Author

I was able to play a bit with inspiration of loader from https://github.com/ardatan/graphql-import-node/blob/master/register.js. Had no idea loader can be "injected" like so in node, I'm not familiar with this low programming level.

but it got a lot of complication after that due to tsxRequire has a different context than the current process. (I think?)

Decided to load graphql files another way (not using imports), but I still have concerns with loading other files such as html, excel, and so on that needs taken care of anyways.

I thought of continue to use serverless-esbuild too but skeptical if it's well maintained as sls v4.

@deathemperor
Copy link
Author

tried with serverless-esbuild and works with many features obviously sls doesn't have like live build watch. may choose to stick with it for awhile. thanks @DorianMazur.

@fridaystreet
Copy link

@deathemperor you can use all the same features of serverless-esbuild with the built in sls4 esbuild. you just need to give sls4 you config file and override the buiult in esbuild

build:
esbuild:
configFile: ./esbuild.config.js

Then you can add whatever plugins etc you want. SLS just uses esbuild under the hood so watch etc is all just baked in to esbuild. Doesn't matter if you're using serverless-esbuild plugin, sls 4 or just running esbuild manually

The only problem is that serverless-offline at the moment doesn't appear to support the sls4 built in use of esbuild

@deathemperor
Copy link
Author

@fridaystreet yeah I realized that. thanks for the instructions anyway. I did tried using the same esbuild.config.js for both sls4 and sls offline, just that serverless-esbuild somewhat use different esbuild config format than sls4 last I checked. Will try that again.

@fridaystreet
Copy link

@deathemperor yeah if you have type:module in your package.json file, it will get tricky. The other thing to note is that there is currently an issue with serverless-esbuild that is doesn't load a config from an async esbuild.conifg.js (eg you config returns an async function)

I got stuck on this for a while as we load some async stuff for our staging and prod deployments, which isn't actually needed in dev (well it can be done without, but not ideal).

Anyway make sure your esbuild isn't an asycn function.

The other gotcha is that it doesn't process the externals as nicely as sls v4 does. if you have any glob patterns in your external in the config eg graphql* it won't package those properly. slsv4 merges those automatically for you.

So you need to call out all the packages individually. Sounds like a pain if this affects you, but a little trick is to run you esbuild with sls v4, look at the package.json it generates in the.servereless/build directory. It will have the full list you need to have in your config.

type: module:

If you are using this, you need to rename your esbuild.config.js to .cjs and use require for any thing you're importing in there. Likewise any local js files it rquires need to not be using ESM imports/exports

Aside from that should work the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants