Как создать свой собственный шаблон React

1665608430 kak sozdat svoj sobstvennyj shablon react

Ник Карник

1*g3L9F6AO-jUW-QuQRFI3JA

Что такое Boilerplate?

В программировании термин шаблонный код относится к блокам кода, которые используются снова и снова.

Предположим, что ваш стек разработки состоит из нескольких библиотек, таких как React, Babel, Express, Jest, Webpack и т.д. Когда вы начинаете новый проект, вы инициализируете все эти библиотеки и настраиваете их для работы друг с другом.

С каждым новым проектом, который вы начинаете, вы будете повторяться. Вы также можете внести неувязки в настройку этих библиотек в каждом проекте. Это может вызвать путаницу при переключении между проектами.

Вот где на помощь приходят шаблоны. Шаблоны – это шаблон, который можно клонировать и повторно использовать для каждого проекта.

Модульная экосистема Javascript упрощает разработку приложений с помощью различных библиотек, фреймворков и инструментов. Шаблоны могут вызвать страх, если вы не понимаете основы их основных компонентов. Давайте узнаем об этих основных строительных блоках при создании собственных.

Нажмите здесь, чтобы получить источник на GitHub

Я использую Webstorm, Git, NodeJS 8.9, NPM 5.6 и React 16. Запустите свою любимую IDE, создайте пустой проект и начнём!

Git Repository: настройка

Создайте папку проекта и инициализируйте хранилище Git:

mkdir react-boilerplate && cd react-boilerplategit init

Вы можете подключить этот проект к своему репо на GitHub, используя эти инструкции.

Файл Readme

Каждый проект должен содержать целевую страницу с полезными инструкциями для других разработчиков. Давайте создадим файл README.md в корне проекта с таким содержимым:

# React-BoilerplateThis is my react-boilerplate
## Setupnpm installnpm run buildnpm start

GitHub отображает содержимое файла readme на целевой странице проекта.

Теперь зафиксируйте приведенные выше изменения в Git:

git add .git commit -m "created readme"

В конце каждой главы вы должны зафиксировать свой код в Git.

Структура папки

Создайте такую ​​структуру папок для своего проекта:

react-boilerplate    |--src       |--client       |--server

с командой:

mkdir -p src/client src/server

Эта структура папок является основной и будет развиваться, когда вы будете интегрировать другие библиотеки в проект.

Git Игнорировать

Когда мы создадим наш проект, будет несколько автоматически сгенерированных файлов и папок. Давайте скажем Git игнорировать некоторые файлы, о которых мы можем думать заранее.

Создайте .gitignore в корневой папке со следующим содержимым:

# Nodenode_modules/
# Webstorm.idea/
# Projectdist/

Комментарии в файле .gitignore имеют префикс #.

Менеджер пакетов узлов

Отправной точкой проекта узла является инициализация его менеджера пакетов, который создает файл под названием package.json. Этот файл необходимо проверить в Git.

Обычно он содержит:

  • Описание вашего проекта для NPM
  • Список ссылок на все установленные пакеты
  • Специальные сценарии командной строки
  • Конфигурация установленных пакетов

Перейдите к корню вашего проекта и введите следующее:

npm init

Заполните все детали, и после того, как вы их примете, npm создаст файл package.json, который выглядит примерно так:

{  "name": "react-boilerplate",  "version": "1.0.0",  "description": "Basic React Boilerplate",  "main": "  "scripts": {    "test": "echo \"Error: no test specified\" && exit 1"  },  "repository": {    "type": "git",    "url": "git+  },  "keywords": [    "Node",    "React"  ],  "author": "Nick Karnik",  "license": "Apache-2.0",  "bugs": {    "url": "  },  "homepage": "https://github.com/theoutlander/react-boilerplate#readme"}

Статическое содержание

Давайте создадим статический файл HTML src/client/index.html с таким содержимым:

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>React Boilerplate</title></head><body>    <div id="root">        Welcome to React Boilerplate!    </div></body></html>

Экспресс-веб-сервер

Чтобы обслуживать приведенный выше статический файл, необходимо создать веб-сервер в ExpressJS.

NPM v5 автоматически сохраняет установленные пакеты в разделе зависимостей в package.json, поэтому параметр —save атрибут не необходимо

npm install express

