Build a React UI Library from scratch - TypeScript, Storybook, Jest & Rollup

Поделиться
HTML-код
  • Опубликовано: 27 июл 2024
  • We're doing a deep dive into how to build a React UI Library from scratch in this video - building a simple Button with a variant prop and creating a "story" of it as well as tests. We also publish to NPM and import it directly into another project. If this helps, please drop a like and comment to let me know if you need me to cover anything else (or if you just wanna say hi!) ✌️
    Code: nickderaj.com/youtube/react-u...
    Chapters:
    00:00 - Introduction
    00:30 - Initialise the NPM project
    01:50 - Setting up TypeScript & what the settings mean
    07:24 - Folder structure - why use index.ts?
    10:34 - Setting up Rollup
    15:12 - Publishing to NPM
    17:52 - Importing the package in another project
    19:14 - Customising our Button
    22:25 - Adding postcss to Rollup
    26:10 - Setting up Storybook
    27:44 - Adding a Button.stories.ts file
    30:07 - Adding react as a peer dependency
    30:32 - Setting up tests with Jest
    33:09 - Final deployment
    33:55 - Outro & Thanks :)
  • НаукаНаука

Комментарии • 51

  • @bigbigfoot3365
    @bigbigfoot3365 26 дней назад

    Thanks for your work.

  • @craiggazimbi
    @craiggazimbi 25 дней назад

    Dude. You are amazing . Thank You

    • @nickderaj
      @nickderaj  25 дней назад

      I’m glad it helped! Thanks :)

  • @rohithroshan3843
    @rohithroshan3843 Месяц назад

    thank you so much for this lesson

    • @nickderaj
      @nickderaj  Месяц назад

      You're very welcome!

  • @Dhanushsaji
    @Dhanushsaji 2 месяца назад

    I have a style.css with my jsx file. When I build this and publish, the component ia working but style.css isn't reflecting on the component

  • @zenobiusztasak8604
    @zenobiusztasak8604 4 месяца назад

    I am trying to use useNavigation from 'react-router-dom' inside my Button component and after exporting in another project I am facing the error:
    Cannot read properties of null (reading 'useContext')

  • @interestingcoding4698
    @interestingcoding4698 7 месяцев назад +1

    Thank you for sharing the repo, I really understood but I don't wanna do it from scratch hehe,

    • @nickderaj
      @nickderaj  7 месяцев назад

      Haha I’m the same, I like to follow along with the video but not write it all from scratch

  • @abhishekmishra5872
    @abhishekmishra5872 29 дней назад

    I followed the video. Everything works fine except css. What could be the problem?

  • @sohamdalal220
    @sohamdalal220 4 месяца назад

    I have some error . This is my error:
    code E402
    npm ERR! 402 Payment Required

  • @zishanahmad3662
    @zishanahmad3662 20 дней назад

    Hey, awesome video! I had a lot to learn.
    I need some help. Initially, the project I'm working on had a 'components' folder containing all the Box, Button, Input, etc. My project simply used those components.
    We decided to move to a monorepo approach. I successfully used Rollup to create that bundle. The bundle size in its unzipped form is around 132 KB. However, when I include it in our project and import Buttons or Inputs in many files, and try to build this project (since it's also a React library), the bundle size increases exponentially. After replacing all occurrences with component imports and building it, my bundle size increased by 16 MBs. I've tried what I could, but I really need help to resolve this. For now, I've simply marked it as external, but I want to understand the root cause of this problem and how we can fix it.
    I would really appreciate your help if possible !

  • @shopme1122
    @shopme1122 4 месяца назад

    I am creating a serious Ui library but the problem with the rollup is that it doesnot support experimental things like "use client" and others. And i also found it terrible for large projects as it bundles all components inside a single file and had problems splitting them. Considered moving to webpack for now.

  • @tapatap-ed2py
    @tapatap-ed2py 5 месяцев назад

    great video, looking for something similar
    question : do you recommend building using javascript ,coz in out company we dont use typescript , what should i do differently with js

    • @nickderaj
      @nickderaj  5 месяцев назад

      Typescript is just built on top of JavaScript - everything you can do in TypeScript you can do in JavaScript, just don't add the types!

  • @kanchanakularathna9422
    @kanchanakularathna9422 7 месяцев назад +1

    Hi Nick, Thanks a bunch! I managed to create a component library following your advice, and it's working well. I have a couple of questions I'd love your input on. First, when dealing with more complex components like a calendar or a data table, what's the best approach? Is it okay to use third-party libraries, or is that a bit too much? Second, if we go with third-party libs, how do we handle dependencies to prevent conflicts with other components and the main project( the one that we use this lib as a dependancy)? I'd appreciate your guidance on the most recent approach. Also, could you show me how to stay updated with these libraries, especially if we lock dependancies? Lastly, I'm stoked about using TypeScript, but I'm wondering if other third-party libs we want to use for composite components might not support TypeScript. Any advice on that front? Thanks again!

    • @nickderaj
      @nickderaj  7 месяцев назад +1

      Hey Kanchana, glad it helped!
      Regarding complex components, it's up to you really. You can built them from scratch using JS and CSS, you could use external libraries like Tailwind or you could use a UI library like Material UI. My preferred approach is using Tailwind and building them from scratch since I have full control over everything but do whatever style you like. One thing to note is that UI libraries can bloat your package and make the file size unnecessarily big if that's a concern.
      For dependency conflicts, I haven't had any so far honestly so can't really advise on that - but when we build & publish the package I think Rollup should handle that side of things.
      To stay up to date with packages in your Github repo you could use dependabot to auto-update packages, then you'll have to release a new version of the package for users to update to on their side (github.com/dependabot).
      Finally, TypeScript compiles down to a couple of files - one is a plain JavaScript file and one is a "types" file. If the user is only using JavaScript it will just ignore the types file and work as intended so don't worry about that!
      Hope it helps! ☺

    • @kanchanakularathna9422
      @kanchanakularathna9422 7 месяцев назад

      @@nickderaj
      Thank a million for your support.🙏 You're Absolutely right!!!. I had a bad experience using other UI libraries like Material-UI or Semantic UI within our UI library, because they made our bundle size larger with unnecessary code. The main issue was conflicts with dependencies. For example, if Material-UI's date picker uses Dependency A and Semantic UI's file uploader also uses the same Dependency A, both end up in our node-modules. Now, if we upgrade the date picker, Semantic UI's file uploader might still be using the old version of Dependency A. This can lead to breaking changes, causing issues with the entire UI library. I hope you understand what I mean.
      I'm finding it challenging to build components like a calendar with a date range selector, charts, data table with lazy loading or pagination, drag-and-drop rows, sorting, etc. 😓 I really appreciate the way you approach things and create your components. However, it's a bit difficult for me to think about some features. I'm worring some times when stakeholders asking me, why should we build a component if It's already build🙃. Your advice could be really helpful for me.

    • @nickderaj
      @nickderaj  7 месяцев назад

      @@kanchanakularathna9422
      I think you might be over-engineering it if you're trying to make it entirely future-proof. You don't HAVE to update all the packages all the time - some people are still using NextJS 12 for example, using the pages router, since it works as intended in production and updates will cause engineers to spend a bunch of time (money) on updates which won't make any difference to the end user.
      If you're time constrained then you can do the quick way using a UI library or copy-paste some existing components and fix the issues that arise when you update packages a few months/years down the line when you have more time or just don't update the packages unnecessarily (only if there's some security issues for example).

    • @kanchanakularathna9422
      @kanchanakularathna9422 7 месяцев назад

      ​@@nickderaj Thank you for the explanation. Actually, my first task is to develop a new UI library in my new workplace. Your ideas are very important to me as I make future decisions. Thanks again 🙌

  • @interestingcoding4698
    @interestingcoding4698 7 месяцев назад +1

    Question, are not npm and yarn the same? (package manager)

    • @nickderaj
      @nickderaj  7 месяцев назад +1

      They do the same thing but yarn is a little bit quicker/more secure. There’s others like pnpm as well that are better for monorepo projects (lots of projects in one repo) but for the most part I just use yarn!

  • @Dhanushsaji
    @Dhanushsaji 2 месяца назад

    Throwing error while using hooks

  • @silentco_der
    @silentco_der 6 месяцев назад +1

    Hi Nick i have done it exact in your way and i have used it on my nextjs project too and it works fine. My problem is when i deploy that nextjs project on Vercel then it shows me some kind of error telling authentication token not provided and i chatgpt it and added token on environmental variables too but the error keeps coming so can you please provide me some suggestion how to fix it and when some other person uses my library also i don't want them to face same problem as well and i can't provide my authentication token for everyone also.

    • @nickderaj
      @nickderaj  6 месяцев назад

      Did you deploy a project from a template? There isn’t authentication token at build time in the package I built - you sure it’s not from your project itself?

    • @silentco_der
      @silentco_der 6 месяцев назад

      @@nickderaj i have made a simple nextjs project and i have used my library component only but while i deploy that project into vercel it throws an authentication token not provided error so how to set authentication token at build time ?

    • @nickderaj
      @nickderaj  6 месяцев назад

      @@silentco_der You can set it in your vercel configs, it sounds like you're missing an environment variable..? But it shouldn't be coming from the package you made unless you added something not in the video

  • @ugryksl
    @ugryksl 8 месяцев назад +1

    Hello Nick,
    Firstly, thank you for this video.
    I understand how to build library and I made it.
    But, i can't see anything at all. how to serve this package on like localhost or something else ?

    • @nickderaj
      @nickderaj  8 месяцев назад

      Glad it helped! :)
      Check the part at 15:12 onwards - we publish the package to the NPM repo so you can just import it into your other projects with “npm install” like any other public package

    • @ugryksl
      @ugryksl 8 месяцев назад

      @@nickderaj Okay, I got it that part. you are great :). I publish it to our private npm server and we are trying in our react projects and works perfect :). Actually my question is different. I want to see what I am doing while coding components. example, "npm start" and serve localhost:8080 in library project.
      I am trying like rollup-html rollup-serve plugin and I changed rollup.config.mjs but doesnt work. Because in "dist" directory has no index.js, App.js and index.html for react lifecycle.
      I hope, i explained myself :)

    • @nickderaj
      @nickderaj  8 месяцев назад

      Ahh I get what you mean, you can’t run it like normal unless you create an index.html or something since it’s just components. I wouldn’t create it however since it’s not relevant to a UI package
      That’s why I added the Storybook package so we can see the components and make changes without having to publish every time. You can see around 29:18 I’m viewing the components I built without publishing

    • @ugryksl
      @ugryksl 8 месяцев назад

      @@nickderaj okay, thank you so much for explanation. I get it why dont create reactjs things. Have a good day :)

  • @ekchills6948
    @ekchills6948 4 месяца назад

    best video I've seen so far. but i'm having some problems... i use tailwind but after bundling my styles dont refllect
    any idea what the issue is?

    • @nickderaj
      @nickderaj  4 месяца назад +1

      Thank you! :)
      I had a bunch of issues with compiling the CSS so after a day of banging my head against the computer I decided to just accept it and install Tailwind on the projects that use it, which I likely would have done anyway.
      I might revisit this in the future though, saw some people said to use babel or some bundler packages, think it was called "swc" if I remember correctly, to fix it.

    • @ekchills6948
      @ekchills6948 4 месяца назад

      @@nickderaj ohh I see. Thanks for the response. I'll just do as you've said and install tailwind on the projects that needs it.

  • @martinburford7618
    @martinburford7618 5 месяцев назад

    Hi there, I experienced the same issue with the styles not showing from the button.css file. However, you moved straight onto Storybook, even though you commented on this issue. Do you know what the solution to this would be please? Many thanks

    • @martinburford7618
      @martinburford7618 5 месяцев назад

      I tried changing the postcss settings to: postcss({ extensions: ['.css'], inject: false, extract: true, modules: true }),

    • @martinburford7618
      @martinburford7618 5 месяцев назад

      But then I need to do: import { Button } from "packagename"; AND import "packagename/dist/esm/index.css";

    • @martinburford7618
      @martinburford7618 5 месяцев назад

      How would you propose just being able to do: import { Button } from "packagename" ... so that the component AND the components styles (in the Button.css file) come down via that import?

    • @nickderaj
      @nickderaj  5 месяцев назад

      Hey, sorry I can’t remember the exact solution to this as it was awhile ago but I’ll revisit this as I had quite a few issues with the css side and remember seeing the dist/esm/index.css trick but it looked horrible.
      I remember on another project I just used tailwind across the board and installed tailwind on the project using it as well to avoid this whole css issue. Also saw people commenting that babel would’ve been a lot easier when I was looking up this issue so might give that a go next time.
      An alternative solution would be to load all your css files (or put them all into one root index.css and import that) in the main file of your app and all the styles should be imported

  • @oddfeeling7956
    @oddfeeling7956 5 месяцев назад

    Your head blocks away the installed dependencies for rollup highlighting the packages on the screen would have been useful

    • @nickderaj
      @nickderaj  5 месяцев назад

      The code (and the package.json) file are in the link in the description

  • @Dhanushsaji
    @Dhanushsaji 2 месяца назад

    Adding custom css part also import in making libraries , you aren't covering that

  • @rohithroshan3843
    @rohithroshan3843 Месяц назад

    can you please share roolup comment

    • @nickderaj
      @nickderaj  Месяц назад

      Which rollup comment are you referring to? The code is in the description if that helps!

    • @rohithroshan3843
      @rohithroshan3843 27 дней назад

      hi @@nickderaj , how set the tailwind config

  • @lokeswaranaruljothy8100
    @lokeswaranaruljothy8100 5 месяцев назад

    I like this video but you audio is not clear enough. May be next time try to record audio without earphones

    • @nickderaj
      @nickderaj  5 месяцев назад +1

      Oh hm thanks for letting me know, I tried without the mic but it picks up the sound of me typing - I'll try invest in a little mic soon

  • @nishantkumar6960
    @nishantkumar6960 9 месяцев назад +2

    Your face was too far away from the camera, please come closer.

    • @nickderaj
      @nickderaj  9 месяцев назад +1

      Is that sarcasm ? 😂 my table is super short