I've just rewritten a Node.js GraphQL API from an old version of graphql-yoga + prisma to using express, serverless-http, prisma, and apollo-server-express. I've got it working locally just fine as an Express app, but when I try to get it published on Netlify as Function, I get a "Cannot find module" error:
{
"errorType": "Runtime.ImportModuleError",
"errorMessage": "Error: Cannot find module './schema.graphql'\nRequire stack:\n- /var/task/bundle/index.js\n- /var/task/graphql.js\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js",
"trace": [
"Runtime.ImportModuleError: Error: Cannot find module './schema.graphql'",
"Require stack:",
"- /var/task/bundle/index.js",
"- /var/task/graphql.js",
"- /var/runtime/UserFunction.js",
"- /var/runtime/index.js",
" at _loadUserApp (/var/runtime/UserFunction.js:100:13)",
" at Object.module.exports.load (/var/runtime/UserFunction.js:140:17)",
" at Object.<anonymous> (/var/runtime/index.js:43:30)",
" at Module._compile (internal/modules/cjs/loader.js:1156:30)",
" at Object.Module._extensions..js (internal/modules/cjs/loader.js:1176:10)",
" at Module.load (internal/modules/cjs/loader.js:1000:32)",
" at Function.Module._load (internal/modules/cjs/loader.js:899:14)",
" at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)",
" at internal/main/run_main_module.js:18:47"
]
}
I've tried multiple ways of importing these graphql files (graphql-imports, require.resolve, fs.readDirSync, etc.), but either it doesn't work at all or it only works from the project root. require.resolve
works from the project root locally, so I'm left thinking that this file just wasn't included in the build. How can I tell what gets zipped?
My netlify.toml is:
[build]
command = "npm run bundle"
functions = "functions"
npm run bundle
is basically cpx 'src/**/*' 'functions/bundle'
and the files are visible locally in functions/bundle/schema.graphql
and functions/bundle/generated/prisma.graphql
.
My functions/graphql.js
just takes the Express server and creates a lambda wrapper:
const serverlessHttp = require("serverless-http");
const { app } = require("./bundle/index.js");
exports.handler = serverlessHttp(app, {
request(req, event, context) {
req.event = event;
req.context = context;
}
});
"graphql-import" is super annoying because it only works from the root for the project, so copying the src/
files into functions/bundle/
changes the directory structure and those imports no longer work
Inside the functions/bundle/index.js, I try to require.resolve
some .grapqhl type definition files:
const { importSchema } = require("graphql-import");
const typeDefs = importSchema(require.resolve("./schema.graphql"));
const prismaTypeDefs = importSchema(
require.resolve("./generated/prisma.graphql")
);
const db = new Prisma({
typeDefs: prismaTypeDefs,
endpoint: process.env.PRISMA_ENDPOINT,
secret: process.env.PRISMA_SECRET,
debug: process.env.NODE_ENV === "development"
});
const schema = makeExecutableSchema({
typeDefs: gql`
${typeDefs}
`,
resolvers: {
Mutation,
Query,
},
resolverValidationOptions: { requireResolversForResolveType: false }
});
Again, this works locally so I assume the file is just outright missing from the zipped files.
I'm at a loss. Any ideas?