Я бы рекомендовал соблюдать условия имен файлов, где имена файлов пишутся малым регистром, а несколько слов разделяются точкой. Вы избежите проблем с чувствительностью к регистру на разных платформах, а также упростите именование файлов несколькими словами для больших команд.

Создайте файл src/server/web.server.js и добавьте следующий код для размещения веб-сервера через экспресс-программу и обслуживание статического файла HTML:

const express = require('express')
export default class WebServer {  constructor () {    this.app = express()    this.app.use(express.static('dist/public'))  }
  start () {    return new Promise((resolve, reject) => {      try {        this.server = this.app.listen(3000, function () {          resolve()        })      } catch (e) {        console.error(e)        reject(e)      }    })  }
  stop () {    return new Promise((resolve, reject) => {      try {        this.server.close(() => {          resolve()        })      } catch (e) {        console.error(e.message)        reject(e)      }    })  }}

Выше мы создали простой веб-сервер с командой запуска и остановки.

Нажмите здесь, чтобы узнать больше о Promises.

Файл запуска

Далее нам нужно создать индексный файл, который будет инициализировать разные компоненты высокого уровня. В нашем примере мы собираемся инициализировать веб-сервер. Однако по мере того, как ваш проект растет, вы можете инициализировать другие компоненты, такие как конфигурация, база данных, регистратор и т.д.

Создайте файл src/server/index.js со следующим кодом:

import WebServer from './web.server'
let webServer = new WebServer();webServer.start()  .then(() => {    console.log('Web server started!')  })  .catch(err => {    console.error(err)    console.error('Failed to start web server')  });

Бабель

Чтобы запустить вышеприведенный код ES6, нам нужно сначала превратить его в ES5 через Babel. Давайте установим Babel и зависимость babel-preset-env, поддерживающую транспиляцию ES2015:

npm i babel-cli babel-preset-env --save-dev

Создайте файл конфигурации Babel под названием .babelrc в корневом каталоге и добавьте в него следующие сведения:

{  "presets": ["env"]}

Предварительная настройка env неявно включает в себя babel-preset-es2015, babel-preset-es2016 и babel-preset-es2017 вместе, что означает, что вы можете запускать код ES6, ES7 и ES8.

Команды сборника

Давайте создадим команды для создания серверных и клиентских компонент проекта и запустим сервер. В разделе сценариев пакета.json удалите строку с командой test и добавьте следующее:

"scripts": {    "build": "npm run build-server && npm run build-client",    "build-server": "babel src/server --out-dir ./dist",    "build-client": "babel src/client --copy-files --out-dir ./dist/public",    "start": "node ./dist/index.js"}

Вышеуказанная команда сборки создаст папку dist/public в корне. Команда build-client просто копирует файл index.html в папку dist/public.

Запуск

Вы можете запустить транспилятор Babel на коде выше и запустить веб-сервер с помощью следующих команд:

npm run buildnpm start

Откройте браузер и перейдите к Вы должны увидеть результат своего статического файла HTML.

0*u2ynUivrvLjs-av0

Вы можете остановить веб-сервер, нажав C

Тестовый жгут: Шутка

Я не могу достаточно подчеркнуть важность внедрения модульных тестов в начале проекта. Мы собираемся использовать Jest Testing Framework, созданный для быстрого и удобного разработчика.

Во-первых, нам нужно установить Jest и сохранить его в зависимости от разработки.

npm i jest --save-dev

Модульные тесты

Давайте добавим два теста для запуска и остановки веб-сервера.

Для тестовых файлов следует добавить расширение .test.js. Jest сканирует папку src на наличие всех файлов, содержащих .test в названии файла, вы можете хранить свои тестовые случаи в той же папке, что и тестируемые файлы.

Создайте файл под названием src/server/web.server.test.js и добавьте следующий код:

import WebServer from './web.server'
describe('Started', () => {  let webServer = null
  beforeAll(() => {    webServer = new WebServer()  })
  test('should start and trigger a callback', async () => {    let promise = webServer.start()    await expect(promise).resolves.toBeUndefined()  })
  test('should stop and trigger a callback', async () => {    let promise = webServer.stop()    await expect(promise).resolves.toBeUndefined()  })})

Проверить команду

