- 前端
【免费下载链接】emotion
👩🎤 CSS-in-JS library designed for high performance style composition
导读
import-from-emotion是 @emotion/eslint-plugin 提供的一条专用于迁移场景的 ESLint 规则。它负责拦截从react-emotion包中导入非styled的导出,并自动把导入改写为从emotion(或@emotion/styled)直接引入,帮助团队在 Emotion 10/11 升级过程中一键完成 import 语句的批量修正。读完本文,你将掌握该规则的触发条件、自动修复逻辑、底层实现原理,以及如何在项目中开启它完成迁移。
一、规则背景:为什么要从 react-emotion 迁移出来
在 Emotion 10 及更高版本中,react-emotion这个旧包不再被推荐使用,其导出也不再转发(re-export)自emotion。这意味着import { css } from 'react-emotion'这样的旧写法在 Emotion 10+ 中无法再取到emotion核心包的能力。
因此,官方推荐在 React 应用中直接使用emotion包(或按用途拆分后的@emotion/*子包),而不是react-emotion。import-from-emotion规则正是为此而生:它只允许从react-emotion导入styled(这是唯一被保留的场景),其余导出一律报错并给出修复方案。
说明:该规则文档原文位于 import-from-emotion.md,是 Emotion 官方 ESLint 插件文档体系的组成部分。
二、规则的判定逻辑:什么算错误,什么算正确
判定条件
规则会在每次遇到ImportDeclaration(ES 模块导入语句)时检查两件事(见 import-from-emotion.ts):
- 导入来源(
node.source.value)是否等于'react-emotion'; - 导入说明符(specifiers)中是否存在非默认导入(即不是
import x from ...这种ImportDefaultSpecifier)。
两个条件同时满足时即触发incorrectImport报错。
不正确的写法
import { css } from 'react-emotion'该规则会报告错误,提示信息为:
emotion's exports should be imported directly from emotion rather than from react-emotion
正确的写法
import { css } from 'emotion'直接从emotion包导入核心导出(css、keyframes、injectGlobal等),不会触发任何告警。
三、自动修复:fixer 的分支逻辑
import-from-emotion的meta.fixable被标记为'code',也就是说它支持 ESLint 的--fix自动修复,大部分场景下你无需手工改动任何代码。修复逻辑在 import-from-emotion.ts 中按导入说明符的类型分为三种分支:
分支 1:命名空间导入(import * as ...)——不修复
import * as emotion from 'react-emotion'由于无法确定命名空间对象里需要重写到哪个包,fixer直接返回null,即只报错、不自动修复,需要开发者手工处理。
分支 2:同时存在默认导入与命名导入——拆分为两条语句
import styled, { css } from 'react-emotion'自动修复后变为:
import styled from '@emotion/styled'; import { css } from 'emotion';styled(默认导入)被拆分到@emotion/styled,其余命名导入进入emotion。实现上利用了"默认导入说明符永远排在第一位"这一 AST 特性(源码注释default specifiers are always first),并将命名导入逐个处理:
- 若本地名与导入名一致(如
css),直接输出css; - 若使用了别名(如
import { css as somethingElse }),则输出css as somethingElse,完整保留别名语义。
分支 3:仅命名导入——仅改写来源字符串
import { css } from 'react-emotion'自动修复后变为:
import { css } from 'emotion'这里直接调用fixer.replaceText(node.source, "'emotion'"),只替换来源字符串,最轻量。
一个可验证的修复案例
在测试文件 import-from-emotion.test.ts 中,别名场景的期望输出为:
// 输入 import styled, { css as somethingElse } from 'react-emotion' // --fix 输出 import styled from '@emotion/styled'; import { css as somethingElse } from 'emotion';四、如何在项目中启用该规则
1. 安装
先安装 ESLint,再安装插件(见 README.md):
$ npm i eslint --save-dev $ npm install @emotion/eslint-plugin --save-dev注意:若你的 ESLint 是全局安装的(
-g标志),@emotion/eslint-plugin也必须全局安装,否则无法解析。
2. 配置 .eslintrc
在 plugins 中注册@emotion(可省略/eslint-plugin后缀):
{ "plugins": ["@emotion"] }在 rules 中开启该规则:
{ "rules": { "@emotion/import-from-emotion": "error" } }3. 与其他迁移规则组合使用
官方在 README 中给出了 Emotion 10 迁移期的推荐组合,import-from-emotion只是其中之一:
{ "rules": { "@emotion/jsx-import": "error", "@emotion/no-vanilla": "error", "@emotion/import-from-emotion": "error", "@emotion/styled-import": "error" } }相关规则各有分工,均可在迁移后继续保留(例如jsx-import可以保证使用 css prop 时自动引入jsx):
- jsx-import:确保
@emotion/react的jsx被导入(在 css prop 场景下自动补齐@jsx jsx声明); - styled-import:确保
styled从@emotion/styled导入而不是从react-emotion; - no-vanilla:禁用对
emotion(vanilla 版本)的导入,适合使用 React 的应用。
官方同时提醒:这些规则默认假设你在使用 React;如果你不使用 React,应继续使用
emotion包,此时不应开启no-vanilla等规则。
五、源码实现细节:规则是如何注册与分发的
规则元信息
从源码 import-from-emotion.ts 可以看到,规则使用@typescript-eslint/utils的ESLintUtils.RuleCreator创建,元信息包括:
docs.description:确保 styled 从@emotion/styled导入;docs.recommended: false:不属于推荐的默认开启规则,需要显式配置;fixable: 'code':支持自动修复;schema: []:不接收任何配置选项;type: 'problem':属于"代码有问题"类规则。
在插件中的注册位置
该规则在 packages/eslint-plugin/src/index.ts 中被导入并以'import-from-emotion'为键注册。同插件还导出no-vanilla、syntax-preference、styled-import、jsx-import、pkg-renaming五条规则,覆盖了样式语法偏好、包名重命名等更多场景。
错误报告的元信息 URL
规则通过utils.ts中的createRule(见 utils.ts)生成指向对应文档的错误报告链接,便于开发者点击后跳转到当前规则说明页排查问题。
六、测试用例验证
测试文件 import-from-emotion.test.ts 使用RuleTester验证了以下四类场景:
| 场景 | 输入 | 期望结果 |
|---|---|---|
| 合法 | import { css } from 'emotion' | 不报错(valid) |
| 仅命名导入 | import { css } from 'react-emotion' | 报incorrectImport,修复为从emotion导入 |
| 默认 + 命名导入 | import styled, { css } from 'react-emotion' | 拆分为两条 import |
| 别名导入 | import styled, { css as somethingElse } from 'react-emotion' | 保留别名,拆分为两条 import |
这些用例同时验证了规则"错误报告 + 自动修复"的完整行为,也是你升级后回归测试的好素材。
七、使用建议与注意事项
- 优先使用
--fix或编辑器自动修复:规则本身的设计目标就是"可自动修复",文档也明确说明你通常无需手工改动; - 迁移后无需急于移除:即使完成迁移,继续保留
import-from-emotion也可以防止有人重新写回react-emotion的旧导入; - 注意命名空间导入的边界:
import * as emotion from 'react-emotion'这类写法规则只报错不修复,需要手工处理; - 先了解项目是否使用 React:若项目不用 React,应继续使用 vanilla
emotion包,此时不应启用针对 React 生态的迁移规则; - 结合 codemod 使用:插件还内置了 Emotion 11 的
pkg-renaming规则(见 README.md),如需跨大版本迁移可一并参考。
通过以上配置与理解,你可以安全地把import-from-emotion纳入 CI 与本地 lint 流程,让 Emotion 10/11 的升级迁移变得可自动化、可回归、可追溯。
- 前端
【免费下载链接】emotion
👩🎤 CSS-in-JS library designed for high performance style composition
相关推荐
深入理解IRust的工作原理:从代码执行到结果输出
深入理解IRust的工作原理:从代码执行到结果输出 IRust是一款跨平台的Rust交互式解释器(REPL),它让开发者能够实时编写、测试和运行Rust代码片段
前端Puck 编辑器 iframe 内注入 Emotion Cache:@puckeditor/plugin-emotion-cache 插件实战与源码解析
Puck 编辑器 iframe 内注入 Emotion Cache:@puckeditor/plugin emotion cache 插件实战与源码解析 导读
前端低代码UI组件UmiJS x Emotion:基于官方 with-emotion 示例的 Emotion 集成实战指南
UmiJS x Emotion:基于官方 with emotion 示例的 Emotion 集成实战指南 UmiJS 官方仓库内置了一个名为 with emot
前端Web框架CLI构建工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考