storybook: [Bug]: MDX imported from other packages will break because they use the wrong instance of React
Describe the bug
In our monorepo, we have 5 packages. As far as Storybook is concerned, they are HTML, Angular, React, Svelte and Vue. The first package (HTML) has several MDX docs (no stories) that should be shared across the five Storybook sites. Only the React package is able to share those MDXs. All the others get the error described below. Storybook 7.0.0-rc.8 is installed across all packages.
The shared MDXs have a single import…
import { Meta } from '@storybook/blocks'
If I copy an MDX to any of the packages, it works. If the packages try load the MDX from the other package using relative URLs, it fails (except for the React project).
The error, “Cannot read properties of null (reading ‘useContext’)” in Chrome or “Null is not an object (evaluating ‘dispatcher.useContext’)” in Safari is usually a problem with React where there is more than one instance created or a violation of the Rules of Hooks.
Storybook dutifully finds the MDX files in the other project based on my main.ts files. But when I try to view one, I get the following…
null is not an object (evaluating 'dispatcher.useContext')
useContext@http://localhost:9006/node_modules/.cache/.vite-storybook/deps/chunk-376EEON5.js?v=5b39fbc3:1062:28
Meta@http://localhost:9006/node_modules/.cache/.vite-storybook/deps/@storybook_blocks.js?v=5b39fbc3:9408:47
renderWithHooks@http://localhost:9006/node_modules/.cache/.vite-storybook/deps/chunk-V45T5FYE.js?v=5b39fbc3:12171:35
mountIndeterminateComponent@http://localhost:9006/node_modules/.cache/.vite-storybook/deps/chunk-V45T5FYE.js?v=5b39fbc3:14921:36
beginWork$1@http://localhost:9006/node_modules/.cache/.vite-storybook/deps/chunk-V45T5FYE.js?v=5b39fbc3:19749:31
performUnitOfWork@http://localhost:9006/node_modules/.cache/.vite-storybook/deps/chunk-V45T5FYE.js?v=5b39fbc3:19197:31
workLoopSync@http://localhost:9006/node_modules/.cache/.vite-storybook/deps/chunk-V45T5FYE.js?v=5b39fbc3:19133:30
renderRootSync@http://localhost:9006/node_modules/.cache/.vite-storybook/deps/chunk-V45T5FYE.js?v=5b39fbc3:19112:27
recoverFromConcurrentError@http://localhost:9006/node_modules/.cache/.vite-storybook/deps/chunk-V45T5FYE.js?v=5b39fbc3:18732:42
performConcurrentWorkOnRoot@http://localhost:9006/node_modules/.cache/.vite-storybook/deps/chunk-V45T5FYE.js?v=5b39fbc3:18680:56
performConcurrentWorkOnRoot@[native code]
workLoop@http://localhost:9006/node_modules/.cache/.vite-storybook/deps/chunk-V45T5FYE.js?v=5b39fbc3:197:50
flushWork@http://localhost:9006/node_modules/.cache/.vite-storybook/deps/chunk-V45T5FYE.js?v=5b39fbc3:176:30
performWorkUntilDeadline@http://localhost:9006/node_modules/.cache/.vite-storybook/deps/chunk-V45T5FYE.js?v=5b39fbc3:384:50
The React project shares the MDX files with the HTML project just fine…
Here’s the MDX I am trying to load from the other package…
import { Meta } from '@storybook/blocks'
<Meta title="Test/Test" />
# Test
Here’s the main.ts for my Vue project (an example of a package not working)…
import type { StorybookConfig } from '@storybook/vue3-vite'
const config: StorybookConfig = {
stories: [
'../src/**/*.mdx',
'../src/**/*.stories.@(js|jsx|ts|tsx)',
'../../charts/stories/tutorials/!(0-api)*.stories.mdx',
'../../charts/stories/getting-started/vue.stories.mdx'
],
addons: [
{
name: '@storybook/addon-essentials',
options: {
actions: false
}
}
],
framework: {
name: '@storybook/vue3-vite',
options: {}
},
docs: {
autodocs: 'tag'
},
staticDirs: ['./assets'],
features: {
storyStoreV7: false
}
}
export default config
Here’s the main.ts for my React project (this one is working fine)…
import type { StorybookConfig } from '@storybook/react-vite'
const config: StorybookConfig = {
stories: [
'../src/**/*.mdx',
'../src/**/*.stories.@(js|jsx|ts|tsx)',
'../../charts/stories/tutorials/!(0-api)*.stories.mdx',
'../../charts/stories/getting-started/react.stories.mdx'
],
addons: [
{
name: '@storybook/addon-essentials',
options: {
actions: false
}
}
],
framework: {
name: '@storybook/react-vite',
options: {}
},
docs: {
autodocs: 'tag'
},
staticDirs: ['assets'],
async viteFinal(config, _) {
return config
},
features: {
storyStoreV7: false
}
}
export default config
To Reproduce
Make sure you have yarn 3.5.0 and node 18.15.0
git clone https://github.com/nstuyvesant/carbon-charts.git
cd carbon-charts
git checkout next
git pull
yarn install
yarn build
cd packages/charts-svelte
# uncomment lines 8 and 9 of packages/charts-svelte/.storybook/main.ts then...
yarn storybook
# click on any story in DOCS/Tutorials or DOCS/Getting Started
# now go to the core project where those MDXs are
cd ../charts
yarn storybook
# click on one of the stories that failed above and it will display ok
Then click on any stories in DOCS/Tutorials.
System
Environment Info:
System:
OS: macOS 13.2.1
CPU: (10) arm64 Apple M1 Pro
Binaries:
Node: 18.15.0 - /opt/homebrew/bin/node
Yarn: 3.5.0 - /opt/homebrew/bin/yarn
npm: 9.6.2 - /opt/homebrew/bin/npm
Browsers:
Chrome: 111.0.5563.110
Firefox: 111.0.1
Safari: 16.3
npmPackages:
@storybook/addon-essentials: ^7.0.0-0 => 7.0.0-rc.8
@storybook/addon-interactions: ^7.0.0-0 => 7.0.0-rc.8
@storybook/addon-links: ^7.0.0-0 => 7.0.0-rc.8
@storybook/angular: ^7.0.0-0 => 7.0.0-rc.8
@storybook/blocks: ^7.0.0-0 => 7.0.0-rc.8
@storybook/manager-api: ^7.0.0-0 => 7.0.0-rc.8
@storybook/testing-library: ^0.0.14-next.1 => 0.0.14-next.1
@storybook/theming: ^7.0.0-0 => 7.0.0-rc.8
Additional context
I tried moving one MDX above the package folder level while debugging and noticed that when it was no longer in a package folder, I got this error message that was a little revealing…
_No response_About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 4
- Comments: 27 (13 by maintainers)
BTW, I never did get the alias approach working for Angular (have not had time to investigate it). If Angular 16 arrives soon I won’t have to wrestle with webpack since it uses esbuild. For packages based on vite, the alias approach works well.
The downside is the extra required step for those with monorepos that they are not expecting. But I guess if you had a monorepo documentation page that includes this along with the nuances related to module hoisting, this would be helpful.
If you think about it, in a monorepo, Storybook is the most complicated part of a monorepo implementation since it’s a) external and b) most storybook modules (other than environment-specific ones) are shared across the monorepo. If homegrown packages are dependent upon each other, you just add something like this to your package’s package.json dependencies and move on:
Hoisting and Storybook are problematic since the default for yarn workspaces would be to keep something like
@storybook/react
in the local package’s node_modules while the shared ones sit in the monorepo’s root node_modules. Any interactions between storybook modules can’t assume they all sit in one node_modules directory. This is the bigger challenge I’m hoping can be solved.