Давайте добавим npm для запуска теста в разделе сценариев package.json. По умолчанию Jest запускает все файлы, в названии которых есть слово .test. Мы хотим ограничить его исполнением тестов в папке src.

"scripts": {...    "test": "jest ./src"...}

Babel-jest автоматически устанавливается при установке Jest и автоматически преобразует файлы, если в вашем проекте существует конфигурация Babel.

Давайте запустим наши тесты с помощью такой команды:

npm test
0*4OQroTGQMuSlEg3j

Наша программа настроена на обслуживание статики HTML файл через an Экспресс веб-сервер. Мы интегрировались Бабель чтобы включить ES6 и Шутка для модульного тестирования Давайте сосредоточимся на настройках интерфейса.

Настройка React

Установите библиотеки react и react-dom:

npm i react react-dom

Создайте файл под названием src/client/app.js из:

import React, {Component} from 'react'
export default class App extends Component {    render() {        return <div>Welcome to React Boilerplate App</div>    }}

Давайте визуализируем программу через индексный файл в src/client/index.js из:

import React from 'react'import ReactDOM from 'react-dom'import App from './app'
ReactDOM.render(<App />, document.getElementById('root'))

Babel React

Если вы выполните npm run build-client, вы получите сообщение об ошибке, поскольку мы не сообщили Babel, как работать с React/JSX.

0*W-9sbHjloV7lyDfq

Давайте исправим это, установив зависимость babel-preset-react:

npm install --save-dev babel-preset-react

Нам также нужно изменить конфигурационный файл .babelrc, чтобы включить transpiling react:

{  "presets": ["env", "react"]}

Теперь, когда вы запускаете npm run build-client, он создаст app.js и index.js в dist/public с кодом ES6, транслируемым в ES5.

Загрузить скрипт в HTML

Чтобы подключить наше приложение React к HTML-файлу, нам нужно скачать index.js в наш файл index.html. Не забудьте очистить текст узла #root, поскольку приложение React будет подключено к нему:

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>React Boilerplate</title></head><body>    <div id="root"></div>    <script src="https://www.freecodecamp.org/news/how-to-build-your-own-react-boilerplate-2f8cbbeb9b3f/index.js"></script></body></html>

Запустить сервер

Если вы запустите свой веб-сервер и перейдете на вы увидите пустую страницу с ошибкой в ​​консоли.

Uncaught ReferenceError: требование не определено.

0*C0et_W8a6-CIWpJK

Это потому, что Babel – это только транспиллер. Чтобы поддерживать динамическую загрузку модулей, нам нужно будет установить Webpack.

Начните с изменения команд сборки под сценариями в package.json на build-babel:

"scripts": {    "build-babel": "npm run build-babel-server && npm run build-babel-client",    "build-babel-server": "babel src/server --out-dir ./dist",    "build-babel-client": "babel src/client --copy-files --out-dir ./dist/public",    "start": "node ./dist/index.js",    "test": "jest ./src"  }

Webpack

Webpack позволяет нам легко модулировать наш код и объединять его в один Javascript. Он поддерживается многочисленными плагинами, и, скорее всего, есть плагин почти для любой задачи по созданию, которое только можно придумать. Начните с установки Webpack:

Это руководство было опубликовано непосредственно перед выпуском webpack v4, поэтому мы явно установим webpack v3.

npm i webpack@^3

По умолчанию Webpack ищет конфигурационный файл под названием webpack.config.js, поэтому давайте создадим его в корневой папке и определим две точки входа: одну для веб-приложения, а другую для веб-сервера. Давайте создадим два объекта конфигурации и экспортируем их как коллекцию:

const client = {    entry: {        'client': './src/client/index.js'    }};
const server = {    entry: {        'server': './src/server/index.js'    }};
module.exports = [client, server];

Теперь давайте укажем, куда Webpack будет выводить пакет, и установим целевую сборку так, чтобы она игнорировала собственные узловые модули, такие как fs и path от объединения. Для клиента мы установим значение web, а для сервера узел.

let path = require('path');
const client = {    entry: {        'client': './src/client/index.js'    },    target: 'web',    output: {        filename: '[name].js',        path: path.resolve(__dirname, 'dist/public')    }};
const server = {    entry: {        'server': './src/server/index.js'    },    target: 'node',    output: {        filename: '[name].js',        path: path.resolve(__dirname, 'dist')    }};
module.exports = [client, server];

