From 9ac85f8cc0c5842617df797752da7bc6dfbc8628 Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Mon, 5 Oct 2026 20:29:48 -0400 Subject: [PATCH 1/3] fix: #284 ignore javascript from sucrase transformations --- src/wcc.js | 33 ++++++++++++------- .../compiled-javascript.spec.js | 27 +++++++++++++++ .../src/contentful-error.js | 9 +++++ test/cases/compiled-javascript/src/index.js | 9 +++++ 4 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 test/cases/compiled-javascript/compiled-javascript.spec.js create mode 100644 test/cases/compiled-javascript/src/contentful-error.js create mode 100644 test/cases/compiled-javascript/src/index.js diff --git a/src/wcc.js b/src/wcc.js index 3aed9a2a..af3c634c 100644 --- a/src/wcc.js +++ b/src/wcc.js @@ -9,6 +9,23 @@ import { serialize } from 'parse5'; import { transform } from 'sucrase'; import fs from 'fs'; +function transformModule(moduleURL, moduleContents) { + const extension = moduleURL.pathname.split('.').pop(); + + // `.js`, `.mjs`, and `.cjs` modules do not need to be transformed by Sucrase, + // and in fact doing so can break valid JavaScript syntax. + // https://github.com/ProjectEvergreen/wcc/issues/284 + if (!['jsx', 'ts', 'tsx'].includes(extension)) { + return moduleContents; + } + + return transform(moduleContents, { + transforms: ['typescript', 'jsx'], + jsxRuntime: 'automatic', + production: true, + }).code; +} + function isCustomElementDefinitionNode(node) { const { expression } = node; @@ -79,11 +96,7 @@ async function renderComponentRoots(tree, definitions) { function registerDependencies(moduleURL, definitions, depth = 0) { const moduleContents = fs.readFileSync(moduleURL, 'utf-8'); - const result = transform(moduleContents, { - transforms: ['typescript', 'jsx'], - jsxRuntime: 'automatic', - production: true, - }); + const moduleCode = transformModule(moduleURL, moduleContents); const nextDepth = (depth += 1); const customParser = getParser(moduleURL); const parser = customParser ? customParser.parser : acorn.Parser; @@ -94,7 +107,7 @@ function registerDependencies(moduleURL, definitions, depth = 0) { }; walk.simple( - parser.parse(result.code, { + parser.parse(moduleCode, { ecmaVersion: 'latest', sourceType: 'module', }), @@ -142,11 +155,7 @@ function registerDependencies(moduleURL, definitions, depth = 0) { async function getTagName(moduleURL) { const moduleContents = await fs.promises.readFile(moduleURL, 'utf-8'); - const result = transform(moduleContents, { - transforms: ['typescript', 'jsx'], - jsxRuntime: 'automatic', - production: true, - }); + const moduleCode = transformModule(moduleURL, moduleContents); const customParser = getParser(moduleURL); const parser = customParser ? customParser.parser : acorn.Parser; const config = customParser @@ -157,7 +166,7 @@ async function getTagName(moduleURL) { let tagName; walk.simple( - parser.parse(result.code, { + parser.parse(moduleCode, { ecmaVersion: 'latest', sourceType: 'module', }), diff --git a/test/cases/compiled-javascript/compiled-javascript.spec.js b/test/cases/compiled-javascript/compiled-javascript.spec.js new file mode 100644 index 00000000..33012704 --- /dev/null +++ b/test/cases/compiled-javascript/compiled-javascript.spec.js @@ -0,0 +1,27 @@ +/* + * Use Case + * Run WCC against a custom element that imports already-compiled JavaScript. + * + * User Result + * Should parse the dependency without passing it through Sucrase. + * + * User Workspace + * src/ + * contentful-error.js + * index.js + */ +import { expect } from 'chai'; +import { renderToString } from '../../../src/wcc.js'; + +// https://github.com/ProjectEvergreen/wcc/issues/284 +describe('Run WCC For ', function () { + const LABEL = 'Custom Element with a JavaScript dependency'; + + describe(LABEL, function () { + it('should not transform compiled JavaScript dependencies', async function () { + const { html } = await renderToString(new URL('./src/index.js', import.meta.url)); + + expect(html).to.contain('Compiled JavaScript parsed successfully'); + }); + }); +}); diff --git a/test/cases/compiled-javascript/src/contentful-error.js b/test/cases/compiled-javascript/src/contentful-error.js new file mode 100644 index 00000000..e9e53b2a --- /dev/null +++ b/test/cases/compiled-javascript/src/contentful-error.js @@ -0,0 +1,9 @@ +// This combination of an initialized class field and a comma expression after super() is valid JavaScript. +// Passing it through Sucrase inserts the field initializer before the comma, producing syntax that Acorn cannot parse. +export class ContentfulError extends Error { + name = 'ContentfulError'; + + constructor(message, linkType) { + (super(message), (this.linkType = linkType)); + } +} diff --git a/test/cases/compiled-javascript/src/index.js b/test/cases/compiled-javascript/src/index.js new file mode 100644 index 00000000..80a7a543 --- /dev/null +++ b/test/cases/compiled-javascript/src/index.js @@ -0,0 +1,9 @@ +import './contentful-error.js'; + +export default class CompiledJavaScriptElement extends HTMLElement { + connectedCallback() { + this.innerHTML = '

Compiled JavaScript parsed successfully

'; + } +} + +customElements.define('wcc-compiled-javascript', CompiledJavaScriptElement); From e07f139b4ca0a0f4be41a6a8bf39ff9519c43b42 Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Mon, 5 Oct 2026 21:09:52 -0400 Subject: [PATCH 2/3] fix: #284 refactor condition --- src/wcc.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wcc.js b/src/wcc.js index af3c634c..a75be23c 100644 --- a/src/wcc.js +++ b/src/wcc.js @@ -12,10 +12,10 @@ import fs from 'fs'; function transformModule(moduleURL, moduleContents) { const extension = moduleURL.pathname.split('.').pop(); - // `.js`, `.mjs`, and `.cjs` modules do not need to be transformed by Sucrase, + // Plain JavaScript files (`.js`, `.mjs`, and `.cjs`) do not need to be transformed by Sucrase, // and in fact doing so can break valid JavaScript syntax. // https://github.com/ProjectEvergreen/wcc/issues/284 - if (!['jsx', 'ts', 'tsx'].includes(extension)) { + if (['js', 'mjs', 'cjs'].includes(extension)) { return moduleContents; } From 3268f13dde72a9cd7d9334835b92ac3725cec47b Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Sat, 10 Oct 2026 11:30:19 -0400 Subject: [PATCH 3/3] fix: #284 revert refactor --- src/wcc.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/wcc.js b/src/wcc.js index a75be23c..18dbddc8 100644 --- a/src/wcc.js +++ b/src/wcc.js @@ -12,10 +12,12 @@ import fs from 'fs'; function transformModule(moduleURL, moduleContents) { const extension = moduleURL.pathname.split('.').pop(); - // Plain JavaScript files (`.js`, `.mjs`, and `.cjs`) do not need to be transformed by Sucrase, + // `.js`, `.mjs`, and `.cjs` modules do not need to be transformed by Sucrase, // and in fact doing so can break valid JavaScript syntax. // https://github.com/ProjectEvergreen/wcc/issues/284 - if (['js', 'mjs', 'cjs'].includes(extension)) { + // Note: this introduces a dis-connect between what WCC can parse vs what it can execute + // https://github.com/ProjectEvergreen/wcc/discussions/226 + if (!['jsx', 'ts', 'tsx'].includes(extension)) { return moduleContents; }