TSDX #
TSDX is a very useful tool that helps us create a react library with typescript and much more configurations out of the box, with just one command. I have been using it for some months, and see it recently got some upgrades. It now also offers the possibility of using storybook, which will be interesting for this case, once we are going to develop a library for presentational components and we want to have a way to see them working in an isolated way.
Lets start. In packages folder execute:
npx tsdx create ui-webI choose the template react-with-storybook. It will take some time to create the library.
I will leave work with storybook for later. Go to the created project folder:
cd ui-webUpdate packages/ui-web/package.json name to @mr/ui-web:
"name": "@mr/ui-web",React Web Component #
We are going to create a presentational react component. It is just a component with book information. I am not working on the styles.
Book Card #
For now, we are only able to use the inline css, but it is not the best approach. Since we are using an external lib it will need some more setup to generate an external css to be used on our application, which bundles with webpack. My preference goes to css modules, however, we will let it for another time.
Another solution would be to use CSS in JS, since css is generated with javascript in runtime, it will not need extra setups in regard to the build. However, I prefer to use plain css in the web, since browsers perform very well with css and not so good with javascript. Too much javascript could be harmful to the performance of our web application.
Here, I am not taking attention to style:
src/components/BookCard/index.tsx
import React from 'react';
export default function BookCard({ book }: { book: any }) {
return (
<div>
<h2>{book.title}</h2>
<p>{book.author}</p>
<small>{book.tag}</small>
</div>
);
}
Notice, I am using the book: any. I will fix it later to use our own IBook type.
src/index.tsx
import BookCard from './components/BookCard';
export { BookCard };
SPA Build Fix #
Started having conflicts with spa application in regard to dependency versions. I have explained it here. Now, this happens with babel-loader and jest. I am going to had it to nohoist, clear node_modules and execute yarn:
"nohoist": [
"**/react-native",
"**/react-native/**",
"**/babel-jest",
"**/babel-loader",
"**/jest"
]
Use BookCard #
We want to use our new component in our SPA application. So, on the root of our workspace we install it using lerna:
yarn lerna add @mr/ui-web --scope=@mr/spaLets build our packages:
yarn lerna run buildNotice, thanks to Lerna our build execute in the correct order. It would be a nightmare if we had to do it buy hand.
Now, we are ready to update our react web application (packages/spa) to use this new component from the library created:
packages/spa/App.js:
import React from "react";
import { allBooks } from "@mr/utils";
import { BookCard } from "@mr/ui-web";
function App() {
return (
<div>
<h1>List of Books</h1>
<ul>
{allBooks().map(function renderBook(book) {
return (
<li key={book.id}>
<BookCard book={book} />
</li>
);
})}
</ul>
</div>
);
}
export default App;
We we execute yarn start:spa it should show our books, using the BookCard component created in its own library.
Go to http://localhost:3000/
Next, I want to create a library for react-native components. And after that, play with react-native-web and find a way to uniform components between web and mobile.
Published