We already know that Storybook is for building UI components and keeping them isolated from the business logic. I have implemented some basic examples of StoryBook.
Now I am very curious to know about the Storybook internal behavior means how it interacts with the react main application, the workflow of the Storybook after executing the npm run storybook command starting from the entry point to exit?
I'd also like to know why we don't use npm start for running the storybook?
Thanks :)
Storybook doesn't interact with your react application.
It is just a library for components in your project.
It gives you a variety set of tools to create examples of components usage.
This is why you need to write stories separately from actual react application.
And all these stories have no any intersection with your app.
Command npm run storybook just build all the stories that you've written and build useful ui for that so you can browse them easily.
That becomes extremely useful when you have a big code base.
Because it is difficult to know every component you have in project and how it works.
And Storybook provides us with an instrument to have all components more structured.
You can also use npm start for that. It is just about how you configure scripts in package.json.
Storybook doesn't interact with the main React Application.
Storybook is only used for building UI components and keeping them isolated from the react application(business logic). These components can be easily visualized when you run the storybook through this npm run storybook (windows) or yarn storybook(mac/ubuntu) command. It runs on a different port unlike npm start runs on the 3000 port by default.
These components are then imported into the main react application. React will use these components based on the requirement. Storybook gives you the ability to browse all the UI components that you have built and then later react will use it. This allows you to develop one component at a time.
What will happen when you execute the command npm run storybook?
This command at first will search for main.js and if found it will look for all the file which extends with stories.js which is nothing but the stories that you have built. It will then create a list of stories in any order or specified order which will be shown in the storybook webpage at 6006 port by default.
Why we don't use npm start for running the storybook?
We can use npm start for running the storybook but you need to configure it in the package.json file under the "scripts" as shown below.
"scripts": {
"start": "start-storybook -p 6006 -s public"
}
Here public means that this storybook doesn't require any authentication for running it. Now if you do npm start it will only run the storybook for you, not the react application. This storybook can be used later in different react applications.
I'll recommend that if you are implementing some basic concept of storybook then it is better to run both separately on a different port.
Related
I'm trying to share a React component I've created through a local hosted npm repo.
To do that I created the React component with typescript, transpiled it to js and published the resulting code to the repo. But when I install this package in an existing project (a basic create-react-app project with typescript) and try to use that component - My app tried to compile it for a few minutes and I fail to load that component. Sometimes if I wait a few minutes I see this error - although the component was tested and works:
Error: Invalid hook call. Hooks can only be called inside of the body
of a function component. This could happen for one of the following
reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug
and fix this problem.'
I've copied the same component to be embedded in the app and not installed by npm - it worked. I tried to strip the component to the bare minimum - it still takes a long time.
The steps to reproduce are easy:
I've shared the component in github:
https://github.com/ymoran00/example-stackoverflow-react
To build it you need to run npm install and then npm run build.
the result will be generated in the lib folder.
You can then go into the lib folder and run:
npm link
Then create a new typescript create-react-app project:
npx create-react-app my-app --template typescript
Go inside it and run:
npm link login-component
This will install the linked package.
Now go to App.tsx and import the package:
import LoginContainer from 'login-component/LoginContainer';
And use it in the App:
<LoginContainer onLogin={()=> {alert('success')}}/>
Run the app with npm start.
The App will open the browser - but nothing will load. It's kind of stuck on build or whatever - I don't know what happens there. If you'll take a look at the component you'll see it's quite a basic one with Material-UI.
The first place that I looked was your package.json file because it most likely that you are dealing with reason #1:
You might have mismatching versions of React and the renderer (such as React DOM)
I see that you are including react and react-dom as dependencies for your component. You should move these from dependencies to peerDepenedencies. You likely want to move #material-ui/core and #material-ui/icons to peerDependencies as well. Right now React is being bundled with your component and your component uses its own React version rather than the one in your app. You want to make it so that projects that use your component are expected to include React on their own.
For more information about why you should use peerDependencies, see this question:
What's the difference between dependencies, devDependencies and peerDependencies in npm package.json file?
It seems that the main problem I had in the process is using npm link.
It causes problems when combined with hooks - that's why I get this hooks error.
See also in this thread:
https://github.com/facebook/react/issues/13991
So instead of using npm link I've started using npm-sync and it seems to solve the problem.
I want to integrate https://github.com/Microsoft/BotFramework-WebChat/tree/v3 into my react app.
I have followed the below method and run npm install but it aint working.i have set my file to botchat.js in package.json:
"dependencies": {
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"botframework-webchat": "file:../../BotFramework-WebChat-3/botchat.js.map"
}
In Botframework document it is given as below
In your React website, incorporate a custom build of the Web Chat component
The simplest approach is to clone (or fork) this repo, alter it, build it, then reference your local build in your project's package.json as follows:
dependencies: {
...
'botframework-webchat': 'file:/path/to/your/repo'
...
}
Running npm install will copy your local repo to node_modules, and import/require references to 'botframework-webchat' will resolve correctly.
You may also wish to go so far as to publish your repo as its own full-fledged, versioned npm package using npm version and npm publish, either privately or publicly.
Different projects have different build strategies, yours may vary considerably from the above. If you come up with a different integration approach that you feel would have broad application, please consider filing a pull request for this README.
FOR BUILDING I FOLLOWED BELOW PROCESS
Building Web Chat
Clone (or fork) this repo
npm install
npm run build (to build on every change npm run watch, to build production npm run prepublish)
This builds the following:
/built/*.js compiled from the TypeScript sources in /src/*.js - /built/BotChat.js is the root
/built/*.d.ts declarations for TypeScript users - /built/BotChat.d.ts is the root
/built/*.js.map sourcemaps for easier debugging
/botchat.js webpacked UMD file containing all dependencies (React, Redux, RxJS, etc.)
/botchat.css base stylesheet
/botchat-es5.js is the Webpack bundle (a.k.a. botchat.js) plus polyfills for ES5 browsers
/botchat-fullwindow.css media query stylesheet for a full-window experience.
I want to customize my Botframework and execute it
I'm not sure what your question is as it looks like your able to compile the build. If you are looking to make custom changes, then you would do those pre-compile.
However, I would recommend you use the v4 BotFramework-WebChat, instead, as the v3 version (BotChat) is deprecated and unsupported (read here).
The v4 Web Chat is built in React, is more robust and full-featured, is fully compatible with the v3 and v4 Bot Framework SDKs, and is fully supported (learn more about it here).
That being said, if you are intent on using v3, then you should use this provided sample that is React based and ready to integrate.
Hope of help!
I've just created my Storybook library of components (ES6 etc).
It is structured as a Lerna project (all components isolated in the packages/ folder). However, that's a private repo with no real publish feature so, I think Lerna won't work with a private (free) account.
I've pushed the storybook repo to my Bitbucket as it is.
Now, I'd like to use my storybook library of components from the main application which is a different repo (on Bitbucket) build on Next.js.
I was attempting to import the individual storybook components as follows
import MyComponent from 'storybook-repo/packages/my-component/my-component';
but it obviously doesn't work, returning this error:
Module parse failed: Unexpected token (8:9)
You may need an appropriate loader to handle this file type.
This, because MyComponent is a jsx file.
I was hoping Next.js to transpile the imported modules but this is not the case.
My questions are:
My guts say the import of the whole storybook as git+ssh://git#bitbucket.org/myusername/storybook-repo.git from package.json is not a good idea. Any better solutions?
Is it true that Lerna works only for public/Pro repos where I can publish my packages?
Why is Next.js not transpiling the imported jsx modules? At this point, how does this process work? Shall I transpile the storybook components from the remote repo or do the job from my main application?
Thanks
On my last project, we used Rollup.js to create a dist build of just the components we had developed in Storybook. Our components were located in src/components directory. We maintained an index.js for the components using an internal scaffolding tool. We published our dist folder as a privately scoped NPM package and then pulled in our components from there.
For local development, we used Webpack aliasing to check the current environment and either pull the published NPM package or pull directly from the storybook/dist folder that we were building to.
There's a great guide on building this here. Hope this points you in the right direction. As an alternative, I believe you can fiddle with next.config.js to override the Webpack config and make sure that your external imports get sucked up through the same Webpack, but, you also have to add a few rules to the .babelrc on the Storybook side to ensure that it gets ignored over there. We found it to be easier to just publish a package and bundle everything up.
I'm developing my first big react app, which will be served dynamically by Express, so it came to my mind, that dependencies (not devDependencies) are just Express and maybe some deployment keep-running-eternally package, but not react, redux, react-router etc, which are conventionally mentioned in package.json deps. All my app is bundled and cooked before deployment, so how correct is it to mention react related deps as dependencies in config.json?
This library is, after I have tried several boiler plates for react server-side-rendering, the simplest! Unlike other libraries which consist a lot of complicated things at first (redux, relay, graphQL etc.,) this library gives detailed explanation on how to do isomorphic react app with the minimum set of only react express and few other necessary ones: (or course in ES6, too)
https://medium.com/front-end-hacking/server-side-rendering-with-react-and-express-382591bfc77c
You just need to install it:
npm install react-server-boilerplate --save
After that, build and start
cd react-server-boilerplate
npm install
npm run build
npm start
Then, use curl in your command line's terminal so check if it truly returns data for SSR or not :
curl http://localhost:8080
The github of that library: https://github.com/Roilan/react-server-boilerplate
I started to build a component library that I want to publish on NPM (and reuse in other apps) by creating a React app using create-react-app. Unfortunately the create-react-app default configuration doesn't seem to support building such component libraries (see these issues). So it seems I have to eject.
Do you have some instructions what to configure after ejecting to make this a component library I can reuse in other apps (I guess some Webpack stuff)?
Re-framing my comments into an answer.
Don't eject! CRA hides a lot of stuff under the hood and ejecting throws it up. It's relatively easier to just clone your src into another project with the tooling setup done.
And it's not very difficult to setup one yourself! Here's the things you will need to do:
Basic babel and webpack configuration so your code compiles.
Make sure React and React-DOM are added as external dependencies in your package.json file and added as alias in your webpack.config.js. (A thorough discussion is here.) This is important to ensure you ship the smallest bundles only. Also, React doesn't play well with multiple copies.
Optionally, do the same for any other heavier libraries, e.g. Material-UI, Bootstrap, Lodash etc.
In webpack's configuration, decide how you want your library exports should be? You should be good with UMD.
Add main (and optionally module) entries in your package.json to let npm imports know where the components should be imported from.
Publish it.
Done!
Or, you can simply clone one of these super thin component projects and put in your components there -
https://github.com/wangzuo/react-progress-label
https://github.com/aaronshaf/react-toggle
There are more complete starter-kits as well, but IMO it's important to first know the details yourself before you abstract them away. Once you are familiar with the process, you should try leveraging the kits too as they go much beyond the basics, like test integration, react-storybook support and great npm publishing support.
UPDATES:
The purpose of CRA is to allow quick experimentation and on-boarding to React development, without going through the (somewhat complicated to a beginner) tooling setup. The intended use case of CRA, as denoted by the "App" in the name, is the whole app, not a component. Although developing anything built on language features like ES6 takes some tooling, an app typically takes more setup than a component. E.g. you also need a server component which hosts the generated code. CRA does all this and more for you.
And if you are working on an app, you will eject when you want to take control of the server side of it. It adds value in that case as you will get the basic hosting code auto-generated by CRA during eject.
To address test needs, CRA also has Jest integration, which is a test runner having React specific features like snapshot testing. Again, setting it up manually with your build pipeline is a handful and CRA once again hides all of this complexity from you, so you can simply focus on writing the tests.
This is super simple - you don't actually need webpack if you want to publish a package. Don't install it just for that if you don't want to.
If you use ES6:
You can use a simple script to create a dist folder that babel will create the files after transpiling:
"scripts": {
// other scripts
// .. might want to change "rm -rf" below if you're on a PC
"build:production": "rm -rf es && cross-env NODE_ENV=production node_modules/.bin/babel ./src -d es"
},
What this does is:
Remove the es folder, which is a build folder.
Runs babel for your files (in case they are located in src folder, change it to wherever your files reside) and create the es folder with the transpiled files.
In order to use the script above you need to install the following dependencies:
babel-cli / babel-core / babel-preset-es2015 / cross-env
Make sure you have a .babelrc file so that babel will work:
{
"presets": [
["es2015", { "modules": false }]
]
}
Now all you have to do (after running npm run build:production) is to run:
npm publish
And your library is published in npm. This is also the command you run if you want to update, just don't forget to update the version number in your package.json.
In case you have files you dont want published to npm, just have a file in your root called .npmignore (similar to .gitignore) and list everything you want excluded.
If you don't use ES6:
In this case you don't need to transpile anything, just go straight to the npm publish section above and run it on the root folder you want published.
create-react-app is meant for quick setting up and development of apps, not really for development of libraries. For one thing, create-react-app creates an index.html file when building, which is usually not needed by libraries. Libraries require a different set of configuration (much less).
I faced this problem myself and have written a React component boilerplate for writing and publishing React components: https://github.com/yangshun/react-component-starter, after referencing how popular ES6 libraries were written, such as Redux.
Pros:
Similar to create-react-app, batteries are included
It has got all the important areas covered: development, linting, testing, and distributing
Minimal configuration
Babel for transpilation to ES5 and CommonJS format
ESLint included and configured
Jest tests examples
Webpack configuration that compiles to UMD
React Storybook for quick development of the components
Support for stylesheet distribution alongside your component
Cons:
Highly opinionated in terms of choice of tooling; they follow the choices set by create-react-app.
Have to manually update each package dependencies in future (you'll face this issue if you did eject anyways)
There is minimal configuration included and setup is easy. The various webpack, Babel and ESLint configurations should be quite understandable.
Hope this will be helpful to you. Feel free to give suggestions and comments on how it can be improved.