core icon indicating copy to clipboard operation
core copied to clipboard

fix: migrate Stencil from v2 to v4 and fix build errors

Open hmoreras opened this issue 1 month ago • 2 comments

Migrate Stencil from v2 to v4 and Fix Build Errors

Overview

This PR migrates Stencil from version 2.22.2 to 4.39.0 to resolve critical build errors and fixes TypeScript compilation issues that were introduced after the Angular 21 migration.

Problem Statement

After the Angular 21 migration, the Stencil build was failing with:

  1. Runtime Error: TypeError: Cannot read properties of null (reading 'newLine') at getNewLineCharacter - This was a bug in Stencil 2.x that prevented builds from completing
  2. TypeScript Compilation Errors:
    • Cannot find module 'primeng/api'
    • Cannot find module '@angular/common/http'
    • These errors occurred because Stencil builds couldn't resolve types from Angular/PrimeNG dependencies

Solution

1. Stencil Migration (v2 → v4)

Upgraded Dependencies:

  • @stencil/core: ^2.22.2^4.39.0
  • @stencil/sass: ^2.0.3^3.2.3
  • @nxext/stencil: 20.1.021.0.0

Configuration Updates:

  • Removed deprecated configuration options
  • Fixed duplicate outputTargets in dotcms-field-elements/stencil.config.ts
  • Verified no deprecated @Prop context/connect usage (none found)

Migration References:

2. Type Declaration Stubs

Created type declaration stubs (stencil-types.d.ts) for both Stencil projects to provide TypeScript type information for external dependencies that aren't available during the Stencil build:

  • @angular/common/http: Stub declarations for HttpClient, HttpRequest, HttpResponse, HttpErrorResponse, HttpEvent, HttpEventType, HttpParams, HttpHeaders
  • primeng/api: Stub declarations for MenuItem, MenuItemCommandEvent, SelectItem

Why This Approach?

  • Web components should be framework-agnostic and not bundle Angular/PrimeNG code
  • These dependencies are only needed for type checking, not runtime
  • Stencil builds web components independently, and these external dependencies shouldn't be included in the final bundle
  • This is a standard TypeScript pattern using declare module

Files Created:

  • libs/dotcms-webcomponents/stencil-types.d.ts
  • libs/dotcms-field-elements/stencil-types.d.ts

3. TypeScript Configuration Updates

Updated tsconfig.json files:

  • Added skipLibCheck: true to ignore type errors in declaration files
  • Excluded e2e test files (**/*.e2e.ts, **/*.e2e.tsx) from builds
  • Updated include paths to reference type declaration files
  • Added types: ["node"] for proper type resolution

Files Modified:

  • libs/dotcms-webcomponents/tsconfig.json
  • libs/dotcms-field-elements/tsconfig.json

4. Type-Only Imports

Converted regular imports to import type for type-only usage to prevent runtime dependencies:

Files Modified:

  • libs/dotcms-models/src/lib/dot-action-menu-item.model.ts
  • libs/dotcms-models/src/lib/dot-apps.model.ts
  • libs/dotcms-models/src/lib/dot-experiments.model.ts
  • libs/dotcms-js/src/lib/core/util/http-response-util.ts
  • libs/dotcms-js/src/lib/core/login.service.ts

5. Babel Runtime Module Resolution

Problem: Build was failing with Module not found: Error: Can't resolve '@babel/runtime/helpers/esm/asyncToGenerator.js' because the build system was looking for @babel/runtime in a nested location.

Solution:

  • Added @babel/runtime@^7.28.4 as a direct dependency
  • Added npm overrides to ensure proper module hoisting:
    "overrides": {
        "@babel/runtime": "^7.28.4"
    }
    

6. Additional Fixes

MCP Server Module Resolution:

  • Fixed ESM subpath imports by adding .js extensions:
    • @modelcontextprotocol/sdk/server/mcp@modelcontextprotocol/sdk/server/mcp.js
    • @modelcontextprotocol/sdk/shared/protocol@modelcontextprotocol/sdk/shared/protocol.js
    • @modelcontextprotocol/sdk/types@modelcontextprotocol/sdk/types.js

SCSS @extend Issues:

  • Added !optional flag to @extend #form-field-disabled in _autocomplete.scss
  • Added @use "common"; at the top of form/index.scss to ensure proper import order

Type Definitions:

  • Added @types/minimatch@^5.1.2 for Stencil build compatibility

Testing

All builds now succeed:

  • nx run dotcms-webcomponents:build - ✅ Success
  • nx run dotcms-field-elements:build - ✅ Success (with type stubs)
  • nx run dotcdn:build - ✅ Success
  • nx run mcp-server:build:production - ✅ Success
  • nx run sdk-angular:build:production - ✅ Success

Breaking Changes

None. This is a bug fix and migration that maintains backward compatibility.

Migration Notes

  • The type declaration stubs are minimal and only include the types actually used
  • If new Angular/PrimeNG types are needed in the future, they should be added to the stubs
  • The Stencil 4 migration follows official migration guides and maintains all existing functionality

Related Issues

  • Resolves Stencil runtime error: TypeError: Cannot read properties of null (reading 'newLine')
  • Resolves TypeScript compilation errors for primeng/api and @angular/common/http
  • Resolves Babel runtime module resolution issues
  • Resolves MCP server module resolution issues

Documentation

  • Updated libs/dotcms-webcomponents/STENCIL_TYPES_APPROACH.md with migration details and current status

This PR fixes: #33882

hmoreras avatar Dec 11 '25 01:12 hmoreras

Semgrep found 1 ssc-2427bad3-7619-448f-8f95-70806990606e finding:

Risk: Affected versions of @angular/compiler are vulnerable to Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'). A stored XSS vulnerability in the Angular Template Compiler arises because its internal security schema doesn't classify certain URL‐ holding attributes (e.g. xlink:href, math|href, annotation|href) or the attributeName binding on SVG animation elements (<animate>, <set>, etc.) as requiring strict URL sanitization. An attacker who can supply untrusted input to template bindings like [attr.xlink:href] or <animate [attributeName]="'href'" [values]="maliciousURL"> can inject a javascript: URL payload. When the element is activated (e.g. clicked) or the animation runs, the malicious script executes in the application's origin, enabling session hijacking, data exfiltration, or unauthorized actions.

Manual Review Advice: A vulnerability from this advisory is reachable if you allow SVG/MathML attributes (e.g., xlink:href, href) or to the attributeName field of SVG animation tags (, , etc.) in HTML templates

Fix: Upgrade this library to at least version 19.2.17 at core/core-web/package-lock.json:28647.

Reference(s): https://github.com/advisories/GHSA-v4hv-rgfq-gp49, CVE-2025-66412

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Semgrep found 1 ssc-4e59e976-8886-47a3-9b32-abcb3212a6c1 finding:

Risk: http-cache-semantics versions before 4.1.1 are vulnerable to Inefficient Regular Expression Complexity leading to Denial of Service. The issue can be exploited via malicious request header values sent to a server, when that server reads the cache policy from the request using this library.

Fix: Upgrade this library to at least version 4.1.1 at core/core-web/package-lock.json:43120.

Reference(s): https://github.com/advisories/GHSA-rc47-6667-2j5j, CVE-2022-25881

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Legal Risk

The following dependencies were released under a license that has been flagged by your organization for consideration.

Recommendation

While merging is not directly blocked, it's best to pause and consider what it means to use this license before continuing. If you are unsure, reach out to your security team or Semgrep admin to address this issue.

GPL-2.0

MPL-2.0