You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何搭建简易Serverless Framework Monorepo(无Lerna等工具)

单仓库多Serverless服务搭建与Webpack依赖分离方案

你的思路完全可行——不依赖大型Monorepo工具,通过根目录统一管理共享依赖、服务目录隔离专属代码的方式,既能保持项目简洁,又能实现统一打包部署。以下是具体实现步骤:


一、项目初始化与目录搭建

1. 根目录初始化

# 创建项目根目录并初始化
mkdir serverless-mono && cd serverless-mono
npm init -y

# 安装所有共享开发/运行依赖
npm install --save-dev serverless serverless-compose typescript webpack webpack-cli serverless-webpack eslint prettier husky
npm install --save aws-sdk # 若Lambda运行时已内置可改为--save-dev

2. 构建目标目录结构

手动创建或通过命令生成目录:

# 创建共享代码目录与服务目录
mkdir shared services/services-a services/services-b

# 为每个服务创建核心文件
touch services/services-a/serverless.yml services/services-a/src/handler.ts
touch services/services-b/serverless.yml services/services-b/src/handler.ts

最终目录结构与你规划的完全一致。


二、Serverless Compose 统一部署配置

在根目录创建serverless-compose.yml,定义所有服务的路径:

services:
  service-a:
    path: services/service-a
    # 可添加统一环境变量等全局配置
    environment:
      NODE_ENV: ${sls:stage}
  service-b:
    path: services/service-b
    environment:
      NODE_ENV: ${sls:stage}

后续通过serverless deploy即可一键部署所有服务,或通过serverless deploy --service service-a单独部署指定服务。


三、Webpack 配置与依赖分离

核心目标:让Webpack打包时自动区分根目录共享依赖和服务专属依赖,避免重复打包冗余代码。

1. 根目录通用Webpack配置

创建webpack.config.js,配置如下:

const path = require('path');
const slsw = require('serverless-webpack');
const nodeExternals = require('webpack-node-externals');

module.exports = {
  entry: slsw.lib.entries,
  target: 'node',
  mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
  externals: [
    nodeExternals({
      // 排除根目录共享的运行依赖(若需打包进服务则删除对应项)
      allowlist: ['aws-sdk']
    }),
    // 排除Lambda内置依赖,避免打包
    'aws-sdk'
  ],
  resolve: {
    // 优先从根目录node_modules找共享依赖,再找服务专属依赖
    modules: [path.resolve(__dirname, 'node_modules'), './node_modules'],
    extensions: ['.ts', '.js'],
    // 配置共享代码别名,方便服务引用
    alias: {
      '@shared': path.resolve(__dirname, 'shared')
    }
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: 'ts-loader',
        exclude: [/node_modules/, /services\/.*\/node_modules/]
      }
    ]
  },
  output: {
    libraryTarget: 'commonjs2',
    path: path.resolve(__dirname, '.webpack'),
    filename: '[name].js'
  }
};

2. 服务端Webpack插件配置

在每个服务的serverless.yml中引入serverless-webpack插件,并指向根目录配置:

service: service-a
frameworkVersion: '3'

plugins:
  - serverless-webpack

custom:
  webpack:
    webpackConfig: '../../webpack.config.js'
    includeModules: false # 禁用自动打包node_modules,由我们手动控制
    packager: 'npm'

provider:
  name: aws
  runtime: nodejs20.x
  region: us-east-1

functions:
  hello:
    handler: src/handler.hello
    events:
      - httpApi:
          path: /hello
          method: get

3. 依赖分离关键操作

  • 共享依赖:所有跨服务通用的开发工具(如typescript、webpack)和运行依赖(如axios、lodash)统一安装在根目录。
  • 专属依赖:仅服务自身需要的依赖,通过指定--prefix安装到对应服务目录:
    # 为service-a安装专属依赖stripe
    npm install stripe --save --prefix services/service-a
    

Webpack会自动识别服务目录的node_modules,将专属依赖打包进服务bundle,而共享依赖仅在必要时打包(或通过externals排除)。


四、配套工具配置

1. TypeScript 配置

根目录tsconfig.json覆盖所有服务与共享代码:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "outDir": "./dist",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "baseUrl": ".",
    "paths": {
      "@shared/*": ["shared/*"]
    }
  },
  "include": ["shared/**/*", "services/**/src/**/*"],
  "exclude": ["node_modules", "services/**/node_modules"]
}

2. 代码规范与提交钩子

  • 根目录配置.eslintrc.js和.prettierrc,自动覆盖所有服务目录。
  • 初始化Husky钩子,确保提交代码前自动检查规范:
    npx husky install
    npx husky add .husky/pre-commit "npx eslint . --fix"
    

思路验证

你的方案非常适合服务数量较少、追求轻量化的场景。唯一需要注意的是:若后续服务数量激增,共享运行依赖的重复打包会导致部署包体积增大,此时再考虑引入Turborepo等轻量Monorepo工具即可。当前方案无需额外学习成本,完全满足简洁性与统一性的需求。

内容的提问来源于stack exchange,提问作者Stepan Yudin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:30:41