Skip to content

Conversation

yashank676
Copy link

@yashank676 yashank676 commented Oct 9, 2025

Details

/\b(track|api|wire)\b/ tests false if track is with ANSI escape codes for color output in terminals e.g. \033[31;1;4mtrack\033[0m

Does this pull request introduce a breaking change?

  • 😮‍💨 No, it does not introduce a breaking change.

Does this pull request introduce an observable change?

  • 🔬 Yes, it does include an observable change.
  • The user will now get LWC1198 error instead of LWC1007 for Babel decorator error consistently.

@yashank676 yashank676 requested a review from a team as a code owner October 9, 2025 14:24
Copy link

salesforce-cla bot commented Oct 9, 2025

Thanks for the contribution! It looks like @yashank-aggarwal_sfemu is an internal user so signing the CLA is not required. However, we need to confirm this.

@wjhsf
Copy link
Contributor

wjhsf commented Oct 9, 2025

What is the motivation for this change? Please also add some test cases to demonstrate the changed behavior.

@yashank676
Copy link
Author

yashank676 commented Oct 10, 2025

@wjhsf The regex condition present was not able to search for the decorator due to ANSI format of the error code given to match, in cases like eg it was able to match the regex due to import statement present and hence threw 1198 error
but if we have anything else added after import statement (try adding a comment eg), the regex wont be able to match and 1007 error would be thrown which caused inconsistency.

@wjhsf
Copy link
Contributor

wjhsf commented Oct 10, 2025

When the LWC compiler encounters a babel error, it checks the message for the LWC decorators (api/track/wire), and provides a more helpful message if encountered (LWC1198, rather than LWC1007). However, it checks using regex word boundaries (\b), and babel uses ANSI escape codes (\x1b[39m) for formatting the how the error message is printed to console, causing the regex to sometimes report false, even though an LWC decorator is used. For example, \x1b[33m@\x1b[39mapi prints @api with a yellow @. This is a scenario that we should capture, but do not.

The actual decorator usage that causes the error seems to always be preceded by a color token. However, babel includes a few lines of code as context prior to the erroneous decorator usage. This means that whether we get LWC1198 or LWC1007 is dependent on that context. For example, if the context includes import { api } from 'lwc', then we will get LWC1198. If not, we will get LWC1007. This behavior is inconsistent and confusing.


Consider this class, which is not a component:

import { eschatology } from 'vermont'
export default class Bananaphone {
  @eschatology biggens
}

With the proposed change, the above code will fail to compile with "Error: SyntaxError: LWC1198: Decorators like @api, @track, and @wire are only supported in LightningElement classes." That's misleading, because neither the decorators nor LightningElement are involved in this scenario.

A better fix, here, would be to update the regex to account for the possibility of ANSI escape codes, so that we still only add the LWC context when actually relevant. We should not rely on any specific codes being present, as babel may change the color of their output at any time.

@yashank676
Copy link
Author

Agreed to all the points, i am already looking into it and see if some regex can be made to handle that.

@yashank676
Copy link
Author

@wjhsf i have updated the regex. Also, looks like updating unit test for this makes no sense as the issue we faced in previous regex was due to ANSI format in error, but in vitest it was a simple string error instead.

(e as any).message?.includes('Decorators are not enabled.') &&
/\b(track|api|wire)\b/.test((e as any).message) // sniff for @track/@api/@wire
// eslint-disable-next-line no-control-regex -- Intentionally matching ANSI escape sequences
/@[\x1b[0-9;m]*(track|api|wire)\b/.test((e as any).message)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is brittle. Please just remove the \b from the original regex and it should be enough.

Copy link
Author

Choose a reason for hiding this comment

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

@abdulsattar agreed that would also work but there could be a case like following:

import { eschatology } from 'vermont'
export default class Bananaphone {
  @eschatology wire
}

then this also throws 1198 instead of 1007 due to wire/api/track being the variable name.

Copy link
Author

Choose a reason for hiding this comment

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

or even something that contains any of these words would lead to 1198.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I imagined it would be the case. But, it's an acceptable trade-off. At worst, users are getting a little generic error (which is still related to decorators).

Copy link
Author

Choose a reason for hiding this comment

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

sure, let me update it then.

Copy link
Contributor

@wjhsf wjhsf Oct 14, 2025

Choose a reason for hiding this comment

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

The full sequence, as returned by the ansi-regex npm package, is /(?:\u001B\][\s\S]*?(?:\u0007|\u001B\u005C|\u009C))|[\u001B\u009B][[\]()#;?]*(?:\d{1,4}(?:[;:]\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]/g.

Using that is definitely overkill for our use case. I think we should keep the original check, but relax it if we see the escape character (\x1b). We don't really care if the escape codes are properly formatted or not. The regex to accomplish this would be /(?:\b|\x1b\S*?)(api|wire|track)\b/.

Yashank Aggarwal and others added 2 commits October 14, 2025 21:08
Copy link

Thanks for the contribution! Before we can merge this, we need @yashank676 to sign the Salesforce Inc. Contributor License Agreement.

@abdulsattar abdulsattar changed the title fix: remove unnecessary regex check for decorator detection fix: remove word boundaries from decorator check regex Oct 14, 2025
@wjhsf
Copy link
Contributor

wjhsf commented Oct 14, 2025

@yashank676 please make sure the CLA is signed and add two test cases to packages/@lwc/compiler/src/transformers/__tests__/transform-javascript.spec.ts.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants