我正试图在TypeScript中编写谷歌云函数的代码。其思想是,源仓库将具有为多个云函数定义的处理程序函数,每个函数在不同的文件中,以及由所有处理程序共享的一些代码。我可以用tsc编译我的源代码,但我需要webpack它们来生成一个云函数将加载的单个index.js
。所以我需要webpack将这些处理程序合并到一个文件中。
这是我的tsconfig.json
:
{
"compilerOptions": {
"incremental": true,
"target": "es2016",
"module": "commonjs",
"sourceMap": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"noImplicitAny": true,
"noImplicitThis": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node"
},
"include": ["src/**/*.ts"]
}
以下是src/TheHandler.ts
中一个处理程序的代码:
import { EventFunction } from "@google-cloud/functions-framework";
export const TheHandler: EventFunction = (
message,
context
) => {
console.log(message);
console.log(context);
};
编译成JavaScript没有问题。
现在我把它输入webpack。这是我的webpack.config.js
:
const path = require("path");
const fs = require("fs");
const nodeExternals = require("webpack-node-externals");
const files = fs
.readdirSync("src")
.filter((item) => item.match(/.ts$/))
.map((file) => `./src/${file}`);
module.exports = {
mode: "production",
entry: files,
externalsPresets: { node: true },
externals: [nodeExternals()],
module: {
rules: [
{
test: /.ts$/,
use: "ts-loader",
exclude: /node_modules/,
},
],
},
resolve: {
extensions: [".ts"],
},
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist"),
},
};
这导致dist/bundle.js
为空,由webpack输出确认:
asset bundle.js 0 bytes [compared for emit] [minimized] (name: main)
./src/TheHandler.ts 612 bytes [built] [code generated]
webpack 5.50.0 compiled successfully in 1937 ms
这是模块格式问题还是webpack试图在ts-loader编译src/TheHandler.ts
之前捆绑一切?还有别的吗?
我必须在webpack.config.js
中添加libraryTarget: "commonjs2"
和output
。
正如你所发现的,你需要设置libraryTarget
来构建一个webpack bundle,它本身可以被webpack构建之外的另一个模块导入(例如从云函数)。
使用webpack-cloud-functions(我是作者),您可能会更轻松(并且在可靠的HMR方面有更好的开发人员体验)。它抽象了使用webpack和云功能所需的大部分配置,包括配置libraryTarget
。