Skip to content

Feature/demos remove system js infra - #34671

Merged
vorobey merged 13 commits into
DevExpress:feature/remove-systemjs-from-demosfrom
vorobey:feature/demos-remove-system-js-infra
Aug 6, 2026
Merged

Feature/demos remove system js infra#34671
vorobey merged 13 commits into
DevExpress:feature/remove-systemjs-from-demosfrom
vorobey:feature/demos-remove-system-js-infra

Conversation

@vorobey

@vorobey vorobey commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Part 1. Shall be merged before #34672

bit-byte0 and others added 10 commits August 5, 2026 13:34
…ss#34656)

Co-authored-by: Eldar Iusupzhanov <eldar.iusupzhanov@users.noreply.github.com>
Widget Gallery is dropping its in-browser code-editing feature
independently of this work, so this flag has no reader left anywhere in
the repo — it was purely a signal for that feature.
Replaces SystemJS's per-request in-browser transpile with real esbuild
bundling, reusing the existing CSP-check scripts as the shared core
rather than duplicating them:

- csp-bundle.js / csp-bundle-angular.js: parameterized to write
  bundle.js/bundle.css next to a demo's own source (BUNDLE_IN_PLACE)
  instead of only to the CSP-check's csp-bundled-demos/ side directory.
  Also fixes two bugs found while wiring this up: a missing
  require.main guard that made requiring csp-bundle.js trigger a full
  bundle-everything run, and the Angular AOT compiler plugin sometimes
  listing a CSS output in its esbuild metafile that it never actually
  writes to disk.
- utils/build/{build-react-vue-demo,build-angular-demo}.js: thin
  wrappers that drive the above for a single demo.
- utils/shell/server.js: lazy build-on-request — rebuilds only the
  demo being viewed when its source is newer than its bundle, so local
  dev doesn't need a pre-build/watch step over ~2,500 demos.
- utils/templates/{Angular,React,Vue}/index.html: scaffold templates
  for new demos, updated to the <script src="./bundle.js"> shape.
  Real demos get index.html regenerated by the builder itself
  (idempotent once migrated), which is why these are just the
  before-first-build placeholder.
- visual-tests-demos.yml: build-demos becomes a matrix job (React/Vue
  single-shard, Angular 3-shard, mirroring csp-check-frameworks'
  already-proven split) using BUNDLE_IN_PLACE=1 instead of the old
  `nx prepare-bundles` vendor-bundle step; testcafe-frameworks-all/
  -changed download the new per-framework/-shard artifacts and overlay
  them onto their own checkout instead of the old single vendor
  bundle; csp-check-frameworks/csp-check-jquery drop the now-moot
  CSP_USE_BUNDLED env (every demo is bundled now, there's no SystemJS
  dev mode left to compare against).
- csp-server.js: Demos/ is unconditionally the bundled, strict-CSP
  source now, so the whole SystemJS-dev-vs-csp-bundled-demos duality
  (relaxed nonce/strict-dynamic/unsafe-eval script-src, Vue's
  unsafe-inline style-src default, the SystemJS-only font-src
  allowlist entries) collapses to one profile; the csp-bundled-demos/
  routes/handler are dropped as dead code.
- csp-check.js: same simplification — always reads from Demos/.

Not yet run in real CI — drafted and diff-reviewed locally, since this
repo's demo CI can't be exercised outside GitHub Actions.
Now that every demo builds via esbuild (previous commits), delete the
SystemJS-era per-demo config.js generation and vendor-bundle pipeline
it fed:

