我刚刚重写了一个Node.js GraphQL API,从旧版本的 graphql-yoga + prisma改成了使用 express、serverless-http、prisma和apollo-server-express。我已经让它在本地作为一个Express应用程序工作得很好,但是当我试图让它作为Function发布到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-imports, 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 "超级烦人,因为它只在项目的根目录下工作,所以复制 "graphql-import src/
文件到 functions/bundle/
改变了目录结构,这些导入不再起作用在functionsbundleindex.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 }
});
同样的,这在本地工作,所以我认为这个文件是直接从压缩文件中丢失的。
我很迷茫。有什么好办法吗?
你有没有试过在本地测试,但通过netlify环境进行测试?netlify functions:invoke
? 它可以帮助调试此类问题。(见 https:/github.comnetlifycliblobmasterdocsnetlify-dev.md#locally-testing-function-with-netlify-functioninvoke。)
关于你的问题,似乎某些文件被忽略了,你已经建议了。
Netlify会在每次部署过程中访问函数目录,将每个支持的代码文件压缩并部署为AWS上的无服务器Lambda函数。注意,除了一个例外,子目录中的任何文件都将被忽略)。
要使用多个文件,您需要在您的函数文件夹中定义一个文件夹,其中包含函数名称和js,否则它将只考虑.js文件。
你可以使用一个独立的.js文件来导出处理程序(例如function{function_name}.js),也可以使用一个与.js文件同名的文件夹来导出处理程序(例如function{function_name}{function_name}.js)。
确保使用相对导入或考虑全路径。
另外,你也可以尝试从CLI 2.7.0版本开始部署未捆绑的JavaScript。请看 https:/docs.netlify.comcliget-started#unbundled-javascript-function-deploys。