Panda CSS 如何让 `.js/.mjs/.cjs` 文件中的 JSX 样式被正确提取:解析 “Unexpected JSX expression“ 修复的底层原理 前端构建工具开发工具【免费下载链接】panda Universal, Type-Safe, CSS-in-JS Framework for Design Systems ⚡️项目地址https://gitcode.com/gh_mirrors/pa/panda点击查看免费下载导读Panda CSS 在其编译器pandacss/compiler的一次 patch 级别更新中修复了一个影响混合 JavaScript/JSX 项目的典型问题当样式代码以 JSX 形式出现在.js、.mjs、.cjs这类非 TSX 扩展名文件里时编译器此前会抛出Unexpected JSX expression警告并导致这些文件中的样式无法被提取。本文以该变更集为线索结合仓库源码梳理问题成因、修复机制以及你在实际项目中如何正确使用这一能力读完可以理解 Panda CSS 的 JSX 提取开关是如何按文件扩展名决策的并能安全地在纯 JS 文件中书写样式。变更集说了什么一次针对 JSX-in-JS 的编译器修复本次变更记录在 .changeset/jsx-in-js-files.md原文如下--- pandacss/compiler: patch --- Fix Unexpected JSX expression warnings for JSX inside .js, .mjs and .cjs files. Styles in those files are now extracted.拆解这条变更信息可以提炼出三个关键事实影响包与级别pandacss/compiler为patch修复性、向后兼容不引入破坏性变更修复对象Unexpected JSX expression警告触发场景是 JSX 代码出现在.js、.mjs、.cjs扩展名文件里修复结果这些文件中的样式如css({ ... })、styled()、pattern 工厂等调用现在能够被正常提取并生成 CSS。在纯 TypeScript / TSX 工程中JSX 提取早已可用问题恰恰出在文件扩展名不带x、但内容却包含 JSX的混合场景——这正是本次变更集的边界所在。为什么会出现 Unexpected JSX expression 警告Panda CSS 的样式提取器Rust 实现位于crates/pandacss_extractor基于 Oxc 解析器工作。Oxc 在解析源码之前需要确定该文件的SourceType而SourceType直接决定了是否启用 JSX 语法模式解析器处于非 JSX 模式时一旦遇到开头的 JSX 表达式例如div css{...}就会产生类似Unexpected JSX expression的语法错误编译器把这些语法错误以warning的形式暴露出来不会立即中止编译但对应的文件会被跳过或部分跳过导致其中书写的 Panda CSS 样式调用无法进入提取流程最终表现为样式没有被生成。从源码结构看这是由 crates/pandacss_extractor/src/adapter.rs 中的source_type决策逻辑与文件扩展名共同决定的.vue/.svelte只有在script langtsx时按 TSX 解析Astro/MDX 始终按 TSX 解析其余情况则走source_type_from_path按扩展名推断。修复的底层实现JS 文件现在以 JSX 模式解析本次修复的核心改动体现在 crates/pandacss_extractor/src/adapter.rs 的source_type_from_path函数中pub(crate) fn source_type_from_path(path: impl AsRefstd::path::Path) - SourceType { SourceType::from_path(path).map_or_else( |_| SourceType::tsx(), |source_type| { if source_type.is_javascript() { source_type.with_jsx(true) } else { source_type } }, ) }这段实现的关键逻辑是优先让 Oxc 依据路径推断SourceType当推断结果是 JavaScript.js、.mjs、.cjs时调用with_jsx(true)显式打开 JSX 模式只有非 JavaScript 类型才保持原样因此.ts、.tsx等文件的既有解析行为不受影响。也就是说修复后.js、.mjs、.cjs三类文件都以JavaScript JSX的复合模式参与解析Unexpected JSX expression警告随之消失文件内的样式调用得以进入后续提取阶段。这也是变更集标题jsx-in-js-files的字面含义让 JSX 出现在 JS 文件中成为合法且可提取的输入。同时提取器的跨文件扫描白名单也完整覆盖了这些扩展名。crates/pandacss_extractor/src/cross_file.rs 中可以看到扩展名列表[.tsx, .ts, .jsx, .mjs, .cjs, .js, .json]说明.mjs/.cjs与.js一样处于跨文件样式解析的扫描范围内修复后的 JSX 提取能够与跨文件追踪机制协同工作。JSX 提取的总开关jsxFramework配置需要强调的是修复按文件启用 JSX 解析并不等于无条件提取所有 JSX。是否真正收集 JSX 样式还取决于项目的jsxFramework配置。提取器在 crates/pandacss_extractor/src/extract.rs 中通过should_collect_jsx判断其实现为config.has_jsx_framework见 crates/pandacss_extractor/src/extract.rsfn should_collect_jsx(config: ExtractorConfig) - bool { config.has_jsx_framework }对应的配置入口在 crates/pandacss_extractor/src/matcher.rsMatcher持有has_jsx_framework字段并提供with_jsx_framework(enabled)与with_jsx(jsx)构建方法。项目级配置即为panda.config.ts中的jsxFramework选项可选值包括react、solid、vue、preact等参见仓库各 sandbox 配置如 sandbox/vite-ts/panda.config.ts 的用法。从源码看两者配合的关系可以总结为条件行为未配置jsxFrameworkhas_jsx_framework falseJSX 相关匹配MatchCategory::Jsx被过滤样式不会被收集配置了jsxFramework且文件为.js/.mjs/.cjs文件以 JSX 模式解析本次修复且 JSX 提取开关已打开样式正常提取配置了jsxFramework且文件为.ts/.tsx/.jsx原本就支持 JSX 提取行为不变此外 crates/pandacss_extractor/src/jsx.rs 的extract_jsx入口同样以if !config.has_jsx_framework作为短路条件进一步印证了框架开关与文件级解析模式是两层独立的机制修复解决的是解析层问题而是否提取仍由配置层决定。在实际项目中安全使用在.js/.mjs/.cjs中写 Panda 样式结合上述机制如果你想在纯 JS或 CommonJS/ESM 变体文件中使用 JSX 形态的 Panda CSS API需要满足以下前提项目配置了jsxFramework。以 React 为例在 panda.config.ts 中声明import { defineConfig } from pandacss/dev export default defineConfig({ // 启用 JSX 提取的总开关react / solid / vue / preact 等 jsxFramework: react, include: [./src/**/*.{js,jsx,ts,tsx,mjs,cjs}], // ...其余配置 })include覆盖这些扩展名。include指定参与扫描的文件范围需要把.js/.mjs/.cjs纳入其中否则文件根本不会进入提取流程。在 JS 文件中正常书写 JSX 样式。修复之后下面这类代码不再触发Unexpected JSX expression警告样式会被正确提取// styles.mjs —— 注意这是纯 JS 文件却包含 JSX import { styled } from ../styled-system/jsx export const Button styled(button, { base: { padding: 8px 16px, borderRadius: md, }, variants: { color: { primary: { bg: blue.500, color: white }, ghost: { bg: transparent }, }, }, defaultVariants: { color: primary }, })// app.js —— 直接使用 css() 或 pattern 工厂 import { css } from ../styled-system/css export function Card({ title }) { return div className{css({ p: 4, rounded: lg, shadow: md })}{title}/div }需要注意的是该修复让解析与提取环节对 JS 文件中的 JSX 生效但这并不改变JSX 最终仍由你的构建工具Babel/SWC/esbuild 等转译这一事实Panda CSS 的职责是静态分析源码并产出样式层两者互不冲突。验证方式与回归保障仓库中与该机制相关的测试覆盖可以从以下几个文件入手继续研究crates/pandacss_extractor/tests/jsx.rsJSX 提取相关的断言与快照覆盖 JSX 属性、constant folding、AST 展开等场景crates/pandacss_extractor/src/adapter.rs测试SfcFormat::from_path对Card.ts/Card.tsx/Card.jsx/Card.vue.ts等文件一律返回None确认脚本文件不会误判为 SFC 容器crates/pandacss_extractor/src/cross_file.rs跨文件扫描扩展名白名单。个人验证的最快路径是在配置了jsxFramework的沙箱项目如 sandbox/vite-ts中新建一个.mjs文件写入 JSX 样式运行pnpm pandacodegen/cssgen检查控制台不再输出Unexpected JSX expression警告生成的styles.css中出现了对应类名与样式规则。升级与使用前提小结本次变更随pandacss/compiler的 patch 版本发布属于非破坏性修复正常升级即可获得修复生效的完整链路是文件扩展名 ∈.js/.mjs/.cjs解析层按 JSX 模式 项目配置jsxFramework提取层开关开启include覆盖对应扩展名扫描层准入若你的项目全部使用.tsx或.jsx本次修复不改变既有行为无需额外配置若你在 JS 文件中仍看到 JSX 相关警告请优先确认jsxFramework是否已正确配置——该警告也可能来源于转译工具本身而非 Panda CSS 提取器。总体上这是一次小而关键的兼容性修复它让 Panda CSS 的Universal、Type-Safe、CSS-in-JS理念在多语言、多扩展名的真实工程中更进一步——样式可以书写在任何一个含有 JSX 的文件里而不再受扩展名命名规则的隐性约束。赞分享前端构建工具开发工具【免费下载链接】panda Universal, Type-Safe, CSS-in-JS Framework for Design Systems ⚡️项目地址https://gitcode.com/gh_mirrors/pa/panda点击查看免费下载相关推荐Panda CSS v2 jsxMatchTag 深度解析用声明式规则精确控制 JSX 样式属性提取Panda CSS v2 jsxMatchTag 深度解析用声明式规则精确控制 JSX 样式属性提取 导读 jsxMatchTag 是 Panda CSS v前端构建工具开发工具eslint-plugin-react 的 react/jsx-uses-react 规则详解让 ESLint 正确识别被 JSX 隐式使用的 Reacteslint plugin react 的 react/jsx uses react 规则详解让 ESLint 正确识别被 JSX 隐式使用的 React 导开发工具代码质量静态分析Panda CSS 生成器系统解析CSS、JS、JSX 代码生成的艺术Panda CSS 生成器系统解析CSS、JS、JSX 代码生成的艺术 Panda CSS 是一款革命性的 CSS in JS 框架通过其强大的生成器系统将前端构建工具开发工具上一篇深入 Rome 的 JavaScript 解析器 rome_js_parser无损、容错、可定制的 ECMAScript 解析架构与测试指南下一篇WindowsCleaner三分钟解决Windows系统空间不足的专业方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考