Closed crubier closed 5 years ago
Here is a way to somewhat work around this (didn't get storybook to work yet though..)
It uses solution 3 listed here : https://yarnpkg.com/en/docs/pnp/troubleshooting#toc-is-trying-to-require-without-it-being-listed-in-its-dependencies
Go to top level package and then:
yarn add @storybook/channels @emotion/core @emotion/styled emotion-theming
For info, I have this other bug afterwards:
https://github.com/storybooks/storybook/issues/6905
Am I the first person in the world to run storybook on a project installed with yarn pnp, or am I badly mistaken somewhere ?
@arcanis , this link here https://yarnpkg.com/en/docs/pnp/troubleshooting#toc-is-trying-to-require-without-it-being-listed-in-its-dependencies says I am supposed to ping you.
There's been a few reports of incompatibilities with Storybook but unfortunately those who did them didn't have the bandwidth to investigate. I did try a bit, but since I never used Storybook myself I would have to learn it first and it didn't seem straightforward 😅
I'm pretty sure the problems can be fixed with only a few PRs, and I'd be happy to lend my experience to help achieve this goal! We did the same thing with Gatsby and it really was just a few dependencies to add here and there, and the Webpack plugin to add to the configuration (like here: https://github.com/gatsbyjs/gatsby/pull/12315).
This file might be a good culprit ?
https://github.com/storybooks/storybook/blob/master/app/react/src/server/cra-config.js
I made a quick first pass. My methodology:
$> yarn create react-app sb-test && cd sb-test
$> yarn add @storybook/cli && yarn sb init
$> yarn policies set-version berry
This gives us a project with Storybook using Yarn v2 (Yarn v2 is where most of the development occurs nowadays, and in particular it uses PnP by default; it's the best place to debug such issues).
I had to do the following changes to the resulting lockfile in order to get somewhere (note that except for pnp-webpack-plugin
, all those dependencies should be listed regardless of whether we're operating in PnP or non-PnP mode; not listing them makes Storybook subject to hoisting issues):
pnp-webpack-plugin
to the dependenciesbabel-plugin-add-react-displayname
to the dependencies@emotion/core
to the dependencies@emotion/styled
to the dependencies@storybook/channel
to the dependenciesemotion-theming
to the dependenciesregenerator-runtime
to the dependenciesAdditionally, I had to "unplug" Storybook in my package.json, as it tries to create new directories inside its own directory at runtime (Yarn 2 keeps by default all packages within their own archives, which prevents them from modifying their sources. Unplugging a package means that it will be unpacked within their own directory, which we don't recommend as it breaks zero-installs):
{
"dependenciesMeta": {
"@storybook/core": {
"unplugged": true
}
}
}
The pnp-webpack-plugin
now has to be injected inside the configuration. I found a few places where this needs to be done:
Again, I don't know much about Storybook so I find it curious that there are so many different configuration files - maybe I'm missing something? In particular, the base-webpack
file doesn't seem to be reused by iframe-webpack
and manager-webpack
, so I don't know what uses it. Regardless, they need to be modified to contain a code similar to this pseudocode:
const PnpWebpackPlugin = require('pnp-webpack-plugin');
module.exports = {
resolve: {
plugins: [
PnpWebpackPlugin,
],
},
};
The babel-loader
helper also has to be modified to use require.resolve('babel-loader')
instead of just babel-loader
.
After following all those steps I ended up on something that builds, but running it I get a runtime error:
vendors~main.204baa2a64d34d32b96d.bundle.js:22447 Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
at Module.<anonymous> (vendors~main.204baa2a64d34d32b96d.bundle.js:22447)
at Module../.yarn/cache/core-js-npm-2.6.9-f034530cf2064b0812b01d6590542b0dbd4006bc7611ea0ab1bc7cfcc2d17c7f.zip/node_modules/core-js/modules/_object-keys.js (vendors~main.204baa2a64d34d32b96d.bundle.js:22450)
at __webpack_require__ (runtime~main.e27e72d77edfc378d751.bundle.js:80)
at Object../.yarn/cache/core-js-npm-2.6.9-f034530cf2064b0812b01d6590542b0dbd4006bc7611ea0ab1bc7cfcc2d17c7f.zip/node_modules/core-js/modules/_object-dps.js (vendors~main.204baa2a64d34d32b96d.bundle.js:22260)
at __webpack_require__ (runtime~main.e27e72d77edfc378d751.bundle.js:80)
at Object../.yarn/cache/core-js-npm-2.6.9-f034530cf2064b0812b01d6590542b0dbd4006bc7611ea0ab1bc7cfcc2d17c7f.zip/node_modules/core-js/modules/_object-create.js (vendors~main.204baa2a64d34d32b96d.bundle.js:22164)
at __webpack_require__ (runtime~main.e27e72d77edfc378d751.bundle.js:80)
at Object../.yarn/cache/core-js-npm-2.6.9-f034530cf2064b0812b01d6590542b0dbd4006bc7611ea0ab1bc7cfcc2d17c7f.zip/node_modules/core-js/modules/_iter-create.js (vendors~main.204baa2a64d34d32b96d.bundle.js:21648)
at __webpack_require__ (runtime~main.e27e72d77edfc378d751.bundle.js:80)
at Module.<anonymous> (vendors~main.204baa2a64d34d32b96d.bundle.js:21694)
The faulty code is the module.exports
assignment in the following snippet:
/***/ "./.yarn/cache/core-js-npm-2.6.9-f034530cf2064b0812b01d6590542b0dbd4006bc7611ea0ab1bc7cfcc2d17c7f.zip/node_modules/core-js/modules/_object-keys.js":
/*!*********************************************************************************************************************************************************!*\
!*** ./.yarn/cache/core-js-npm-2.6.9-f034530cf2064b0812b01d6590542b0dbd4006bc7611ea0ab1bc7cfcc2d17c7f.zip/node_modules/core-js/modules/_object-keys.js ***!
\*********************************************************************************************************************************************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* WEBPACK VAR INJECTION */(function(module) {/* harmony import */ var core_js_modules_web_dom_iterable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/web.dom.iterable */ "./.yarn/cache/core-js-npm-2.6.9-f034530cf2064b0812b01d6590542b0dbd4006bc7611ea0ab1bc7cfcc2d17c7f.zip/node_modules/core-js/modules/web.dom.iterable.js");
/* harmony import */ var core_js_modules_web_dom_iterable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_iterable__WEBPACK_IMPORTED_MODULE_0__);
// 19.1.2.14 / 15.2.3.14 Object.keys(O)
var $keys = __webpack_require__(/*! ./_object-keys-internal */ "./.yarn/cache/core-js-npm-2.6.9-f034530cf2064b0812b01d6590542b0dbd4006bc7611ea0ab1bc7cfcc2d17c7f.zip/node_modules/core-js/modules/_object-keys-internal.js");
var enumBugKeys = __webpack_require__(/*! ./_enum-bug-keys */ "./.yarn/cache/core-js-npm-2.6.9-f034530cf2064b0812b01d6590542b0dbd4006bc7611ea0ab1bc7cfcc2d17c7f.zip/node_modules/core-js/modules/_enum-bug-keys.js");
module.exports = Object.keys || function keys(O) {
return $keys(O, enumBugKeys);
};
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack-npm-4.32.2-21c8ff8dcc2c4971b61859e9e22de16292dec8acb6d592a55e798a87b574f514.zip/node_modules/webpack/buildin/harmony-module.js */ "./.yarn/cache/webpack-npm-4.32.2-21c8ff8dcc2c4971b61859e9e22de16292dec8acb6d592a55e798a87b574f514.zip/node_modules/webpack/buildin/harmony-module.js")(module)))
/***/ }),
I'm not exactly sure what causes this; more investigation will be needed once the first issues I've reported have been fixed!
@crubier You should be able to override the webpack configuration without modifying those files using "full control mode": https://storybook.js.org/docs/configurations/custom-webpack-config/
@shilman I agree with this but I have been trying this for a long time now, to now avail. I always get the problem seen in #6905
@arcanis great digging! In my limited understanding of storybook, it has "2 webpacks" one for the storybook UI and wrapper stuff, where the actual server is ran, which they call manager
, and one do be configured by the user, i guess the 'iframe'.
@shilman I believe "full control mode" only allows to configure the iframe-webpack
.
@crubier I'm also trying to use sotrybook with yarn 2 and pnp, so you are not alone.
@shilman Here is an example of a webpack override that could be expected to work but does not:
const PnpWebpackPlugin = require(`pnp-webpack-plugin`);
// Export a function. Accept the base config as the only param.
module.exports = async ({ config, mode }) => {
// `mode` has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
// 'PRODUCTION' is used when building the static version of storybook.
// Make whatever fine-grained changes you need
console.log("config Pre");
console.log(config);
const newConfig = {
...(config || {}),
module: {
...((config || {}).module || {}),
rules: [
...(((config || {}).module || {}).rules || []),
{
test: /\.tsx?$/,
loader: require.resolve("babel-loader")
}
]
},
resolve: {
...((config || {}).resolve || {}),
plugins: [
...(((config || {}).resolve || {}).plugins || []),
PnpWebpackPlugin
]
},
resolveLoader: {
...((config || {}).resolveLoader || {}),
plugins: [
...(((config || {}).resolveLoader || {}).plugins || []),
PnpWebpackPlugin.moduleLoader(module)
]
},
optimization: {
...((config || {}).optimization || {}),
minimizer: undefined
}
};
console.log("config Post");
console.log(newConfig);
// Return the altered config
return newConfig;
};
@shilman I think the "full control mode" allows to customize the webpack config that @marco-silva0000 calls "the one do be configured by the user, i guess the 'iframe'."
But is there a way to configure the other one, what @marco-silva0000 calls "the one for the storybook UI and wrapper stuff, where the actual server is ran" ?
This is the one causing the bug now for me.
@crubier you have more info about that on #4995 It's a pretty long conversation, and honestly I'm not sure about the state of te problem, but maybe you can figure it out, if not I'm sure @shilman can help us out.
@marco-silva0000 Thank you, I think this is going in the right direction, even though it does not work yet
@crubier @marco-silva0000 Yeah that #4995 is exactly right. I've merged the presets documentation in #5333 and you can see the relevant docs here:
https://next--storybooks.netlify.com/presets/writing-presets/#advanced-configuration
Hopefully this makes sense. If not, hop on Discord and I can help you get going and update the documentation to make it more clear.
OMG Ok This works :tada:
It was painful, but it works and the solution is relatively simple in the end, thanks to presets.
The solution is a combination of @arcanis answers + this storybook preset
//pnp-ts-preset.js
const PnpWebpackPlugin = require(require.resolve("pnp-webpack-plugin"));
function webpack(webpackConfig = {}, options = {}) {
const { module = {}, resolve = {}, resolveLoader = {} } = webpackConfig;
const { tsLoaderOptions, tsDocgenLoaderOptions, include } = options;
return {
...webpackConfig,
module: {
...module,
rules: [
...(module.rules || []),
{
test: /\.tsx?$/,
use: [
{
loader: require.resolve("ts-loader"),
options: PnpWebpackPlugin.tsLoaderOptions({
"compilerOptions": {
"jsx": "react",
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": false
}
})
},
{
loader: require.resolve("react-docgen-typescript-loader"),
options: tsDocgenLoaderOptions
}
],
include
}
]
},
resolve: {
...resolve,
extensions: [...(resolve.extensions || []), ".ts", ".tsx"],
plugins: [...(resolve.plugins || []), PnpWebpackPlugin]
},
resolveLoader: {
...resolveLoader,
plugins: [
...(resolveLoader.plugins || []),
PnpWebpackPlugin.moduleLoader("@storybook/react")
]
}
};
}
function managerWebpack(webpackConfig = {}, options = {}) {
const { module = {}, resolve = {}, resolveLoader = {} } = webpackConfig;
const { tsLoaderOptions, tsDocgenLoaderOptions, include } = options;
return {
...webpackConfig,
module: {
...module,
rules: [
...(module.rules || [])
]
},
resolve: {
...resolve,
extensions: [...(resolve.extensions || []), ".ts", ".tsx"],
plugins: [...(resolve.plugins || []), PnpWebpackPlugin]
},
resolveLoader: {
...resolveLoader,
plugins: [
...(resolveLoader.plugins || []),
// PnpWebpackPlugin.moduleLoader(module)
PnpWebpackPlugin.moduleLoader("@storybook/react")
]
}
};
}
module.exports = { webpack, managerWebpack };
// presets.js
const path = require("path");
module.exports = [path.resolve("./.storybook/pnp-ts-preset")];
I will probably make a PR on Friday.
Thanks all !
PR for adding a preset for Pnp here:
Second PR following @arcanis recommandations above:
Merged! Marked it as a patch, so should be part of next 5.1.x release
Ermahgerd!! I just released https://github.com/storybookjs/storybook/releases/tag/v5.2.0-alpha.29 containing PR #6922 that references this issue. Upgrade today to try it out!
You can find this prerelease on the @debug
NPM tag.
Closing this issue. Please re-open if you think there's still more to do.
Ermahgerd!! I just released https://github.com/storybookjs/storybook/releases/tag/v5.1.9 containing PR #6922 that references this issue. Upgrade today to try it out!
Describe the bug
When using sotrybook within a yarn PnP project, we get this error:
Trying to require the package "@emotion/core" without it being listed in its dependencies
Here is how to fix this:
https://yarnpkg.com/en/docs/pnp/troubleshooting#toc-is-trying-to-require-without-it-being-listed-in-its-dependencies
Fixes for https://github.com/storybooks/storybook/issues/5919 do not fix this.
To Reproduce
package.json
:storybook start
Expected behavior
Correct dependency declaration that does not create this problem
Screenshots
Code snippets If applicable, add code samples to help explain your problem.
System:
Additional context
@arcanis Should now about this