Babel Loader

Прежде чем мы сможем запустить Webpack, нам нужно настроить его для обработки кодов ES6 и JSX. Это делается с помощью загрузчиков. Начнем с установки babel-loader:

npm install babel-loader --save-dev

Нам нужно изменить конфигурацию Webpack, чтобы включить babel-loader для работы со всеми .js файлами. Мы создадим общий объект, определяющий раздел модуля, который мы сможем повторно использовать для обеих целей.

const path = require('path');
const moduleObj = {    loaders: [        {            test: /\.js$/,            exclude: /node_modules/,            loaders: ["babel-loader"],        }    ],};
const client = {    entry: {        'client': './src/client/index.js',    },    target: 'web',    output: {        filename: '[name].js',        path: path.resolve(__dirname, 'dist/public')    },    module: moduleObj};
const server = {    entry: {        'server': './src/server/index.js'    },    target: 'node',    output: {        filename: '[name].js',        path: path.resolve(__dirname, 'dist')    },    module: moduleObj}
module.exports = [client, server];

Для объединения вложенных общих объектов я бы рекомендовал проверить модуль Webpack Merge.

Выключение файлов

Webpack объединит ссылающиеся библиотеки, то есть все, что включено с node_modules, будет упаковано. Нам не нужно объединять внешний код, поскольку эти пакеты обычно минимизированы, и они также увеличат время сборки и размер.

Давайте настроим Webpack, чтобы исключить все пакеты в папке node_modules. Это легко сделать с помощью модуля webpack-node-externals:

npm i webpack-node-externals --save-dev

Далее следует настроить webpack.config.js для его использования:

let path = require('path');let nodeExternals = require('webpack-node-externals');
const moduleObj = {    loaders: [        {            test: /\.js$/,            exclude: /node_modules/,            loaders: ["babel-loader"],        }    ],};
const client = {    entry: {        'client': './src/client/index.js',    },    target: 'web',    output: {        filename: '[name].js',        path: path.resolve(__dirname, 'dist')    },    module: moduleObj};
const server = {    entry: {        'server': './src/server/index.js'    },    target: 'node',    output: {        filename: '[name].js',        path: path.resolve(__dirname, 'dist')    },    module: moduleObj,    externals: [nodeExternals()]}
module.exports = [client, server];

Обновить команду сборника

Наконец, нам нужно внести изменения в раздел сценариев в package.json, чтобы включить команду сборки, которая использует Webpack, и переименовать index.js в server.js для npm start, поскольку это то, что Webpack настроен для вывода.

"scripts": {    "build": "webpack",    "build-babel": "npm run build-babel-server && npm run build-babel-client",    "build-babel-server": "babel src/server --out-dir ./dist",    "build-babel-client": "babel src/client --copy-files --out-dir ./dist/public",    "start": "node ./dist/server.js",    "test": "jest ./src"  }

Build Clean

Давайте добавим команду для очистки наших папок dist и node_modules, чтобы мы могли выполнить чистую сборку и убедиться, что наш проект все еще работает правильно. Прежде чем мы сможем сделать это, нам нужно установить пакет под названием rimraf (это команда rm -rf).

npm install rimraf

Теперь раздел сценариев должен содержать:

"scripts": {..."clean": "rimraf dist node_modules",...}

Чистая сборка из Webpack

Теперь вы можете успешно очистить и создать свой проект с помощью Webpack:

npm run cleannpm installnpm run build

Это создаст файлы dist/server.js и dist/public/client.js в корневой папке.

Плагин HTML Webpack

Однако вы могли заметить, что index.html отсутствует. Это потому, что раньше мы просили Babel скопировать файлы, которые не были транслированы. Однако Webpack не может это сделать, поэтому нам нужно использовать плагин HTML Webpack.

Давайте установим плагин HTML Webpack:

npm i html-webpack-plugin --save-dev

Нам нужно включить плагин в верхней части конфигурационного файла webpack:

const HtmlWebPackPlugin = require('html-webpack-plugin')

Далее нам нужно добавить ключ плагинов к конфигурации клиента:

const client = {  entry: {    'client': './src/client/index.js'  },  target: 'web',  output: {    filename: '[name].js',    path: path.resolve(__dirname, 'dist/public')  },  module: moduleObj,  plugins: [    new HtmlWebPackPlugin({      template: 'src/client/index.html'    })  ]}

