Серия блогов React: Часть первая
Эта статья является первой в еженедельной серии статей о создании блога с помощью React и является основой для остальной части этой серии.
Серия блогов React
Часть первая: Создание веб-сайта с помощью React и Bulma
Часть вторая: Создание блога с помощью React и Contentful
Часть третья : Импортируйте свой канал Medium в React
Часть четвертая: Добавление Redux в блог React
Часть пятая: Замена Redux Thunks на Redux Sagas
Часть шестая: (В процессе) Написание модульного теста для блога React с Redux Sagas
Настраивать
Итак, давайте установим React
npm install -g create-react-app aaronklaser cd aaronklaser npm start
Затем давайте установим кое-что из того, что, как мы знаем, нам понадобится:
React Helmet
Bulma
Расширения Bulma
Moment
Стилизованные компоненты
npm install bulma bulma-extensions moment react-helmet styled-components --save
Настройте React для использования Sass
Это может быть не совсем необходимо, потому что мы в основном будем использовать стилизованные компоненты, но это значительно упростит импорт Bulma.
Теперь что касается сложной части, нам нужно настроить Sass, но я не хочу, чтобы вам приходилось извлекать из приложения create-react-app. Я последовал этому туториалу.
npm install --save node-sass-chokidar
Это создаст файлы .css из наших файлов .scss, от которых я не особо помешан, но пока давайте разберемся с этим. Мы хотим игнорировать наши файлы css в git, поэтому добавьте src/**/*.css
в наш файл .gitignore.
Установите npm-run-all, чтобы мы могли включить нашу сборку scss в npm start
npm install --save npm-run-all
В package.json в сценариях npm добавьте build-css и watch-css, build-js и watch-js, а также измените build и начните использовать все наши новые scss-файлы.
"scripts": { "build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/
", "watch-css": "npm run build-css && node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/ --watch --recursive
", "start-js": "react-scripts start", "start": "npm-run-all -p watch-css start-js", "build-js": "react-scripts build", "build": "npm-run-all build-css build-js", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" }
ПРИМЕЧАНИЕ. Важно включить --include-path ./src --include-path ./node-modules
как в build-css, так и в watch-css. Это позволяет нашему коду находить библиотеки, такие как Bulma, в нашей папке узловых модулей.
Добавление расширений Bulma и Bulma
Мы собираемся включить Bulma и любую конфигурацию Bulma в компонент индекса. Начните с переименования index.css
в index.scss
, затем перезапустите приложение, используя npm start
Если ничего не взорвалось, и ваш проект теперь включает index.scss и index.css, значит, все работает правильно.
Затем в вашем index.scss import bulma.
@import 'bulma/bulma'; @import 'bulma-extensions/extensions';
Но я собираюсь сделать несколько шагов по добавлению, чтобы включить дополнительный цвет, потому что Bulma не включает фиолетовый в свои цвета по умолчанию, и я как бы хочу фиолетовый.
// 1. Import the initial variables @import "bulma/sass/utilities/initial-variables"; @import "bulma/sass/utilities/functions"; // 2. Setup your Custom Colors $purple: hsl(275,87%,45%); $purple-invert: findColorInvert($purple); // 3. Add new color variables to the color map. @import "bulma/sass/utilities/derived-variables.sass"; $addColors: ( "purple":($purple, $purple-invert), ); $colors: map-merge($colors, $addColors); @import 'bulma/bulma'; @import 'bulma-extensions/extensions';
Все должно запуститься, и ваши шрифты на стандартной домашней странице приложения create-react-app должны выглядеть иначе.
Теперь, когда мы закончили настройку, давайте с помощью Bulma разместим некоторые базовые элементы макета.
Базовый макет и заголовок
Позвольте мне немного поговорить о моей файловой структуре, потому что она немного отличается от того, что вы могли бы видеть.
Фрактальная файловая структура
Впервые я нашел идею фрактальных файловых структур в статье на Hackernoon. В первый раз, когда я прочитал статью, идея была не очень ясна, но одна вещь всплыла у меня, и я думаю, что я ее понимаю. Я могу ошибаться, но, тем не менее, мой метод ОЧЕНЬ хорошо зарекомендовал себя в последние несколько месяцев. Это своего рода расширение шаблона ReDucks, за исключением того, что вы создаете своего рода значение ключа или структуру родительского дочернего объекта с вашими файлами.
src |- index.js |- App.js |- app |- Layout.js |- layout |- Header.js |- Content.js |- Footer.js |- User.js |- user |- Profile.js |- PasswordReset.js |- Address.js |- components |- SharedCompOne.js |- SharedCompTwo.js
Итак, вы можете видеть, что мы начинаем группировать наш код по модулям или функциям, но мы не создаем миллиард папок для каждого компонента. Вместо этого мы храним наши компоненты в их родительской папке, используя PascalCasing для каждого имени компонента и camelCasing для этой дочерней папки компонентов. Единственное реальное исключение - App.js технически является дочерним по отношению к index, но я не уверен, что это имеет значение 🤔.
Преимущество этого заключается в том, что мы можем ясно видеть, что Header, Content и Footer - все компоненты, используемые в компоненте Layout, который используется в компоненте App. Если бы структура полей была более плоской, например:
/* This is NOT fractal */ src |- index.js |- App.js |- layout |- Layout.js |- Header.js |- Content.js |- Footer.js
Тогда у нас нет никаких реальных указаний на иерархию компонентов или на то, какие компоненты Layout.js даже используется, где, поскольку фрактальный шаблон показывает вам, кто именно использует какие компоненты и где. Это четкая родительская дочерняя структура, и макеты могут даже включать общую папку для компонентов, совместно используемых только внутри дочерних макетов.
Помните, как я упоминал ранее структуру ключевого значения. Это была идея, которая заставила все это щелкнуть в моей голове. Итак, если вы возьмете мой первый пример, вы подумаете об этом так:
src: { Index.js, App.js: { Layout.js: { Header.js Content.js Footer.js } } User.js: { Profile.js PasswordReset.js Address.js } components: { SharedCompOne.js SharedCompTwo.js } }
Наш сайт начинает выглядеть как данные JSON… вроде как, но вы поняли. «Ключ» - это всегда компонентный файл .js. «Значение» - это, как всегда, папка с именем ключа, содержащая все дочерние компоненты.
Где это действительно начинает сиять, так это в вашем магазине, который я храню отдельно от моего презентационного слоя (приложения). Теперь мы можем начать структурировать наш магазин, как нашу структуру данных. Это ДЕЙСТВИТЕЛЬНО хорошо работает с NoSQL.
Мы поговорим об этом позже.
Начнем с приложения
- В корне создайте папку с именем app и создайте в ней файл с именем Layout.js
- В папке приложения создайте папку с именем layout
- В папке макета создайте 4 файла: Site.js, Header.js, Content.js и Footer.js.
App.js вызовет компонент Layout и позже включит наш Redux Store.
Layout.js будет содержать Site.js и Content.js, которые являются всего лишь оболочкой стилизованного компонента для сайт и контент, чтобы мы могли правильно настроить flexbox, а также компоненты Header.js и Footer.js.
Вот эти 5 файлов помещены в один Gist для нашего удобства.
Настроить маршрутизацию на некоторые страницы
npm install react-router-dom
Мы создаем простой веб-сайт / блог, поэтому будем использовать BrowserRouter. Есть и другой вариант, который вы можете изучить, но это не тема для этого;)
В корне нашего приложения в src/index.js
мы собираемся обернуть приложение маршрутизатором.
import ReactDOM from 'react-dom'
import registerServiceWorker from './registerServiceWorker'
import { BrowserRouter
as Router } from 'react-router-dom'
import App from './App'
import './index.css'
ReactDOM.render((
<Router>
<App />
</Router>
), document.getElementById('root'))
registerServiceWorker()
Затем в папке приложения создадим две простые страницы Home.js
и Blog.js
.
import React from 'react' const Home = () => ( <p>This is the Home Page</p> ) export default Home
а также
import React from 'react' const Blog = () => ( <p>This is the Blog Page</p> ) export default Blog
Теперь, когда у нас есть несколько страниц для маршрутизации, давайте настроим компонент Router. На данный момент мы не будем пытаться делать с ним что-нибудь интересное, только простой и понятный Switch and Route.
В нашу папку макета добавляем новый файл call Router.js
. Этот маршрутизатор будет находиться внутри содержимого нашего Layout.js
файла. Здесь будут размещаться наши основные страницы верхнего уровня.
<Content> <Router /> </Content>
На страницах можно создавать дополнительные компоненты Routers, чтобы добавить более глубокую вложенную маршрутизацию. Наши соглашения об именах для тех, кто в будущем, будет их именем родительского компонента и Router. Например, BlogRouter.js или HomeRoute.js. Помните, что они будут жить в папке с названием blog.
В нашем компоненте маршрутизатора нам нужен компонент Switch и внутри него список или наши маршруты, использующие компонент Route.
import React from 'react' import { Switch, Route } from 'react-router-dom' import Home from './../Home' import Blog from './../Blog' const Router = () => ( <Switch> <Route exact path='/' component={Home}/> <Route path='/blog' component={Blog}/> </Switch> ) export default Router
И, наконец, давайте настроим наш заголовок для вызова этих маршрутов.
А пока давайте просто внесем изменения для двух страниц, для которых у нас есть маршруты. Мы собираемся изменить наши <a>
в элементах навигации Blog и Logo Title.
<NavLink className="navbar-item" to="/" activeClassName="is-active" > <img style={{ borderTopLeftRadius: '50%', borderTopRightRadius: '50%', borderBottomLeftRadius: '50%', borderBottomRightRadius: '50%', marginRight: 15 }} src="https://media-exp2.licdn.com/mpr/mpr/shrinknp_400_400/AAEAAQAAAAAAAAU3AAAAJGE1MzYxNzYzLTE1NTUtNDEyYi04MzRjLTgzZjNkOGU0MGIzNg.jpg" width="30px" alt="" /> <span>AaronKlaser.com</span> </NavLink>
а также
<NavLink className="navbar-item" to="/blog" activeClassName="is-active" > <span className="icon has-text-primary" style={{ marginRight: 5 }} <i className="fas fa-code"></i> </span> Code Blog </NavLink>
Обратите внимание, что мы добавили activeClassName=”is-active”
. Это потому, что это активный класс Bulma nav. Самое замечательное в NavLink - это то, что он всегда проверяет, на какой странице вы находитесь, и если ваш маршрут совпадает с NavLink to
, он автоматически добавит is-active. Если вы не хотите добавлять активный класс, просто просто используйте компонент Link.
Заключение
Итак, это базовый фрейм приложения.
Рассмотрение
- Настройте сайт React с помощью приложения create-react-app
- Настройте React для сборки SassI
- Установлена Bulma
- Мы узнали о фрактальных файловых структурах
- Создал верстку сайта
- Настроить маршрутизацию
- Добавлены несколько страниц для перехода к
Еще не все! Я обновлю этот пост соответственно.