-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Rax Compat CSS Import Tilde Transform #7121
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
Open
wssgcg1213
wants to merge
7
commits into
master
Choose a base branch
from
fix/rax-compat-support
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+59
−3
Open
Changes from 2 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
637f24a
fix: rax compat support ~ in css
wssgcg1213 41cbaa9
chore: add changeset
wssgcg1213 837946a
fix: css in ~
wssgcg1213 2c40f39
fix: remove useless files
wssgcg1213 f5005af
chore: delete 2 useless files
wssgcg1213 6c59827
chore: rax-compat@0.4.1
wssgcg1213 71fd26f
chore: update changelogs for rax-compat plugin
wssgcg1213 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@ice/plugin-rax-compat': patch | ||
| --- | ||
|
|
||
| Support css build |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| /* 示例:CSS 中使用波浪号导入语法 */ | ||
|
|
||
| /* 导入第三方包的样式 */ | ||
| @import "~@ali/fusion-design/theme.css"; | ||
| @import "~antd/dist/antd.css"; | ||
|
|
||
| /* 导入内部包的样式 */ | ||
| @import "~@company/design-system/tokens.css"; | ||
| @import '~@internal/shared-styles/base.css'; | ||
|
|
||
| /* 常规导入(不受影响) */ | ||
| @import "./local-styles.css"; | ||
| @import url("https://cdn.example.com/remote.css"); | ||
|
|
||
| /* 组件样式 */ | ||
| .example-component { | ||
| color: var(--primary-color); | ||
| font-size: 16px; | ||
| } | ||
|
|
||
| .example-component:hover { | ||
| color: var(--primary-hover-color); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| # CSS Import Tilde Transform | ||
|
|
||
| ## 功能概述 | ||
|
|
||
| 这个功能添加了对 CSS 中 `~` 引入语法的支持,将 `@import "~@ali/xxx"` 自动转换为 `@import "@ali/xxx"`,以兼容 esbuild 的模块解析。 | ||
|
|
||
| **注意:** webpack 本身已经支持 `~` 语法,所以客户端构建不需要额外处理。 | ||
|
|
||
| ## 实现方式 | ||
|
|
||
| ### 1. 服务端渲染(SSR/SSG)- ESBuild 插件 | ||
|
|
||
| **文件:** `esbuildCSSImportPlugin.ts` | ||
|
|
||
| - 在 esbuild 构建过程中拦截 CSS 文件 | ||
| - 对包含 `~` 引入语法的文件进行转换 | ||
| - 优先级设置在 CSS 模块处理之前 | ||
|
|
||
| ### 2. 内联样式处理 | ||
|
|
||
| **文件:** `transform-styles.ts` | ||
|
|
||
| - 在 `styleSheetLoader` 函数中直接处理转换 | ||
| - 支持所有样式文件类型:CSS、LESS、SASS/SCSS | ||
|
|
||
| ## 转换规则 | ||
|
|
||
| | 输入格式 | 输出格式 | | ||
| |---------|---------| | ||
| | `@import "~@ali/package/style.css"` | `@import "@ali/package/style.css"` | | ||
| | `@import '~@company/design/tokens.css'` | `@import '@company/design/tokens.css'` | | ||
|
|
||
| ## 使用场景 | ||
|
|
||
| 1. **第三方包引入** | ||
| ```css | ||
| @import "~@ali/fusion-design/style.css"; | ||
| @import "~antd/dist/antd.css"; | ||
| ``` | ||
|
|
||
| 2. **内部包引入** | ||
| ```css | ||
| @import "~@company/design-system/tokens.css"; | ||
| @import "~@internal/shared-styles/base.css"; | ||
| ``` | ||
|
|
||
| ## 注意事项 | ||
|
|
||
| 1. **仅影响 esbuild 构建**:webpack 本身支持 `~` 语法,所以只在服务端渲染(使用 esbuild)时需要转换 | ||
| 2. 只转换 `@import` 语句中的 `~` 语法 | ||
| 3. 保持引号类型不变(单引号或双引号) | ||
| 4. 不影响其他类型的导入语句 | ||
| 5. 兼容现有的相对路径和绝对路径导入 | ||
|
|
||
| ## 测试 | ||
|
|
||
| 运行测试文件 `cssImportTransform.test.ts` 验证功能正常工作: | ||
|
|
||
| ```bash | ||
| npm test -- src/services/styles/__tests__/cssImportTransform.test.ts | ||
| ``` |
84 changes: 84 additions & 0 deletions
84
packages/plugin-rax-compat/src/services/styles/__tests__/cssImportTransform.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| import { describe, it, expect } from 'vitest'; | ||
| import styleSheetLoader from '../../../lib/transform-styles.js'; | ||
|
|
||
| describe('CSS Import Tilde Transform for ESBuild', () => { | ||
| it('should transform @import with tilde syntax in CSS', async () => { | ||
| const input = ` | ||
| @import "~@ali/some-package/style.css"; | ||
| @import '~@company/design-system/tokens.css'; | ||
| .test { | ||
| color: red; | ||
| } | ||
| `; | ||
|
|
||
| const result = await styleSheetLoader(input, '/fake/path/test.css', 'css'); | ||
|
|
||
| // The result should be JavaScript module code for inline styles | ||
| expect(result).toContain('module.exports = _styles'); | ||
|
|
||
| // We can't easily test the exact transformation here since it goes through | ||
| // the CSS parser, but we can verify it doesn't throw an error | ||
| expect(result).toBeDefined(); | ||
| }); | ||
|
|
||
| it('should transform @import with tilde syntax in LESS', async () => { | ||
| const input = ` | ||
| @import "~@ali/some-package/variables.less"; | ||
| @color: #333; | ||
| .test { | ||
| color: @color; | ||
| } | ||
| `; | ||
|
|
||
| const result = await styleSheetLoader(input, '/fake/path/test.less', 'less'); | ||
|
|
||
| expect(result).toContain('module.exports = _styles'); | ||
| expect(result).toBeDefined(); | ||
| }); | ||
|
|
||
| it('should transform @import with tilde syntax in SASS/SCSS', async () => { | ||
| const input = ` | ||
| @import "~@ali/some-package/variables.scss"; | ||
| $color: #333; | ||
| .test { | ||
| color: $color; | ||
| } | ||
| `; | ||
|
|
||
| const result = await styleSheetLoader(input, '/fake/path/test.scss', 'scss'); | ||
|
|
||
| expect(result).toContain('module.exports = _styles'); | ||
| expect(result).toBeDefined(); | ||
| }); | ||
|
|
||
| it('should handle mixed import styles', async () => { | ||
| const input = ` | ||
| @import "~@ali/package/style.css"; | ||
| @import "./local-style.css"; | ||
| @import url("https://example.com/remote.css"); | ||
| .test { | ||
| color: blue; | ||
| } | ||
| `; | ||
|
|
||
| const result = await styleSheetLoader(input, '/fake/path/test.css', 'css'); | ||
|
|
||
| expect(result).toContain('module.exports = _styles'); | ||
| expect(result).toBeDefined(); | ||
| }); | ||
|
|
||
| it('should not transform non-tilde imports', async () => { | ||
| const input = ` | ||
| @import "./local-style.css"; | ||
| @import url("https://example.com/remote.css"); | ||
| .test { | ||
| color: green; | ||
| } | ||
| `; | ||
|
|
||
| const result = await styleSheetLoader(input, '/fake/path/test.css', 'css'); | ||
|
|
||
| expect(result).toContain('module.exports = _styles'); | ||
| expect(result).toBeDefined(); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
packages/plugin-rax-compat/src/services/styles/esbuildCSSImportPlugin.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import fs from 'fs'; | ||
| import type { ESBuildPlugin } from '../../typings'; | ||
|
|
||
| /** | ||
| * ESBuild plugin to transform CSS imports with tilde (~) syntax | ||
| * Converts @import "~@ali/xxx" to @import "@ali/xxx" | ||
| * | ||
| * Note: This plugin only handles CSS files that are not processed by the inline style plugin. | ||
| * For inline styles, the transformation is handled in transform-styles.ts | ||
| */ | ||
| export const createCSSImportPlugin = (): ESBuildPlugin => { | ||
| return { | ||
| name: 'esbuild-css-import-tilde', | ||
| setup: (build) => { | ||
| // Handle CSS files that are processed by esbuild's default CSS loader | ||
| // (not by our inline style plugin) | ||
| build.onLoad({ filter: /\.css$/ }, async (args) => { | ||
| try { | ||
| const source = await fs.promises.readFile(args.path, 'utf8'); | ||
|
|
||
| // Check if this CSS contains tilde imports | ||
| if (!source.includes('@import "~') && !source.includes("@import '~")) { | ||
| // No tilde imports found, let default processing handle it | ||
| return null; | ||
| } | ||
|
|
||
| // Transform @import "~..." to @import "..." | ||
| const transformedContent = source.replace( | ||
| /@import\s+(['"])~([^'"]+)\1/g, | ||
| '@import $1$2$1', | ||
| ); | ||
|
|
||
| return { | ||
| contents: transformedContent, | ||
| loader: 'css', | ||
| }; | ||
| } catch (error) { | ||
| return { | ||
| errors: [{ | ||
| text: `Failed to process CSS imports: ${error.message}`, | ||
| location: { file: args.path }, | ||
| }], | ||
| }; | ||
| } | ||
| }); | ||
| }, | ||
| }; | ||
| }; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.