Skip to content

fix: include esbuild build output assets in packages#13628

Open
puneetdixit200 wants to merge 1 commit into
serverless:mainfrom
puneetdixit200:fix-13163-esbuild-build-assets
Open

fix: include esbuild build output assets in packages#13628
puneetdixit200 wants to merge 1 commit into
serverless:mainfrom
puneetdixit200:fix-13163-esbuild-build-assets

Conversation

@puneetdixit200

@puneetdixit200 puneetdixit200 commented Jun 4, 2026

Copy link
Copy Markdown

Closes: #13163

This updates the native esbuild packaging step to include additional files emitted into .serverless/build, such as assets copied by esbuild plugins, while still skipping generated package metadata, lockfiles, node_modules, handlers, and sourcemaps that are already added explicitly.

The new unit coverage verifies both service-wide packaging and individually packaged functions include copied build output files in the final zip.

AI assistance was used while drafting this patch; I reviewed the diff and verified the results below.

Targeted checks run:

  • npm run test:unit -w @serverless/framework -- test/unit/lib/plugins/esbuild/index.test.js --runInBand
  • npx prettier -c packages/serverless/lib/plugins/esbuild/index.js packages/serverless/test/unit/lib/plugins/esbuild/index.test.js
  • npx eslint packages/serverless/lib/plugins/esbuild/index.js packages/serverless/test/unit/lib/plugins/esbuild/index.test.js
  • git diff --check

Summary by CodeRabbit

  • Bug Fixes

    • Improved esbuild output packaging to ensure build artifacts are correctly included in ZIP files without duplicates during both individual and combined function packaging.
  • Tests

    • Added comprehensive unit tests verifying build artifacts and sourcemaps are properly packaged in generated ZIP files.

@Mmarzex

Mmarzex commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR refactors esbuild packaging to centralize the inclusion of build artifacts and track which files are already added to prevent duplication. A new helper method adds all esbuild outputs from .serverless/build to the ZIP, while per-function and all-functions packaging modes now share deduplication logic via an addedFiles set that skips redundant user-specified patterns.

Changes

Esbuild packaging artifact deduplication

Layer / File(s) Summary
New helper for adding build artifacts to zip
packages/serverless/lib/plugins/esbuild/index.js
Added _addBuildFilesToZip(zip, addedFiles) helper that globs all files under .serverless/build (excluding node_modules and package/lockfiles), adds each file to the zip by relative path, and tracks both absolute and relative paths in addedFiles to prevent duplication.
Per-function packaging refactor
packages/serverless/lib/plugins/esbuild/index.js
Updated _package() method to initialize an addedFiles set, record inclusion of build/package.json, lockfiles, compiled handler, and optional sourcemap, then delegate remaining build artifacts to _addBuildFilesToZip. When adding user package.patterns, skips files whose absolute paths already exist in addedFiles and records newly-added files.
All-functions packaging refactor
packages/serverless/lib/plugins/esbuild/index.js
Updated _packageAll() method to delegate build artifact inclusion to _addBuildFilesToZip and to skip adding files from package.patterns when their absolute paths already exist in addedFiles.
Test coverage for packaging behavior
packages/serverless/test/unit/lib/plugins/esbuild/index.test.js
Added Jest test suite for the Esbuild plugin with temporary directory setup, build artifact emission helpers, and test cases verifying that _packageAll() and _package() (including individually packaged functions) include handlers, sourcemaps, locales, worker locales, and other build outputs in generated ZIPs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • serverless/serverless#13507: Modifies where esbuild plugin's packaged zip artifacts are written, complementing this PR's refactor of how zip assembly works internally.

Poem

🐰 With dedup logic and helpers new,
Build artifacts now flow right through!
No more lost locales or stray JSON,
The esbuild plugin marches on. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: include esbuild build output assets in packages' directly and clearly describes the main change: ensuring esbuild-generated assets are included in package zips.
Linked Issues check ✅ Passed The code changes successfully implement the core requirement from issue #13163: esbuild output files in .serverless/build (e.g., JSON locales, assets) are now included in packages via the new _addBuildFilesToZip helper, with proper exclusions for node_modules and package metadata.
Out of Scope Changes check ✅ Passed All changes are directly related to the scope: the _addBuildFilesToZip helper and its integration into _package and _packageAll methods focus solely on including esbuild build artifacts, with comprehensive unit tests validating the functionality.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/serverless/lib/plugins/esbuild/index.js`:
- Around line 855-872: The loop that adds include patterns currently only checks
addedFiles.has(absolutePath) so files already added from the build dir can be
duplicated when the zip entry name (path relative to service/build, e.g.
"src/locales/en.json") collides; update the logic in the functions
_addBuildFilesToZip, _package, and _packageAll to compute the zip entry name
(the relative path used in zip.file/zip.directory) for each matched file and
check addedFiles.has(entryName) in addition to addedFiles.has(absolutePath)
before adding; when adding a file, add both the absolutePath and the entryName
to addedFiles so subsequent iterations (from build artifacts or
package.patterns) properly dedupe by the zip entry name.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 42ec9086-e12d-4751-880f-ebafd56bb372

📥 Commits

Reviewing files that changed from the base of the PR and between 94663bd and 1052a92.

📒 Files selected for processing (2)
  • packages/serverless/lib/plugins/esbuild/index.js
  • packages/serverless/test/unit/lib/plugins/esbuild/index.test.js

Comment on lines 855 to 872
await Promise.all(
includesToPackage.map(async (filePath) => {
const absolutePath = path.join(
this.serverless.config.serviceDir,
filePath,
)
if (addedFiles.has(absolutePath)) {
return
}
const stats = await stat(absolutePath)
if (stats.isDirectory()) {
zip.directory(absolutePath, filePath)
} else {
zip.file(absolutePath, { name: filePath })
addedFiles.add(absolutePath)
}
}),
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Dedup against build artifacts misses zip-entry-name collisions, allowing duplicate entries.

_addBuildFilesToZip adds build files using their path relative to the build dir as the zip entry name (e.g. src/locales/en.json) and tracks both the absolute path and that relative name in addedFiles. But this user-patterns loop only checks addedFiles.has(absolutePath), where absolutePath is rooted at serviceDir, not .serverless/build. When a user package.patterns entry matches a source file that esbuild also copied into the build dir (e.g. src/** matching src/locales/en.json — exactly the locale-asset case from #13163), the two absolute paths differ, so the file is added a second time under the same zip entry name, producing a duplicate entry in the artifact.

The relative name is already tracked precisely to catch this, but it's never consulted. The same gap exists in _packageAll at Lines 995-1009.

🐛 Proposed fix — also check the relative entry name

In _package (Lines 861-863):

-                  if (addedFiles.has(absolutePath)) {
-                    return
-                  }
+                  if (addedFiles.has(absolutePath) || addedFiles.has(filePath)) {
+                    return
+                  }

In _packageAll (Lines 998-1000):

-            if (addedFiles.has(absolutePath)) {
-              return
-            }
+            if (addedFiles.has(absolutePath) || addedFiles.has(filePath)) {
+              return
+            }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/serverless/lib/plugins/esbuild/index.js` around lines 855 - 872, The
loop that adds include patterns currently only checks
addedFiles.has(absolutePath) so files already added from the build dir can be
duplicated when the zip entry name (path relative to service/build, e.g.
"src/locales/en.json") collides; update the logic in the functions
_addBuildFilesToZip, _package, and _packageAll to compute the zip entry name
(the relative path used in zip.file/zip.directory) for each matched file and
check addedFiles.has(entryName) in addition to addedFiles.has(absolutePath)
before adding; when adding a file, add both the absolutePath and the entryName
to addedFiles so subsequent iterations (from build artifacts or
package.patterns) properly dedupe by the zip entry name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Include esbuild files besides the handler

2 participants