Прежде чем создать проект, давайте изменим наш HTML-файл и удалим ссылку на сценарий index.js, потому что плагин выше добавит это за нас. Это особенно полезно, когда есть один или несколько файлов с динамическими именами (например, когда файлы создаются с уникальной меткой времени для очистки кэша).

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>React Boilerplate</title></head><body>    <div id="root"></div></body></html>

Давайте перестроим проект:

npm run cleannpm installnpm run build

Убедитесь, что наши существующие тесты все еще выполняются:

npm test

Мы обновили шаблон для интеграции React и Webpack, создали дополнительные команды NPM, динамически ссылались на index.js в файле HTML и экспортировали его.

Настройка фермента

Прежде чем добавить тест React, нам нужно интегрировать Enzyme, позволяющий нам утверждать, манипулировать и проходить компоненты React.

Давайте начнем с установки Enzyme и enzyme-adapter-react-16, которые необходимы для подключения Enzyme к проекту, использующему react v16 и выше.

enzyme-adapter-react-16 имеет одноранговые зависимости от react, react-dom и react-test-renderer.

npm i --save-dev enzyme enzyme-adapter-react-16 react-test-renderer

Создайте файл src/enzyme.setup.js с таким содержимым:

import Enzyme from 'enzyme'import Adapter from 'enzyme-adapter-react-16'
Enzyme.configure({    adapter: new Adapter()})

Нам нужно настроить Jest для использования src/enzyme.setup.js в package.json, добавив такой раздел под корневой объект:

{..."jest": {    "setupTestFrameworkScriptFile": "./src/enzyme.setup.js"  }...}

Проверка компонентов React

Давайте проверим компонент программы и убедимся, что он отображает ожидаемый текст. Кроме того, мы сделаем снимок этого компонента, чтобы убедиться, что его структура не меняется при каждом тестовом запуске.

Нажмите здесь, чтобы узнать больше о тестировании снимков.

Создайте тестовый пример в src/client/app.test.js с таким содержимым:

import App from './app'import React from 'react'import {shallow} from 'enzyme'
describe('App', () => {  test('should match snapshot', () => {    const wrapper = shallow(&lt;App/>)
    expect(wrapper.find('div').text()).toBe('Welcome to React Boilerplate App')    expect(wrapper).toMatchSnapshot()  })})

Если мы запустим этот тест сейчас, он пройдет с предупреждением:

1*y44uqej9jGRMqLOm0lmRWw

Давайте исправим это, установив polyfill под названием raf:

npm i --saveDev raf

И изменив конфигурацию Jest в package.json на:

{..."jest": {    "setupTestFrameworkScriptFile": "./src/enzyme.setup.js",    "setupFiles": ["raf/polyfill"]  }...}

Теперь вы можете убедиться, что все наши тесты прошли:

npm test
0*IK1jRFuIfXrdkmez

После запуска теста React вы увидите новый файл по адресу src/client/snapshots/app.test.js.snap. Он содержит сериализированную структуру нашего компонента react. Его нужно проверить в Git, чтобы можно было использовать для сравнения с динамически созданным снимком во время тестового запуска.

Финальный забег

Давайте еще раз запустим веб-сервер и перейдем, чтобы убедиться, что все работает:

npm start 
0*oNefrz8voxKjaDNY

Надеюсь, эта статья дала вам понять, как упростить процесс запуска нового проекта с нуля с помощью Express |реагировать | Шутка | Webpack | Бабель. Было бы хорошей идеей создать собственный шаблон для многократного использования, чтобы вы понимали, что происходит под капотом, и имели преимущество при создании новых проектов.

Мы едва поцарапали поверхность, и есть много возможностей для усовершенствования, чтобы подготовить это стандартное производство.

Вот несколько вещей, которые вы можете попробовать:

Если вы хотите узнать больше об экосистеме React, я настоятельно рекомендую пройти полный курс для веб-разработчиков React от Эндрю Мида.

Если эта статья была полезной,??? и следите за мной в Twitter.

1*X-sqS5Sd479XE60HoKAn0g
Вам также может понравиться мое руководство на YouTube о жизненном цикле компонентов React

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *