Closed
Conversation
Replace all runtime CDN imports (esm.sh, unpkg, cdnjs, jsdelivr) with locally vendored browser-ready ES modules served from vendor/. A postinstall script (scripts/vendor.mjs) copies or esbuild-bundles each dependency from node_modules into vendor/, with lockfile-hash idempotency. Vendor files are committed to git as required by EDS. - Add chart.js, chartjs plugins, rum-distiller, echarts, yaml, diff, prismjs as npm dependencies with esbuild as dev dependency - Update all import maps in optel/error-analyzer HTML files to /vendor/ - Update dynamic imports (yaml) and loadScript calls (prismjs) in JS - Remove https://esm.sh from CSP script-src in optel pages - Centralize duplicate vendored diff.js into vendor/ - Remove redundant sub-directory package.json files in optel - Configure dependabot with weekly schedule and semver-aware cooldown - Bump stylelint to 17.6.0 to match aem-boilerplate - Update AGENTS.md with vendor documentation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
trieloff
approved these changes
Apr 9, 2026
|
|
||
| ## Options Considered | ||
|
|
||
| ### Option A: Full Vendoring (esbuild + postinstall) — SELECTED |
shsteimer
added a commit
that referenced
this pull request
Apr 14, 2026
Replaces the runtime unpkg.com CDN import of `yaml` with a locally vendored copy managed via npm. Adds Renovate config with minimumReleaseAge cooldowns (3d patch / 7d minor / 30d major) and postUpgradeTasks to re-vendor on update. Closes #282 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4 tasks
Collaborator
Author
|
Superseded by #287, which implements the approach as a pilot on a single dependency (yaml) before rolling out more broadly. Switching to Renovate instead of Dependabot for equivalent cooldown support via minimumReleaseAge. |
shsteimer
added a commit
that referenced
this pull request
Apr 14, 2026
…#287) * feat(vendor): pilot yaml dependency vendoring with Renovate cooldowns Replaces the runtime unpkg.com CDN import of `yaml` with a locally vendored copy managed via npm. Adds Renovate config with minimumReleaseAge cooldowns (3d patch / 7d minor / 30d major) and postUpgradeTasks to re-vendor on update. Closes #282 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): move vendor script to project root, ignore *.mjs in hlx vendor.mjs belongs alongside other root-level tooling (package.json, .eslintrc.js) rather than scripts/, which is reserved for browser-served AEM runtime code. Also adds *.mjs to .hlxignore so tooling scripts are not served by the AEM CDN. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): move vendor.mjs into vendor/ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): exclude vendor/vendor.mjs specifically in .hlxignore Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): pin yaml dep, centralize ensureYaml in index-admin - Pin yaml dependency to exact version 2.8.3 (drop ^ range) so vendored output is always reproducible across installs - Add ensureYaml() helper in index-admin to consolidate vendor import, replacing three inline YAML = YAML || await import(...) calls; also fixes stale unpkg CDN URL on the delete path - Un-ignore vendor/vendor.mjs in .eslintignore so the vendor script is linted alongside the rest of the codebase Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): switch to esbuild bundling with postinstall + hash guard - Add esbuild (0.28.0) as devDependency; use it to bundle yaml into a single vendor/yaml.js instead of copying ~80 individual files. This is the correct pattern for deps without a pre-built browser ESM and keeps the vendoring approach consistent for future additions. - Add postinstall script so vendor files are regenerated automatically on npm install, not just via Renovate postUpgradeTasks. - Add package-lock.json hash guard (vendor/.vendor-hash) so repeated installs skip the rebuild when nothing has changed. - Update ensureYaml() import paths in index-admin and sitemap-admin to point to vendor/yaml.js. - Remove legacy vendor/yaml/ directory tree (80 files → 1 file). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): explicitly hlxignore vendor/.vendor-hash Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Apply suggestion from @claude[bot] Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> * Apply suggestion from @shsteimer * chore(vendor): use fs/promises, declarative DEPS list, write hash eagerly - Switch all fs calls to fs/promises - Replace one-off bundle/cleanup calls with a DEPS array; adding a new dep is now a single line - Write hash file before bundling (optimistic) so it sits next to the hash compare rather than at the end of the script - Bundle steps run in parallel via Promise.all - Remove legacy vendor/yaml cleanup (migration complete) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(vendor): correct ensureYaml import paths in both tools index-admin had a wrong path (vendor/yaml/yaml.js) introduced during rebase; sitemap-admin was missing the eslint-disable comment. Both now consistently import from vendor/yaml.js. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): auto-discover deps from package.json dependencies Replace hardcoded DEPS array with automatic discovery from package.json `dependencies`. esbuild resolves each package's browser entry via its exports map, so no entry point overrides are needed. Adding a new runtime dep now requires only a package.json change — vendor.mjs needs no updates. Scoped package names (@scope/name) are normalized to name.js for the output filename. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): replace auto-discovery with explicit DEPS config array Reading from package.json proved insufficient — chart.js plugins require the external option to share a module instance, which can't be expressed per-package via auto-discovery. DEPS at the top of the script is the single place to update when adding deps. The build loop is generic and never needs changing. Commented-out entries document the chart.js/rum-distiller/echarts patterns for when the full rollout happens. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): scope output files to per-package subdirectories vendor/yaml.js → vendor/yaml/yaml.js. Each vendored package now lives in its own subdirectory, consistent with how the old cpSync approach laid things out and easier to reason about when multiple deps are present. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): enable esbuild minification EDS serves committed files directly — no CDN minification step exists. Minifying at vendor time halves the yaml bundle (209KB → 101KB) at negligible build cost. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * minor updates * chore(vendor): clean stale artifacts and write hash only on success Delete vendor subdirectories before rebuilding so removed DEPS entries don't leave orphaned files. Move hash file write to after all builds complete so a failed build forces a retry on next run. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
usman-khalid
pushed a commit
that referenced
this pull request
Apr 15, 2026
…#287) * feat(vendor): pilot yaml dependency vendoring with Renovate cooldowns Replaces the runtime unpkg.com CDN import of `yaml` with a locally vendored copy managed via npm. Adds Renovate config with minimumReleaseAge cooldowns (3d patch / 7d minor / 30d major) and postUpgradeTasks to re-vendor on update. Closes #282 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): move vendor script to project root, ignore *.mjs in hlx vendor.mjs belongs alongside other root-level tooling (package.json, .eslintrc.js) rather than scripts/, which is reserved for browser-served AEM runtime code. Also adds *.mjs to .hlxignore so tooling scripts are not served by the AEM CDN. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): move vendor.mjs into vendor/ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): exclude vendor/vendor.mjs specifically in .hlxignore Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): pin yaml dep, centralize ensureYaml in index-admin - Pin yaml dependency to exact version 2.8.3 (drop ^ range) so vendored output is always reproducible across installs - Add ensureYaml() helper in index-admin to consolidate vendor import, replacing three inline YAML = YAML || await import(...) calls; also fixes stale unpkg CDN URL on the delete path - Un-ignore vendor/vendor.mjs in .eslintignore so the vendor script is linted alongside the rest of the codebase Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): switch to esbuild bundling with postinstall + hash guard - Add esbuild (0.28.0) as devDependency; use it to bundle yaml into a single vendor/yaml.js instead of copying ~80 individual files. This is the correct pattern for deps without a pre-built browser ESM and keeps the vendoring approach consistent for future additions. - Add postinstall script so vendor files are regenerated automatically on npm install, not just via Renovate postUpgradeTasks. - Add package-lock.json hash guard (vendor/.vendor-hash) so repeated installs skip the rebuild when nothing has changed. - Update ensureYaml() import paths in index-admin and sitemap-admin to point to vendor/yaml.js. - Remove legacy vendor/yaml/ directory tree (80 files → 1 file). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): explicitly hlxignore vendor/.vendor-hash Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Apply suggestion from @claude[bot] Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> * Apply suggestion from @shsteimer * chore(vendor): use fs/promises, declarative DEPS list, write hash eagerly - Switch all fs calls to fs/promises - Replace one-off bundle/cleanup calls with a DEPS array; adding a new dep is now a single line - Write hash file before bundling (optimistic) so it sits next to the hash compare rather than at the end of the script - Bundle steps run in parallel via Promise.all - Remove legacy vendor/yaml cleanup (migration complete) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(vendor): correct ensureYaml import paths in both tools index-admin had a wrong path (vendor/yaml/yaml.js) introduced during rebase; sitemap-admin was missing the eslint-disable comment. Both now consistently import from vendor/yaml.js. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): auto-discover deps from package.json dependencies Replace hardcoded DEPS array with automatic discovery from package.json `dependencies`. esbuild resolves each package's browser entry via its exports map, so no entry point overrides are needed. Adding a new runtime dep now requires only a package.json change — vendor.mjs needs no updates. Scoped package names (@scope/name) are normalized to name.js for the output filename. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): replace auto-discovery with explicit DEPS config array Reading from package.json proved insufficient — chart.js plugins require the external option to share a module instance, which can't be expressed per-package via auto-discovery. DEPS at the top of the script is the single place to update when adding deps. The build loop is generic and never needs changing. Commented-out entries document the chart.js/rum-distiller/echarts patterns for when the full rollout happens. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): scope output files to per-package subdirectories vendor/yaml.js → vendor/yaml/yaml.js. Each vendored package now lives in its own subdirectory, consistent with how the old cpSync approach laid things out and easier to reason about when multiple deps are present. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(vendor): enable esbuild minification EDS serves committed files directly — no CDN minification step exists. Minifying at vendor time halves the yaml bundle (209KB → 101KB) at negligible build cost. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * minor updates * chore(vendor): clean stale artifacts and write hash only on success Delete vendor subdirectories before rebuilding so removed DEPS entries don't leave orphaned files. Move hash file write to after all builds complete so a failed build forces a retry on next run. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
vendor/scripts/vendor.mjspostinstall hook that copies or esbuild-bundles each dependency fromnode_modules/intovendor/, with lockfile-hash idempotencyhttps://esm.shfrom CSPscript-srcin all optel pagesdiff.jscopies, remove redundant sub-directorypackage.jsonfilesSee
docs/rfc-vendor-cdn-deps.mdfor the full decision document covering all options evaluated, trade-offs, CDN comparison, and rationale.Preview
https://feat-vendor-cdn-deps--helix-tools-website--adobe.aem.page/tools/optel/oversight/cwvperf.html
Test plan
npm installon clean checkout — vendor/ files generatednpm installagain — postinstall skips (idempotent)grep -r 'unpkg\|esm\.sh\|cdnjs\|jsdelivr' --include='*.js' --include='*.html'Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
🤖 Generated with Claude Code