-
-
Notifications
You must be signed in to change notification settings - Fork 10
feat: support non identifier classnames #309
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: support non identifier classnames #309
Conversation
|
96d2d6f to
3e6cbfb
Compare
|
Great work! This is a big change. I'll review it carefully. It may take some time. |
|
FYI: CSS Modules Kit has flaky tests (#301). Even if your implementation is correct, CI may fail. |
|
Looking back at the code, I noticed there was unnecessary code and deleted it 🙏 |
|
@apple-yagi I've made some changes to the main branch—could you please merge or rebase the main branch?
|
It certainly looks like a bit of complex code. I'll think deeply about whether there's a way to replace it with simpler code. |
81f5cfb to
76ca2ba
Compare
76ca2ba to
1340313
Compare
|
@mizdra I believe all functions are now working correctly after fixing the bug in rename. |
…#309 This is the issue fixed in mizdra#317.
| return result; | ||
| } | ||
|
|
||
| export function getDefinitionAndBoundSpan( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly, I still don't understand what this function is trying to do. Is it doing something that contributes to supporting non-identifier classnames?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When type definitions are made into string literals, tsserver cannot return definitions (it might be a bug in some tool, but I don't know). Therefore, I am manually mapping the definitions(I had Codex write the code).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, shouldn't we investigate that bug first? If it's a dependency bug and fixable, fixing it is the best approach.
If the dependency bug is difficult to fix or would take a long time to resolve, I think implementing a workaround to bypass it is worthwhile. Otherwise, I'd prefer to avoid implementing a complex workaround.
I'll investigate this bug. At this stage, I suspect it's a bug in tsserver or Volar.js.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree.
While organizing the discussion, I thought of another implementation method, so I'll create a new Pull Request and commit step by step. When defining types with string literals, I feel that single quotes are also recognized as part of the type. That might be a specification of tsserver (I briefly read the tsserver implementation but couldn't quite understand it).
With that in mind, I'll try implementing it using tsserver.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I refactored dts-generator.ts to avoid breaking the code (1340313...12f5b4b). Additionally, I fixed the regression (c4dbe5b). As a result, it seems adding new mappings is no longer necessary.
By the way, you explained the following in #309 (comment):
As an implementation issue, the logic has become complex because we needed to manage mappings doubly
What does "managing mappings doubly" mean? Does it mean one more element is added to the mapping array? Looking at the changes in dts-generator.ts, it doesn't appear that any additional elements are being added to the mapping array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mizdra Sorry, Initially, when I submitted the PR, I thought that both quoted and unquoted mappings were necessary for string literals like styles['a-1'], because tsserver returns spans including quotes
css-modules-kit/packages/core/src/dts-generator.ts
Lines 262 to 275 in 96d2d6f
| text += ` '`; | |
| mapping.sourceOffsets.push(token.loc.start.offset); | |
| const quoteStart = base + 2; | |
| const keyStart = base + 3; | |
| mapping.generatedOffsets.push(quoteStart); | |
| mapping.lengths.push(token.name.length); | |
| // Include quotes and `:` so string-literal ranges map correctly. | |
| mapping.generatedLengths!.push(token.name.length + 3); | |
| // Map the inner content so rename ranges without quotes still resolve. | |
| mapping.sourceOffsets.push(token.loc.start.offset); | |
| mapping.generatedOffsets.push(keyStart); | |
| mapping.lengths.push(token.name.length); | |
| mapping.generatedLengths!.push(token.name.length); | |
| text += `${token.name}': '' as readonly string,\n`; |
However, I realized that go-to-definition works even without double mapping because getDefinitionAndBoundSpan normalizes def.name and replaces it with the CSS location (https://github.com/apple-yagi/css-modules-kit/blob/c4dbe5b554281a3501ec0cb6544cbc62875e6ba6/packages/ts-plugin/src/language-service/feature/definition-and-bound-span.ts#L110-L132). Therefore, I removed it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incidentally, performing double mapping allows tsserver's getDefinitionAndBoundSpan to work partially correctly. For example, jumps for styles.a_1; or styles['a-1']; work correctly (this was my original idea). However, bugs occur with duplicate class names like styles.a_2, @import, @value ... from '...';, and symbol renaming, making the implementation increasingly complex.
Background
At a social gathering after a certain study session held in Fukuoka the other day, the topic of css-modules-kit came up. At that time, I heard that css-modules-kit does not allow kebab-case, so I couldn't use it. I investigated whether it was not allowed, and found that it was, so I submitted a PR.
Description
I have modified it to generate type definitions using string literals, referring to #177. This allows defining classnames that are not JS identifiers.
Since namedExports can only use JS identifiers, this will only support defaultExports.
As an implementation issue, the logic has become complex because we needed to manage mappings doubly (one for definition jumps and one for renaming) (this change caused various bugs).
While I believe this feature addition is good for the further adoption of css-modules-kit, I also want to avoid making the code so complex that it becomes unmaintainable in the long run. I would like to respect mizdra's opinion on this 🙏
Related issues
#176
AI Assistance
This PR was written with assistance from Codex (ChatGPT).