如何使用`serverless 将符号链接打包到node_modules 中?

Zha*_* Yi 4 aws-lambda serverless-framework yarnpkg yarn-workspaces

我正在用来serverless打包nodejs应用程序。yarn workspace我在我的项目中使用。

- common
- projectA
- projectB
Run Code Online (Sandbox Code Playgroud)

和正在使用由 管理的projectA模块。它在内部创建一个链接。但是当我用 打包应用程序时,它不包含链接。我怎样才能让它打包符号链接?projectBcommonyarn workspacenode_modules/common -> ../commonsls deploynode_modules/common

Pat*_*ski 5

您应该开始使用代码捆绑器。

什么是代码捆绑器?

代码捆绑器的作用:

  1. 它会从处理程序文件开始扫描所有文件中的 AWS Lambda 代码结构。
  2. 它会遍历所有导入以创建依赖关系树。
  3. 然后它将所有这些依赖项内联到单个“胖”文件中。
  4. 之后,您可以自由部署您的应用程序,该应用程序只有一个文件。

如您所见,它与 AWS Lambda 和您的用例完美匹配。

包中的所有依赖项都common将包含在输出文件中。

此外,代码捆绑器还有其他很酷的功能,例如删除所有不需要的文件,这些文件是在您使用的库中定义的,但您不直接使用它们。由于这个输出包的大小,你的 Lambda 会小很多,这会减少冷启动。

如何使用无服务器框架实现这一目标

最简单的方法是从serverless-webpack插件开始,其中包括 Webpack(最流行的代码捆绑器之一)及其一些最常见的配置。

添加此插件后,只需在以下位置进行配置serverless.yml

custom:
  webpack:
    webpackConfig: 'webpack.config.js'   # you can remove it, it's the same as default
    packager: 'yarn'
Run Code Online (Sandbox Code Playgroud)

现在您需要使用webpack.config.js文件配置 Webpack。配置它的可能性有很多种,下面的示例是最基本的:

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

module.exports = {
  entry: slsw.lib.entries,
  target: 'node',
  mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
  stats: 'minimal',
  devtool: 'nosources-source-map',
  externals: [{'aws-sdk': 'commonjs aws-sdk'}],
  resolve: {
    extensions: ['.js', '.json'],
  },
  output: {
    libraryTarget: 'commonjs2',
    path: path.join(__dirname, '.webpack'),
    filename: '[name].js',
    sourceMapFilename: '[file].map',
  },
};
Run Code Online (Sandbox Code Playgroud)

现在,当您调用sls packageprojectAprojectB然后解压缩后 ./.serverless/functionName.zip,您将发现只有一个“胖”文件,其中包含所有必需的依赖项。

在此sls deploy阶段,此文件将部署为 Lambda 处理程序。

正确定义依赖关系

确保该common包被列为projectA和的依赖项projectB

// common/package.json

{
  "name": "@your-project/common",
  "version": "1.0.0",
  "license": "ISC",
}

// projectA/package.json

{
  "name": "@your-project/packageA",
  "version": "1.0.0",
  "license": "ISC",
  "dependencies": {
      "@your-project/common": "1.0.0"
  }
}
Run Code Online (Sandbox Code Playgroud)

因此,您将能够通过以下方式引用 pakcageA 导入中的公共资源:

import exampleHelper from '@your-project/common/src/exampleHelper';
Run Code Online (Sandbox Code Playgroud)

使用这种方法的项目可以在我的 Github 上找到:

https://github.com/PatrykMilewski/serverless-series

  • @AndréPena 没问题!我个人的最佳实践也发生了一些变化。查看 serverless-esbuild 插件。捆绑大小相同,但捆绑过程快了约 100 倍,而且需要的配置也少得多。如果您愿意,可以在这里查看我的一个示例:https://github.com/PatrykMilewski/serverless-monorepo-template/tree/master/stacks/first (2认同)