我刚刚将Node.js GraphQL API从旧版本的graphql-yoga + pyramida重写为使用express,less server-http,prisma和apollo-server-express。我已经将它作为Express应用程序在本地正常运行,但是当我尝试将其作为功能发布在Netlify上时,出现“找不到模块”错误:
{
"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"
]
}
我尝试了多种导入这些graphql文件的方法(graphql导入,require.resolve,fs.readDirSync等),但是它根本不起作用,或者只能从项目根目录起作用。 require.resolve
从本地项目根目录开始工作,因此我想到此文件只是不包含在构建中。我怎么知道什么被压缩了?
我的netlify.toml是:
[build]
command = "npm run bundle"
functions = "functions"
npm run bundle
基本上是cpx 'src/**/*' 'functions/bundle'
,并且文件在functions/bundle/schema.graphql
和functions/bundle/generated/prisma.graphql
中本地可见。
我的functions/graphql.js
仅使用Express服务器并创建了一个lambda包装器:
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”非常烦人,因为它仅从项目的根目录开始起作用,因此将src/
文件复制到functions/bundle/
中会更改目录结构,并且这些导入不再起作用
在functions / bundle / index.js内部,我尝试require.resolve
一些.grapqhl类型定义文件:
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 }
});
同样,这在本地有效,因此我认为压缩文件中根本没有该文件。
我很茫然。有什么想法吗?
答案 0 :(得分:1)
您是否尝试过通过netlify functions:invoke
在netlify环境中进行本地测试?它可以帮助调试此类问题。 (请参见https://github.com/netlify/cli/blob/master/docs/netlify-dev.md#locally-testing-functions-with-netlify-functionsinvoke)
关于您的问题,似乎某些文件已被忽略,如您已经建议的那样:
Netlify将访问功能目录 在每次部署过程中,将每个受支持的代码文件压缩并部署为 AWS上的无服务器Lambda函数。 (请注意,除了一个例外, 子目录中的所有文件都将被忽略。)
要使用多个文件,您需要在functions文件夹中定义一个包含函数名称和js的文件夹,否则它将仅考虑.js文件:
您可以使用导出处理程序的独立.js文件(例如 functions / {function_name} .js)或与.js同名的文件夹 导出处理程序的文件(例如 functions / {function_name} / {function_name} .js)。
确保使用相对导入或考虑完整路径。
您还可以尝试从CLI版本2.7.0开始部署未捆绑的JavaScript。参见:https://docs.netlify.com/cli/get-started/#unbundled-javascript-function-deploys