Привет всем, В этом уроке мы рассмотрим, как создать простой клон Hacker news с помощью Remix и Tailwind css.
Remix — это полностековый фреймворк react, который рендерит данные на сервере и отправляет html на сторону клиента в качестве ответа.
Давайте кодить!!!
Предварительные условия: Версия Node должна быть не ниже 16.3.0.
Настройка Remix:
Давайте сначала настроим наше приложение remix. Откройте терминал и введите следующее
# create the remix boilerplate
npx create-remix@latest
# Answer the basic questions
**Where would you like to create your app?** remix-hn-clone
**What type of app do you want to create?** Just the basics
**Where do you want to deploy? Choose Remix if you're unsure; it's easy to change deployment targets**. Remix App Server
**Do you want me to run `npm install`?** Yes
**TypeScript or JavaScript?** TypeScript
# changing to project directory
cd remix-hn-clone
# run the application
npm run dev
Приведенная выше команда создает шаблонное приложение remix для начала. После запуска npm run dev
вы должны увидеть базовое приложение remix, отображаемое в браузере.
Теперь, когда установка remix завершена, давайте добавим tailwind css в наше приложение.
Настройка Tailwind css
Откройте терминал и выполните следующие команды
# install tailwind css
npm install -D tailwindcss
# create the configuration file for tailwindcss
npx tailwindcss init
Откройте файл tailwind.config.ts и добавьте в него следующее
module.exports = {
content: [
"./app/**/*.{ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
Теперь нам нужно добавить скрипты в наш package.json, чтобы он генерировал css во время сборки dev и production.
Обновите раздел скриптов в package.json следующим образом
"build:remix": "remix build",
"dev:remix": "remix watch",
"dev": "yarn build:remix && run-p dev:*",
"generate:css": "npx tailwindcss -o ./app/tailwind.css",
"dev:css": "npm run generate:css -- --watch",
"build:css": "npm run generate:css -- --minify",
"build": "run-s build:*"
Сценарий generate:css
использует команду tailwindcss cli для генерации css всякий раз, когда мы добавляем соответствующее имя класса в наш компонент.
Мы должны создать еще два скрипта для разработки и производства. dev:css
будет генерировать соответствующий css для среды разработки, и поскольку мы сопрягли его с опцией --watch
, генерация css происходит в фоновом режиме.
Для производственной среды мы можем создать еще один скрипт prod:css
, который минифицирует css-активы.
Наконец, с помощью команды run-s cli мы создаем сценарий build
, который последовательно выполняет команду. Так run-s build:*
сначала запустит remix build
, а затем скрипт build:css
.
Теперь, когда мы интегрировали скрипт, давайте добавим ссылку на tailwind в наше приложение.
Откройте файл app/root.tsx
и добавьте в него следующее содержимое
import styles from "./tailwind.css";
export const links = () => [
{ rel: "stylesheet", href: styles },
];
Зачем добавлять ссылки на стили в файл root.tsx
?
В Remix есть классная функция под названием route based styling
. Поэтому, когда мы добавляем стили, необходимые для конкретной страницы, в определенный файл маршрутов, Remix сам позаботится о загрузке и выгрузке стилей при каждой загрузке страницы.
Подробнее о стилизации на основе маршрутов
Поскольку у нас будет одностраничное приложение, которое будет отображать новости из api, мы можем добавить стили либо в файл app/root.tsx
, либо в файл app/routes/index.tsx
.
Теперь, когда интеграция завершена, мы можем начать использовать классы tailwind в наших компонентах. Откройте файл app/routes/index.tsx
и замените его следующим содержимым
export default function Index() {
return (
<div>
<h1 className="font-serif text-center p-4">Welcome to Remix</h1>
</div>
);
}
Когда вы проверите браузер с открытым chrome dev tools, вы увидите, что классы успешно применяются к тегу h1
.
Отлично, мы успешно интегрировали remix с tailwind css. Следующий шаг — использовать hacker news api для получения данных и их отображения.
Многоразовые компоненты:
Создайте components/layout.tsx
в папке app
и добавьте следующее содержимое.
// layout.tsx
import { NavLink } from "@remix-run/react";
const Layout = ({ children }: any) => {
return (
<>
<header className="text-gray-600 body-font">
<div className="container mx-auto flex flex-wrap p-8 flex-col md:flex-row items-center">
<NavLink
to="/"
className="flex title-font font-medium items-center text-gray-900 mb-4 md:mb-0"
>
<span className="text-xl">Hacker News</span>
</NavLink>
</div>
</header>
<div className="mx-auto container p-8">{children}</div>
</>
);
};
export default Layout;
В компоненте layout мы используем компонент NavLink
от remix для навигации между страницами.
Давайте создадим простой компонент карточки, который мы будем использовать позже в нашем приложении. Создайте файл под названием Card.tsx
в папке components
и вставьте в него следующее содержимое.
* Примечание:
*
# we will be using moment lib to mess with dates
npm install moment
import moment from 'moment';
export type CardProps = {
title: string
point: string
author: string
time: number
}
const Card = (props: CardProps) => {
return (
<section className="text-gray-600 body-font overflow-hidden">
<div className="py-2 mx-auto">
<div className="-my-8">
<div className="py-8 flex flex-wrap md:flex-nowrap">
<div className="md:flex-grow">
<h5 className="font-medium text-gray-900 title-font mb-2">
{props.title}
</h5>
<p className="leading-relaxed">
{props.point} by {props.author} {moment.unix(props.time).fromNow()}
</p>
</div>
</div>
</div>
</div>
</section>
);
};
export default Card;
Мы будем использовать как card
, так и layout
, когда будем кодировать нашу главную страницу приложения.
Последний шаг!!!
Рендеринг новостных статей:
Давайте теперь получим данные из hacker news api и отобразим их на экране. Откройте файл routes/index.tsx
и добавьте в него следующее содержимое.
import { useLoaderData } from "@remix-run/react";
import Card, { CardProps } from "~/components/card";
import Layout from "~/components/layout";
interface CardDataProps extends CardProps{
url: string
score: string
by: string
}
export async function loader() {
const response = await fetch(
"https://hacker-news.firebaseio.com/v0/newstories.json?print=pretty"
);
const storyIdentifiers: any = await response.json();
let newStories = [];
if (storyIdentifiers) {
for (let i = 0; i < 15; i++) {
const storyResponse = await fetch(
`https://hacker-news.firebaseio.com/v0/item/${storyIdentifiers[i]}.json`
);
const story: any = await storyResponse.json();
newStories.push(story);
}
}
return newStories;
}
export default function Index() {
const data = useLoaderData();
return (
<Layout>
{data &&
data.map((d:CardDataProps) => {
if (d.url) {
return (
<a href={d.url} target="_blank" rel="noopener noreferrer" >
<Card
title={d.title}
point={d.score}
time={d.time}
author={d.by}
/>
</a>
);
}
<Card title={d.title} point={d.score} time={d.time} author={d.by} />;
})}
</Layout>
);
}
Краткое описание кода
Давайте начнем с самого начала. Мы импортировали наши многократно используемые компоненты, а также функцию useLoaderData
из remix
.
useLoaderData
— это пользовательский хук, предоставляемый remix для загрузки данных в компоненты. Remix также предоставляет функцию loader
, которую мы будем вызывать на сервере перед рендерингом страницы.
Внутри функции loader
мы получаем данные из api, манипулируем ими и возвращаем ответ, а затем разбираем ответ в компоненте и передаем его в качестве реквизита компоненту карты.
Когда вы откроете браузер и перейдете по адресу dev url. Вы должны увидеть следующее
Вот и все. Мы закончили. Теперь мы успешно создали базовое приложение Remix с помощью tailwind css.
Полезные ресурсы:
- Документы Remix
Заключение
Вот, в общем-то, и все. Спасибо, что нашли время прочитать это руководство. Я надеюсь, что все поняли, как создать базовое приложение remix.
Если вы нашли этот пост полезным, добавьте ❤️ к нему и дайте мне знать, если я что-то упустил или если у вас есть сомнения в коде, не стесняйтесь спросить в разделе комментариев.
Отзывы о туториале приветствуются.
Развернутая ссылка: https://hacker-news-clone-remix.pages.dev/
Социальные ссылки:
Twitter
Витрина