Упаковка файлов и Webpack

Последнее обновление: 29.10.2022

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

Кроме того, в прошлой теме (да и в ряде других предыдущих тем) мы сталкиваемся с еще одной проблемой - компиляция кода JSX в обычный Javascript на лету занимает некоторое время. Соответственно лучше, если бы у нас был сразу скомпилирован код Javascript до загрузки веб-страницы.

Обе эти проблемы нам поможет решить Webpack. Webpack представляет популярный упаковщик модулей, который позволяет автоматизировать создание из нескольких файлов один.

Для работы с Webpack создадим новый проект. Для этого определим новый каталог webpackapp. Прежде всего сразу установим все необходимые пакеты, которые будут использоваться в проекте. Для этого определим добавим в проект следующий файл package.json:

{
  "name": "searchapp",
  "description": "A React.js project using Webpack",
  "version": "1.0.0",
  "author": "metanit.com",
  "scripts": {
    "dev": "webpack serve --mode=development",
    "build": "webpack"
  },
  "dependencies": {
    "react": "18.0.0",
    "react-dom": "18.0.0"
  },
  "devDependencies": {
    "@babel/cli": "7.17.0",
    "@babel/core": "7.17.0",
    "@babel/preset-react": "7.16.0",
    "babel-loader": "8.2.0",
    "webpack": "5.70.0",
    "webpack-cli": "4.10.0",
    "webpack-dev-server": "4.11.0"
  }
}

Среди зависимостей в секции "dependencies" здесь определены две библиотеки - react и react-dom. Эти модули содержат функционал библиотеки React.js, который будет необходим для работы приложения.

В секции "devDependencies" определены те модули, которые потребуются только при разработке приложения.

Так как для компиляции из jsx в js необходим компилятор babel, то вначале определяются соотетстующие модули. Модуль "@babel/core" - это основной модуль компилятора. Для загрузки файлов в webpack необходимы загрузчики, которые собственно и определяют правила загрузки и обработки файлов. Для загрузки файлов добавляется модуль "babel-loader". И этот модуль будет использовать другой модуль - "@babel/preset-react", который необходим для работы в связке с React.js и файлами jsx.

Так как для сборки мы будем использовать Webpack, то в конце добавляется модуль "webpack". Чтобы упростить разработку, добавлен еще один модуль - "webpack-dev-server", который позволяет динамически запускать проект.

Кроме того, в секции scripts определены две команды: dev и build. Команда dev предназначена для нужд разработки и позволяет на лету сгенерировать файл сборки и запустить проект. Команда build позволяет сгенерировать файл сборки, и затем этот файл может использоваться в production.

Далее добавим в проект новую веб-страницу index.html:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title>Webpack в React</title>
</head>
<body>
	<div id="app"></div>
	<script src="public/bundle.js"></script>
</body>
</html>

Здесь, предполагается, что вся функциональность будет находиться в файле по пути "public/bundle.js". Пока этого файла нет, но далее мы его создадим с помощью webpack.

Затем определим в каталоге проекта новую папку app, в этой папке будут находиться собственно файлы приложения.

Для компонентов в папке app создадим подкаталог components. Далее в подкаталог components добавим новый файл header.jsx:

const React = require("react");
 
function Header(props){ return <h2>{props.text}</h2>;}
 
module.exports = Header;

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

Поскольку для создания компонентов надо подключить основной модуль react:

const React = require("react");

Для подключения других модулей здесь применяется функция require().

Аналогичный компонент в виде класса:

const React = require("react");
 
class Header extends React.Component {
    constructor(props){
        super(props);
    }
    render() {
        return <h2>{this.props.text}</h2>;
    }
}
 
module.exports = Header;

И также в каталог app/components добавим новый компонент article.jsx, который просто будет выводить неокторый текст:

const React = require("react");
 
function Article(props){return <div>{props.content}</div>;}
 
module.exports = Article;

Данный компонент по аналогии получает извне некоторые данные и применяет их при рендеринге.

Аналогичный компонент в виде класса:

const React = require("react");
 
class Article extends React.Component{

    constructor(props){
        super(props);
    } 
    render() {
        return <div>{this.props.content}</div>;
    }
}
 
module.exports = Article;