- utils/internal/create-config.js, configs/{Angular,React,ReactJs,Vue}/
  (the SystemJS module-map templates + per-demo config.js generator —
  a real bundler resolves imports from actual `import` statements, so
  this whole system has no replacement, it's just gone)
- utils/bundle/index.js, scripts/{build-bundles,update-config}.js, and
  the now-dead `prepare-bundles` Nx target (systemjs-builder's Babel
  6/7 vendor-bundle build)
- shared/loaders/{demo-ts-loader,demo-vue-loader,demo-ts-shared}.js,
  utils/svg-loader.js (the in-browser SystemJS loader plugins)
- prepare-js-configs.js trimmed to what it still does (shared-resource
  copying) with the config-gen calls removed

Drops systemjs, systemjs-builder, systemjs-plugin-json, and
dx-systemjs-vue-browser from package.json, along with the babel-core
patch and terser override that existed solely for systemjs-builder's
Babel 6 pipeline, and the now-pointless systemjs entry in
renovate.json's ignore list. pnpm-lock.yaml regenerated accordingly
(42 packages removed); `pnpm install --frozen-lockfile` verified clean.
…collision

devextreme-angular's wrapper generator produced two different nested
options with the identical class name DxoPivotGridFieldChooserTextsComponent
and selector dxo-pivot-grid-field-chooser-texts: dxPivotGrid's own
fieldChooser.texts, and the standalone dxPivotGridFieldChooser's own
texts. The generator names classes as Dxo+parentWidgetName+optionName
with no collision detection, and "PivotGrid"+"FieldChooserTexts" ===
"PivotGridFieldChooser"+"Texts".

This was invisible under SystemJS's JIT Angular compiler, but a hard
NG8023 ambiguous-selector error under AOT — which is exactly why the
esbuild migration's PivotGrid/StandaloneFieldChooser Angular demo
(the only one combining both widgets) failed to build in the previous
commits.

Fixed at the source with a forcedName metadata override in
make-integration-metadata.ts — the same mechanism already used for
identical collisions elsewhere in that file (e.g. Toolbar.items) —
then regenerated and rebuilt devextreme-angular so the fix reaches
apps/demos/node_modules/devextreme-angular (a symlink to
packages/devextreme-angular/npm/dist, not src/ directly). Also drops
csp-bundle-angular.js's KNOWN_BROKEN_DEMOS skip-list, now that the bug
it worked around is actually fixed.
…for FieldChooserTexts rename

The forcedName metadata fix for the PivotGrid/FieldChooser texts naming
collision (58d765c) regenerated devextreme-angular but missed the
React/Vue wrappers, which the check-regenerate CI job caught.
The generated JavaScript twins of the React demos (utils/ts-to-js-converter,
`Js` output postfix) were left behind by the SystemJS migration: nothing in the
build, the dev server or CI referenced the ReactJs approach, so their
index.html still loaded system.js plus a config.js that no longer has a
producer.

- csp-bundle.js / server.js: accept ReactJs as a bundled approach. It needs no
  framework branch of its own — the shared esbuild options already map '.js' to
  the jsx loader, and only Vue takes a plugin branch.
- .prettierrc.json: drop the ReactJs-only *.html override. index.html is
  generated by the builder now, and singleAttributePerLine/printWidth 100 meant
  every in-place rebuild would leave the tree failing lint-html.
- ts-to-js-converter: exclude index.html from the converter's forced prettier
  flags. They override the config file, so the converter would otherwise reflow
  the builder's HTML on every run and make the "Check generated JS demos" job
  flap. The flags stay for the sources — prettier resolves .prettierignore from
  its cwd (the demo's own out dir), so they are load-bearing there.

The demos themselves are regenerated on the stacked branch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vorobey and others added 3 commits August 6, 2026 12:00
csp-bundle.js splits demos round-robin across CSP_SHARD_TOTAL jobs, but
csp-check.js used CSP_SHARD_* only for the Chrome debug port and the report
filename — findDemos() returned all 500 demos in every shard.

So `CSP check (React 1/2)` bundled 250 demos and then tried to check 500. The
250 belonging to the other shard have no bundle.js, so each one burned the 30s
render deadline plus a sequential retry: ~250 x 60s / 4 workers ~= 62 min
against a 60 min job timeout. Every CSP job in run 31020588268 died that way,
with the log alternating warn/ok exactly on shard parity.

findDemos() now applies the same round-robin split on the same sort key, so
shard k checks exactly the demos shard k bundled. Verified against the real
demo tree: for 2 and 3 shards the two partitions are identical, cover all 500
demos and do not overlap.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The build job uploaded its output as two glob paths
(apps/demos/Demos/**/bundle.js|css) and the TestCafe jobs downloaded it with
`path: apps/demos`. upload-artifact roots the archive at the least common
ancestor of the matched files — apps/demos/Demos — so the Demos/ segment is
not part of the artifact, and the bundles land at apps/demos/<Widget>/... one
level above where every demo's index.html looks for them. Nothing then renders,
which is the likely cause of the wholesale screenshot failures in run
31020588268 (140 comparisons failed, 1 passed, all "invalid").

Packing the bundles into a single explicit file removes the ambiguity instead
of relying on that inference: the tarball stores paths relative to apps/demos,
so extracting it there restores the exact layout (verified locally on 954
bundles). Each artifact now holds an identically named demo-bundles.tgz, so
downloads go to per-artifact directories and one unpack step extracts them all;
it fails immediately, with the constellation name, if no archive arrived —
turning a 60-minute silent timeout into an instant error.

As a bonus this uploads one file instead of ~950, which took ~4 minutes per
build job.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vorobey
vorobey merged commit d45f3bd into DevExpress:feature/remove-systemjs-from-demos Aug 6, 2026
91 checks passed
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.

4 participants