storybook #storybook/addon-options dosent work - reactjs

I am trying to set some option but it doesn't work.
package.json
"devDependencies": {
"#storybook/addon-actions": "^3.4.10",
"#storybook/addon-links": "^3.4.10",
"#storybook/addon-options": "^3.4.11",
"#storybook/addon-storyshots": "^3.4.10",
"#storybook/addons": "^3.4.10",
"#storybook/react": "^3.4.11"
}
addons.js
import '#storybook/addon-options/register';
config.js
import { configure } from '#storybook/react';
import { setOptions } from '#storybook/addon-options';
setOptions({ name: 'my name' });
// automatically import all files ending in *.stories.js
const req = require.context('../stories', true, /.stories.js$/);
function loadStories() {
req.keys().forEach((filename) => req(filename));
}
configure(loadStories, module);
I am trying to understand where i s, going wrong for a few hours.

Edit after testing with provided versions:
I tested this locally with the above versions, and what it looks like is that because #storybook/react and #storybook/addons are on different versions, even by a patch, #storybook/react ends up installing it's own addons dependency and the 2 become out of sync.
If this is the case, you will likely see an error like "accessing nonexistent addons channel" in the console.
To fix this you will need to increase the version of the addons dependency to v3.4.11 AND reinstall the react dependency.
npm install --save-dev #storybook/addons#3.4.11 #storybook/react#3.4.11
Note: If you only update addons to v3.4.11 without reinstalling the react dependency, it won't fully sync up, because the react would already have installed it's own addon subdependency.
An image of the filesystem within node_modules directoy:
Previously Answered for Storybook v4:
According to the documentation, you have to apply the settings as a decorator (and there is no setOptions function, but there is a withOptions function).
So try this:
import { addDecorator, configure } from '#storybook/react';
import { withOptions } from '#storybook/addon-options';
addDecorator(withOptions({ name: 'my name' }));
// rest of the config goes here
Also, make sure to register the addon by adding the following line in your addons.js file:
import '#storybook/addon-options/register';
Reference: https://www.npmjs.com/package/#storybook/addon-options
Aside: The reason it has to be within a decorator is because the UI of storybook is rendered as part of each story, so you can't just set options globally without having each story apply those settings.

Related

Unable to use specific React version in a Jupyter Widget

I'm trying to write a Jupyter Widget that uses react based on this cookiecutter. I specifically need to use a certain version of react. However, even when installing a specific version, after building the widget, a different version is used in the jupyterlab frontend.
The react version that is installed in the node_modules folder is the version that I want to use and no other module has react as a dependency. In the node_modules folder, there is also no trace of a different react version to be found.
Specifically, I want to use react 18.2.0. The version that I get by logging React.version in the frontend is react 17.0.2. Obviously, I am not able to use React 18 features like useId which results in an error.
How can I use a different version of react? And where does this other react version 17.0.2 come from?
Reproduce:
Install the cookiecutter as described in the README.
Install react and react-dom via jlpm/yarn add react#18.2.0 react-dom#18.2.0.
Add a simple React component in a new file:
import React from 'react';
export const SimpleComponent = () => {
console.log('React.version:', React.version);
return <div>Simple Test</div>;
};
Render the react component in the render() function of the view in index.ts:
render() {
this.component = React.createElement(SimpleComponent);
ReactDOM.render(this.component, this.el);
}
Console shows: "React.version: 17.0.2"
If you need to change to a specific version of React, you can run this in the terminal:
npm install --save react#18.2.0
Thanks to krassowski for giving me the link to the answer!
In my package.json, I added two entries for react and react-dom to sharedPackages so that I get:
"jupyterlab": {
"extension": "lib/plugin",
"outputDir": "testproject/labextension/",
"sharedPackages": {
"#jupyter-widgets/base": {
"bundled": false,
"singleton": true
},
"react": {
"bundled": true,
"singleton": true
},
"react-dom": {
"bundled": true,
"singleton": true
}
}
}

How to make cherry picking react component library like lodash & date/fns

