外部应用使用本地组件库时props.theme未定义的问题排查
TypeError: Cannot read property 'primary' of undefined with styled-components in Component Library This is a super common issue when working with local component libraries and styled-components—you're almost certainly dealing with duplicate instances of styled-components running in your app and component library. Here's why and how to fix it:
Why This Happens
styled-components uses React context under the hood to pass the theme around. If your craft component library is loading its own copy of styled-components (even if the version matches), its internal context won't connect to the ThemeProvider from your fe app's styled-components instance. That's why theme-dependent components like Button break, but plain styled components like HeadlineOne work (they don't rely on the context).
Step-by-Step Fixes
1. Ensure Component Library Doesn't Bundle Its Own styled-components
You already have styled-components in craft's peerDependencies—great start! Now make sure it's not installed locally in craft:
- Delete
craft/node_modulesandcraft/yarn.lock(orpackage-lock.json) - Run
yarn install(ornpm install) incraft—peer dependencies won't be installed locally, socraftwill rely on the app's copy.
2. Sync styled-components Instances When Using yarn link
If you're using yarn link to test the library locally, you need to link the same styled-components instance across both projects:
- In your
craftdirectory:yarn link "styled-components" - Then in your
fedirectory:yarn link "styled-components"
This forces both projects to use the exact same styled-components instance, so context is shared correctly.
3. Verify Your Babel Configuration (For Component Library)
Make sure your craft library's Babel setup doesn't bundle styled-components. Add the babel-plugin-styled-components to your .babelrc or babel.config.js:
{ "presets": [/* your existing presets */], "plugins": [ ["styled-components", { "displayName": true, "ssr": false }] ] }
This plugin ensures styled-components is treated as an external dependency, not bundled into your library's output.
4. Validate the Instance Match
To confirm you're using the same instance, add these logs to your code:
- In
fe/Main.tsx:import styled from 'styled-components'; console.log('App styled instance:', styled); - In
craft/Button.tsx:import styled from 'styled-components'; console.log('Craft styled instance:', styled);
Check your browser console—if the two instances are the same object, you've fixed the duplicate instance issue. If not, double-check steps 1 and 2.
Bonus: Double-Check ThemeProvider Wrapping
Ensure your fe/App.tsx's ThemeProvider is wrapping all components that use the library. From your code, it looks like Page is wrapped correctly, but it never hurts to confirm the theme object itself has the colors.primary property (you can log theme in App.tsx to be sure).
内容的提问来源于stack exchange,提问作者Carrein