Далее в папке app определим главный файл проекта app.jsx - основной файл приложения:

const ReactDOM = require("react-dom/client");
const React = require("react");
const Header = require("./components/header.jsx");
const Article = require("./components/article.jsx");
 
const header = "Рассказ";
const article = "После одного из заседаний N-ского мирового съезда судьи собрались в совещательной комнате, чтобы снять свои мундиры, минутку отдохнуть и ехать домой обедать.";
 
ReactDOM.createRoot(
    document.getElementById("app")
)
.render(
    <div>
        <Header text={header} />
        <Article content={article} />
    </div>
);

Это собственно файл с кодом React, который будет загружать компоненты на веб-страницу.

Вначале импортируем оба компонента:

const Header = require("./components/header.jsx");
const Article = require("./components/article.jsx");

Затем в функции render() производим рендеринг обоих компонентов, передавая им некоторые данные.

Для работы с webpack добавим в корневую папку проекта новый файл webpack.config.js:

const path = require("path");
  
module.exports = {
    mode: "development",
    entry: "./app/app.jsx", // входная точка - исходный файл
    output:{
        path: path.resolve(__dirname, "./public"),     // путь к каталогу выходных файлов - папка public
        publicPath: "/public/",
        filename: "bundle.js"       // название создаваемого файла
    },
    devServer: {
     historyApiFallback: true,
     static: {
      directory: path.join(__dirname, "/"),
    },
     port: 8081,
     open: true
   },
    module:{
        rules:[   //загрузчик для jsx
            {
                test: /\.jsx?$/, // определяем тип файлов
                exclude: /(node_modules)/,  // исключаем из обработки папку node_modules
                loader: "babel-loader",   // определяем загрузчик
                options:{
                    presets:[ "@babel/preset-react"]    // используемые плагины
                }
            }
        ]
    }
}

Первой в конфигурации идет опция mode. Ее значение "development" указывает, что приложение находится в состоянии разработки.

В секции entry: "./app/app.jsx" указывается главный файл приложения.

Секция output определяет конфигурацию для выходного файла - его папку и имя - public/bundle.js. Это тот файл, который будет подключаться на веб-страницу.

Секция devServer определяют конфигурацию запускаемого веб-сервера, на котором будет развертываться тестируемое приложение. В частности, значение historyApiFallback: true указывает, что будет использоваться HTML5 History API. Это может быть полезно, если приложение использует маршрутизацию.

Опция static устанавает настройки для статических файлов. В данном случае эта секция нам нужна для установки каталога, где располагается файл index.html. В частности, параметр directory указывает, где этот файл находится - в данном случае это корневой каталог проекта, поэтому применяется путь "/".

Опция port указывает, что веб-сервер будет запускаться на порту 8081, то есть к приложению мы сможем обратиться по адресу http://localhost:8081. А опция open: true указывает, что при запуске веб-сервера приложение будет автоматически открываться в веб-браузере.

И секция module устанавливает набор загрузчиков, которые будут применяться для загрузки модулей. Здесь определен только один загрузчик - babel-loader. Он будет применяться к файлам с расширением jsx и для обработки будет использовать плагины env и react.

В итоге структура проекта будет выглядеть следующим образом:

Webpack и Babel в React

В командной строке/терминале перейдем к папке проекта и установим все этим пакеты с помощью команды

npm install
Установка webpack в проект на React

Затем выполним команду

npm run dev

То есть в данном случае выполняем команду, которая определена в секции scripts и которая запускает приложение:

webpack в Node.js

В итоге приложение автоматически будет запускаться в браузере:

Webpack 5 и React.js

С этим приложением мы также можем работать, как и предыдущих темах. Однако чтобы сгенерировать файл приложени - сборку, которая будет содержать код всех файлов, нам надо выполнить другую команду, которая опредена в секции scripts в файле package.json:

npm run build

Эта команда по файлу app/app.jsx создаст в проекте папку public, а в ней - новый файл bundle.js. Это именно тот файл, который будет подключаться на веб-страницу.

То есть будет сгенерирован обычный файл с кодом javascript, который поддерживается всеми браузерами. И нам не понадобится ни компилятор Babel, ни какие-то другие файлы. Мы можем просто кинуть веб-страницу в веб-браузер, и приложение также будет работать.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850