I have made one small library which includes 20-25 different components & made an npm package of it.
my react project, where I want to use these components, has many pages[routes] used lazy-loading so each page has its own bundle.
but when I write the statement on my home page[App.js].
import { MyModal } from 'my-react-lib';
each and every component is loaded into home page bundle. so my initial loading performance is worst. [2Mb initial bundle size]
I have read the concept of tree shaking and event tried to implement in webpack & even with rollup but they only make bundle.js but not as per mine requirement.
I am willing to achieve cherry-picking like import-export. same as date-fns & lodash does.
import format from 'date-fns/format';
import debounce from 'lodash/debounce';
how to achieve this?
import MyModal from 'my-react-lib/MyModal';
import OtherComponent from 'my-react-lib/OtherComponent';
Rollup allows you to split your library into several independent chunks. You have to provide an object, mapping names to entry points, to the input property of the rollup configuration. It looks like this:
input: {
index: 'src/index.js',
theme: 'src/Theme',
badge: 'src/components/Badge',
contentCard: 'src/components/ContentCard',
card: 'src/elements/Card',
icon: 'src/elements/Icon',
...
src/index.js looks like this:
export { default as Theme } from './Theme'
export { default as Badge } from './components/Badge'
...
Have a look at rollup’s documentation: https://rollupjs.org/guide/en/#input
The output is set to a directory:
output: [
{
dir: 'dist/es',
format: 'es',
},
],
Then you declare the entry point in your package.json as follows:
"module": "dist/es/index.js",
The modules of your library can then be imported:
import { Theme, Badge } from 'your-component-library'
You may need to package them separately.
For example the Material-UI, there are many parts of it. When we use it in the normal way
npm install #material-ui/core
If you look at their source, you would find out that there are multiple packages, each with it's own package.json file
For example the #material-ui/core pacakge.json
{
"name": "#material-ui/core",
"version": "4.9.7",
"private": false,
"author": "Material-UI Team",
...
"dependencies": {
"#babel/runtime": "^7.4.4",
"#material-ui/styles": "^4.9.6",
"#material-ui/system": "^4.9.6",
"#material-ui/types": "^5.0.0",
"#material-ui/utils": "^4.9.6",
Which means that they are actually separate and have dependencies with each other.
Well, that's the scope.

jest + enzyme: TypeError: Cannot read property 'htmlparser2' of undefined

I'm using jest and enzyme to build this test, but I'm having this error when I build it.
This is the test
import React from 'react';
import { shallow, render } from 'enzyme';
import Title from './../';
describe('Title', () => {
it('should render correctly', () => {
const TitleDOM = render(<Title />);
expect(TitleDOM).toBeDefined();
});
});
This is the error
Versions:
"react": "^16.0.0",
"jest": "^21.2.1",
"enzyme": "^3.2.0"
I appreciate if someone can help me.
I was having similar issue with electron native components and the solution that worked for me was isolating those components to a separate file.
You could just separate the usage of the htmlparser2 to a function outside the component in a helper file.
Hit this issue myself today, turns out cheerio (a dependency of enzyme) introduced breaking changes in their 1.x version, and enzyme doesn't appear to correctly pin the version to avoid this.
You can see the related cheerio issues here:
https://github.com/cheeriojs/cheerio/issues/1260
https://github.com/cheeriojs/cheerio/issues/1261
Essentially, they're moving away from htmlparser2 by default, but there is a way to continue it's use.
I opened an enzyme issue about this here (which details where you could make the required changes in enzyme if required):
https://github.com/airbnb/enzyme/issues/2299
A workaround in the meantime would be to coerce cheerio's version resolution in your package.json, which can be done by adding a resolutions entry like the following:
{
// ..snip: other package.json things..
"dependencies": {
"enzyme": "^3.9.0",
// ..snip: all of your other dependencies..
},
"resolutions": {
"cheerio": ">= 0.22.0 < 1.0.0"
}
}
This appears to be a yarn specific feature, which you can read more about at:
https://yarnpkg.com/lang/en/docs/selective-version-resolutions/
If you use npm, there appears to be an equivalent package called npm-force-resolutions (though I haven't used it personally):
https://www.npmjs.com/package/npm-force-resolutions

Sharepoint Framework cant find module

I had a project which used youtube-api-search in it. it works there fine.
I have created a sharepoint framework template with yeoman "yo #microsoft/sharepoint" and installed youtube api package as I did in previous project. but when I run this project I encounter an error like below;
Cannot find module 'youtube-api-search'
as I said its working in other react project do i need something specially to make it work here ?
I installed api via "npm i youtube-api-search --save-dev" command
here main component content;
import * as React from 'react';
import { css } from 'office-ui-fabric-react';
import styles from './Announcements.module.scss';
import { IAnnouncementsProps } from './IAnnouncementsProps';
//I have added only these 2 lines to default code
import YTSearch from 'youtube-api-search';
const YOUTUBE_API_KEY = "AIzaSyCI9gcceui5zcQDAEwbyv...";
export default class Announcements extends React.Component<IAnnouncementsProps, void> {
public render(): React.ReactElement<IAnnouncementsProps> {
return (
...
);
}
}
we can import modules in three methods
FIRST::Using Config-->config.json and change
"externals": {
"jquery": "https://code.jquery.com/jquery-3.1.0.min.js",
"OwlCarousel":{
"path":"./node_modules/react-owl-carousel/lib/OwlCarousel.min.js",
"globalName":"OwlCarousel"
},
"Slider":{"path":"./node_modules/react-slick/lib/slider.js",
"globalName":"Sliders"}
},
SECOND:: npm install #types/youtube-api-search --save
THIRD ::
`npm install typings`
`typings install dt~youtube-api-search -global --save`
sometimes dt~ is neccessary sometimes it is not necessaary

TypeError: __webpack_require__.i(...) is not a function

I am getting a webpack TypeError when I am trying to simplify an import. The following code works without any issues. Here I am importing a React Higher-Order-Component (HOC) called smartForm from core/components/form/index.js.
core/components/form/index.js (does a named export of smartForm)
export smartForm from './smart-form';
login-form.jsx (imports and uses smartForm)
import { smartForm } from 'core/components/form';
class LoginForm extends React.Component {
...
}
export default smartForm(LoginForm);
However, I want to simplify the import to just import { smartForm } from 'core'. So I re-exported smart-form in core/index.js and imported it from core. See the code below:
core/index.js (does a named export of smartForm)
export { smartForm } from './components/form';
// export smartForm from './components/form'; <--- Also tried this
login-form.jsx (imports and uses smartForm)
import { smartForm } from 'core';
class LoginForm extends React.Component {
...
}
export default smartForm(LoginForm); // <--- Runtime exception here
This code compiles without any issues, but I am getting the following runtime exception at the line export default smartForm(LoginForm);:
login-form.jsx:83 Uncaught TypeError: webpack_require.i(...) is not a function(…)
What am I missing?
P.S. Here are the Bable and plugin versions that I am using:
"babel-core": "^6.18.2",
"babel-preset-es2015-webpack": "^6.4.3",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-1": "^6.16.0",
tl;dr
For the questioner: Add this to your webpack.config.js:
resolve: {
alias: {
core: path.join(__dirname, 'core'),
},
},
For the general audience: Make sure the thing you try to import is indeed exists in that package.
Explanation
Questioner's problem: importing own code like npm modules
You try to import your module's exports in the same fashion how you import something from an npm package from the node_modules folder: import { something } from 'packagename';. The problem with this is that doesn't work out of the box. The Node.js docs give the answer on why:
Without a leading '/', './', or '../' to indicate a file, the module must either be a core module or is loaded from a node_modules folder.
So you either has to do what Waldo Jeffers and Spain Train suggested and write import { smartForm } from './core', or you can configure webpack so it can resolve your import path via its aliases which are created to solve this exact problem.
Debugging the error message in general
This error can arise if you try to import something from an existing npm package (in node_modules) but the imported thing doesn't exist in the exports. In this case, make sure there were no typos and that the given thing you try to import is indeed in that package. Nowadays it is trendy to break libraries into multiple npm packages, you might be trying to import from a wrong package.
So if you get something like this:
TypeError: __webpack_require__.i(...) is not a function
at /home/user/code/test/index.js:165080:81
at Layer.handle [as handle_request] (/home/user/code/test/index.js:49645:5)
To get more information on what import you should check, just open the output file generated by webpack and go to the line marked by the topmost line in the error stack (165080 in this case). You should see something like: __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_9_react_router_dom__["match"]). This tells us that there is no match export (or there is but it isn't a function) in react-router-dom, so we need to check our stuff around that import.
Since core is a folder of your app and not an npm module, Webpack can not understand which file you want to load. You must use a correct path pointing to a file. You have to replace import { smartForm } from 'core'; by import { smartForm } from './core/index.js
This error will occur by many reasons. Once I encountered this error when I add js in file-loader then when I removed it start to work correctly.
{
test: /\.(ttf|eot|svg|gif|jpg|png|js)(\?[\s\S]+)?$/,
use: 'file-loader'
},
When I remove |js it works
{
test: /\.(ttf|eot|svg|gif|jpg|png)(\?[\s\S]+)?$/,
use: 'file-loader'
},
Just remove these 2 line from config
const context = resolve.alias.context('./', true, /\.spec\.ts$/); context.keys().map(context);

Resources