feat(mdxish): support library imports in declarations#1530
Conversation
WalkthroughThis PR adds support for resolving ESM Changes
Sequence Diagram(s)sequenceDiagram
participant EvaluateExports
participant CollectImportValues
participant EvaluateSandbox
EvaluateExports->>EvaluateExports: traverse estreeBody nodes
EvaluateExports->>EvaluateExports: collect ImportDeclaration nodes
EvaluateExports->>CollectImportValues: importDeclarations
CollectImportValues-->>EvaluateExports: importValues (resolved bindings)
EvaluateExports->>EvaluateSandbox: evaluate(program, {React, ...importValues})
EvaluateSandbox-->>EvaluateExports: exported scope
Related PRs: None identified. Suggested labels: enhancement, mdxish Suggested reviewers: None identified. 🐰 A rabbit hops through import lines, Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
__tests__/lib/mdxish/exports.test.ts (1)
326-335: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTest doesn't assert the warning it's named after.
The test title says it "warns," but nothing spies on
console.warnto confirm that. It would still pass if the warning behavior regressed.✅ Suggested addition
it('warns and skips an unsupported library without breaking the rest of the doc', () => { + const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {}); const md = `import { clamp } from 'lodash'; export const greeting = "hi"; {greeting}`; const html = mix(md); expect(html).not.toContain('import {'); expect(html).toContain('hi'); + expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('lodash')); + warnSpy.mockRestore(); });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@__tests__/lib/mdxish/exports.test.ts` around lines 326 - 335, The test named in exports.test.ts for handling an unsupported library currently only checks that mix() skips the import and preserves the rest of the doc, but it never verifies the “warns” part of the behavior. Update this test to spy on console.warn around the mix(md) call and assert that a warning is emitted for the unsupported lodash import, while keeping the existing output assertions intact so the test covers both the warning and the skip behavior.processor/transform/mdxish/resolve-esm-imports.ts (1)
15-17: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winSilent
undefinedfor unresolved named imports.
getModuleExportreturnsundefinedwith no warning whenimportedNameisn't found on the module (e.g., a typo likeuseStatinstead ofuseState). This produces a confusing downstreamTypeErrorinsideevaluate()rather than the clear[WARNING]message already used for unsupported libraries.♻️ Suggested fix
-const getModuleExport = (module: unknown, importedName: string): unknown => - isRecord(module) && importedName in module ? module[importedName] : undefined; +const getModuleExport = (module: unknown, importedName: string): unknown => { + if (isRecord(module) && importedName in module) return module[importedName]; + // eslint-disable-next-line no-console + console.warn(`[WARNING] "${importedName}" is not exported by the resolved module.`); + return undefined; +};🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@processor/transform/mdxish/resolve-esm-imports.ts` around lines 15 - 17, The named-export lookup in getModuleExport currently returns undefined silently when importedName is missing, which delays the failure until evaluate() throws a less helpful error. Update the resolve-esm-imports flow so unresolved named imports are detected at the lookup point and routed through the existing warning/error handling used for unsupported libraries, with a clear message that includes the missing importedName and the module being resolved. Keep the check in getModuleExport or its immediate caller so evaluate() only receives valid exports or an explicit warning path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@__tests__/lib/mdxish/exports.test.ts`:
- Around line 326-335: The test named in exports.test.ts for handling an
unsupported library currently only checks that mix() skips the import and
preserves the rest of the doc, but it never verifies the “warns” part of the
behavior. Update this test to spy on console.warn around the mix(md) call and
assert that a warning is emitted for the unsupported lodash import, while
keeping the existing output assertions intact so the test covers both the
warning and the skip behavior.
In `@processor/transform/mdxish/resolve-esm-imports.ts`:
- Around line 15-17: The named-export lookup in getModuleExport currently
returns undefined silently when importedName is missing, which delays the
failure until evaluate() throws a less helpful error. Update the
resolve-esm-imports flow so unresolved named imports are detected at the lookup
point and routed through the existing warning/error handling used for
unsupported libraries, with a clear message that includes the missing
importedName and the module being resolved. Keep the check in getModuleExport or
its immediate caller so evaluate() only receives valid exports or an explicit
warning path.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: e22ea668-a0f6-4a82-a299-e52a7107a621
📒 Files selected for processing (3)
__tests__/lib/mdxish/exports.test.tsprocessor/transform/mdxish/evaluate-exports.tsprocessor/transform/mdxish/resolve-esm-imports.ts
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
readmeio/ai(manual)readmeio/gitto(manual)readmeio/markdown(manual)readmeio/readme(manual)
## Version 14.11.0 ### ✨ New & Improved * **mdxish:** replace brace-escaping preprocessing with lenient expression tokenizer ([#1531](#1531)) ([5c5a57c](5c5a57c)) * **mdxish:** support library imports in declarations ([#1530](#1530)) ([fa6ee97](fa6ee97)) ### 🛠 Fixes & Updates * correct exports map ordering ([#1529](#1529)) ([08a63dd](08a63dd)) <!--SKIP CI-->
This PR was released!🚀 Changes included in v14.11.0 |

🎯 What does this PR do?
Lets in-document declarations use
importstatements. Previously an imported name (e.g. React hooks) was dropped, so using it threw<name> is not defined.importdeclarations now resolve against a module registry (React by default) and their values are injected into the evaluation scope.Not in scope but can be revisited:
🧪 QA tips
Try these in an MDXish doc — each should render without a "not defined" error:
Named import (the reported case):
Default / namespace / aliased imports:
Unsupported library - warns and skips, rest of the doc still renders:
📸 Screenshot or Loom
Screen.Recording.2026-07-02.at.5.58.30.pm.mov