Автор оригинала: FreeCodeCamp Community Member.
Ранее я написал статью под названием « Как покорить WebPack 4 и построить приложение для приложения Sweet React ». Вскоре после того, как я написал статью, Бабел наступил с серьезными перерывами, и многие из пакетов были устаревшими. Поэтому я решил написать новый учебник.
Я сосредоточусь на создании WebPack с R ECT который будет иметь .scss Поддержка вместе с расщепление кода
Цель написания этого снова проста: я хочу, чтобы все чувствовали себя комфортно. Поскольку настройка WebPack может быть действительно пугающим. Особенно для новых разработчиков там. Следуйте, а то, что казалось сложно, и, возможно, страшно, будет похоже на кусок пирога.
Прежде чем начать, вот Исходный код Отказ Я знаю, что это имеет множество вещей в нем. Я планирую использовать ту же кодовую базу, чтобы поговорить о WebPack, React, SCSS, замену горячей модуля, тестированием с шумом и ферментом, подцинковым кодом и добавление корпорации кода, как красивее в других статьях, поэтому я буду постоянно продолжать обновлять эта кодовая база. Я не буду разносываться на этот код базы – я обещаю.
Примечание: если вы хотите сделать PR для Репозиторий Вы более чем приветствуете:) Так что давайте начнем.
Для простоты, эта статья будет сосредоточиться только на;
- Настройка WebPack 4 с Babel 7 для реагирования
- Поддержка .scss
- Расщепление кода
- Окружающая среда разработки с HMR (замена горячего модуля)
- Конфигурация производства
- Разделение конфигурации вашего веб-папа в куски
- Постановка, демонстрация, демонстрация, тестирование и другие среды в коде
- Создание визуализатора в производственной сборке, чтобы проверить, какой кусок кода занял, сколько размера и каковы зависимости кусков. Супер полезный.
Предварительное условие
Вам необходимо установить узел для использования NPM (Manager Unode Package).
Первые вещи сначала, создайте папку под названием приложение
Затем откройте свой терминал и войдите в это приложение
Папка и тип:
npm init -y
Это создаст Package.json
Файл для вас.
Второе создайте папку под названием SRC
В вашем приложение
папка. Внутри Приложение/SRC
Создайте файл под названием index.js
и напишите следующий код.
console.warn('I am a Star Trek nerd'); console.log('So through out this tutorial, you will see a lot of Star Trek quotes'); console.log('Starting now'); console.log("Compassion: that's the one thing no machine ever had. Maybe it's the one thing that keeps men ahead of them. -Dr McCoy");
Вы можете написать что-нибудь выше, конечно. Я выбрал звездный путь.
Далее нам нужно установить пару зависимостей. Вы можете просто скопировать зависимости
& DevDependonds
от Package.json
ниже в свой собственный и сделай NPM установить :
{ "name": "react-boiler-plate", "version": "1.0.0", "description": "A react boiler plate", "main": "src/index.js", "author": "Adeel Imran", "license": "MIT", "scripts": { "start": "a script will come here" }, "dependencies": { "react": "^16.5.2", "react-dom": "^16.5.2" }, "devDependencies": { "@babel/core": "^7.0.0", "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-export-namespace-from": "^7.0.0", "@babel/plugin-proposal-throw-expressions": "^7.0.0", "@babel/plugin-syntax-dynamic-import": "^7.0.0", "@babel/polyfill": "^7.0.0-beta.51", "@babel/preset-env": "^7.0.0-beta.51", "@babel/preset-react": "^7.0.0-beta.51", "babel-loader": "^8.0.0-beta.0", "copy-webpack-plugin": "^4.5.1", "css-loader": "^0.28.11", "html-webpack-plugin": "^3.2.0", "mini-css-extract-plugin": "^0.4.3", "node-sass": "^4.8.3", "optimize-css-assets-webpack-plugin": "^4.0.0", "sass-loader": "^7.0.3", "style-loader": "^0.21.0", "uglifyjs-webpack-plugin": "^1.2.5", "webpack": "^4.12.0", "webpack-cli": "^3.0.8", "webpack-dev-server": "^3.1.4", "webpack-merge": "^4.1.3", "webpack-visualizer-plugin": "^0.1.11" } }
Да, я знаю, я знаю! Это много для создания Hello World React App. Но подожди, это все, что вам нужно. Даже если вы хотите создать приложение на уровне предприятия. (Может быть, одна или еще две вещи в зависимости от ваших требований, но это позвоночник для него.)
Итак, давайте поговорим о каждом из них, прежде чем мы погрузимся в глубоко в коде.
WebPack : Нам нужен WebPack для подключения нашего кода.
WebPack-Cli : Мы будем использовать некоторые особенности WebPack CLI, чтобы облегчить нашу жизнь во время написания некоторых сценариев.
WebPack-Dev-Server : Я создам сервер с помощью пакета WebPack-Dev-Server. Это предназначено только для использования в среде развития, а не для производства. Это значит при разработке и работе по моим коде, мне не нужен отдельный сервер, такой как Nodejs для настройки вручную.
WebPack-Merge : Разделить нашу конфигурацию в куски, больше на это позже
WebPack-визуализатор-плагин : Чтобы увидеть визуальное представление каждого из нашего размера расслоения – сколько места они принимают, и какие их зависимости.
Стиль-погрузчик : Это добавляет CSS к DOM путем впрыскивания A <скрипт
/> Тег в заголовке
Sass-Loader : Для поддержки SCSS
Узел-сасс : Зависимость от SASS-погрузчика
CSS-Loader : Чтобы преобразовать наши файлы .scss в .css
Мини-CSS-экстракт-плагин Этот плагин извлекает CSS в отдельные файлы. Он создает файл CSS на файл JS, который содержит CSS.
uglifyjs-webpack-plugin : Чтобы министерзировать код JavaScript для производства
Оптимизация-CSS-Assets-WebPack-Plugin Чтобы министерзировать CSS-код для производства
html-webpack-plugin : Это делает более, затем генерировать файл HTML, он поддерживает по запросу .css и .js файлы, автоматически добавляемые в ваши файлы HTML по требованию
Copy-WebPack-Plugin : Копирует файлы/папки в папку сборки.
Babel-Loader : Это загрузчик, который помогает Compile WebPack Compile .js
@ Babel/Core : Babel Core Compiler, это зависимость, которая позволяет использовать Babel-Loader
@ Babel/Preset-React Предустановка Babel для кода REACT
@ babel/preset-env : Babel Presetet, который позволяет вам использовать последний JavaScript
@ Babel/Pollefill : Бабел включает в себя Polyfill который включает в себя пользовательский Регенератор времени выполнения и Core-JS Отказ Это будет эмулировать полную среду ES2015 +. Это означает поддержку Async/await
Тип прохладного синтаксиса сахара.
Так что изменилось?
Хорошо! Бабел представил прерывание изменений (для большего добра, поверьте мне), который вы можете читать здесь: Удаление предустановки сцены Бабела Отказ То, что это означало, что раньше, если вы включили Babel-Preset-Stage-2, скажем, он будет включать все предложения, связанные с этапом 2, который будет блокировать ваш код. Но вам просто может понадобиться одна конкретная особенность этапа 2.
Таким образом, для того, чтобы бороться с этим, Бабел устарел все эти предустановленные плагины и отправляли отдельные особенности. Теперь вы должны настроить их вручную. Круто верно? Итак, давайте немного поговорим о тех отдельных пакетах и что они делают.
@ Babel/Plugin-предложение-класс – свойства : Покрывает ваш Класс
синтаксис в Функция
Для браузеров, которые не поддерживают Класс
синтаксис
@ Babel/Plugin-предложение-предложение-пространство имен – от Поддерживает синтаксис, как Импорт * как NS из '../path/to/module';
@ Babel/Plugin-предложение-бросок-выражения Новый синтаксис для броска исключений из в контексте выражения. Я люблю эту особенность: D
@ Babel/Plugin-синтаксис-динамический импорт Это то, что помогает с расщеплением кода. WebPack Ships с разделением кода по умолчанию (поскольку WebPack 1). Но когда вы хотите кодировать разделение в WebPack, пока вы используете Бабел, Тогда вам нужно использовать этот плагин.
Примечание. Для этого учебника вам не понадобится @ Babel/Plugin-предложение - Export-Namsessace - от
& @ Babel/Plugin-предложение-бросок-выражения
И теперь, когда вы знаете, зачем нам нужны то, что нам нужно – ничего особенного – вы будете чувствовать себя более уверенно, внедряя конфигурацию WebPack.
Давайте начнем с добавления .babelrc
Файл в корне из OUT приложение
папка:
{ "presets": [ "@babel/preset-env", "@babel/preset-react" ], "plugins": [ "@babel/plugin-syntax-dynamic-import", "@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-export-namespace-from", "@babel/plugin-proposal-throw-expressions" ] }
У нас есть 2 основных пресета предустановленные env
& Предустановленные реагирование
Отказ Остальные – наши плагины для добавления « крылья » на наш код.
А процитировать капитан Кирк из звездного хода (потому что почему нет):
В его обороне капитан Кирк поставил против подобных общих изменений, хана, боргу и так много опасных врагов. Все, что мы против, это красивая WebPack и Бабел Отказ Так что, возможно, мы разработчики предназначены для рая.
Итак, давайте установим наш веб-запас вверх.
Создать config
. Папка в вашем приложение
Отказ Если вы чувствуете себя потерянным, вы можете в любое время обратиться к GitHub R Эпоситор за это. Теперь внутри нашего config
. Папка Давайте создадим файл под названием WebPack.base.config.js
Причина, по которой я называю это база
Это потому, что он будет использоваться для нашего развития и для производства. Потому что зачем писать то же самое дважды? Опять же, если это не имеет большого смысла, просто нести со мной еще несколько минут.
В вашем config/webpack.base.config.js
Напишите это:
module.exports = { module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }, ] } }
Как только у вас есть на месте, запустите эту команду в корне приложение
каталог. (Я скажу вам, что эта команда немного позже с кодом, который мы написали выше, обещаю.)
$ node_modules/.bin/webpack-dev-server --mode development --config config/webpack.base.config.js --open --hot --history-api-fallback
Как только вы запустите эту команду, вы увидите этот экран:
Так что случилось здесь? Ну, когда мы запустили команду WebPack, это нашел наши index.js
Файл, который мы написали ранее в Приложение/SRC/index.js
– Но у него не было .html
Чтобы запустить его. Так что давайте создадим index.html
Файл в нашем Приложение/SRC
папка:
Tutorial
Давайте обновим наше WebPack.base.config.js
также:
var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: './index.html' }) ] }
Давайте снова запустим эту команду:
$ node_modules/.bin/webpack-dev-server --mode development --config config/webpack.base.config.js --open --hot --history-api-fallback
Ваш браузер откроется. Если вы используете Google Chrome, нажмите Ctrl + Shift + J
И ваша консоль браузера откроется. Вы увидите что-то вроде этого:
Итак, давайте поговорим, что здесь произошло. Наше WebPack.base.config.js
Имеет две основные вещи: модули и плагины. Модуль может иметь несколько правил, и каждое правило применяется к определенному типу файла. Не определенный тип файла, который мы хотим применить это правило, чтобы быть в Тест
Из этого правила:
rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }, ]
Здесь, говоря Тест:/\.js$./,
Мы говорим WebPack применить это правило только для .js
файлы. Другое дело Исключить
Что также принимает экспрессию Regex тому, что не включать. Это где мы говорим, чтобы не скомпилировать node_modules
Поскольку это будет компилировать все это, и установлены нагрузки зависимостей. Проверьте node_modules
сами. Последняя часть – использовать
Отказ
Теперь WebPack знает, где применить правило, используя Тест
и где не применять правило, используя Исключить
– Но как точно правило? Вот где использовать
вступает в игру: здесь мы указываем Погрузчик: «Babel-Loader»
Отказ Теперь, что Babel-Loader
Есть ли это ищет .babelrc
Файл, который мы написали ранее. И все предустановки и плагины, которые мы написали там. Требуется все они и относится к нашему .js
файлы.
Который приносит нас к следующему вопросу: как WebPack 4 Найти эти файлы? Хорошо WebPack 4 суда с нагрузками по умолчанию, которые уже настроены для вас. Два из них Вход
и Выход
Отказ
Вход
Точка по умолчанию это SRC
Каталог, который мы написали в нашем приложение
папка.
Выход
Точка – это то, где генерируется весь скомпилированный код, который будет создан Dist
Папка в OUT приложение
папка. (Теперь вы не увидите, потому что мы еще не скомпилировали наш код для производства.)
Далее мы поговорим о html-webpack-plugin
Цель этого плагина просто, как следует из названия. Он создает HTML-файлы для обслуживания всех ваших подключенных файлов. (Все это – .js, .css, .scsss, .img и т. Д.)
Давайте поговорим о том, когда мы проводим следующее:
$ node_modules/.bin/webpack-dev-server --mode development --config config/webpack.base.config.js --open --hot --history-api-fallback
Эта команда откроет порт http://localhost: 8080 или другой порт, если 8080
взят. (Я расскажу больше о том, что эта команда делает позже – пока давайте перейдем к).
index.html Это сгенерировано выглядит так:
Синяя часть: Синяя часть просто там, где я положил в мою мета теги и определил заголовок для приложения.
Желтая часть: Желтая часть выделена жесткая кодированная часть, которую мы написали в наших index.html файл. Именно здесь наше будущее приложение React будет проживать.
Красная часть: Часть, которую я подчеркнул красную, является самым интересной частью. Мы никогда не писали это в нашем файле index.html, так откуда он взялся?
WebPack очень умный. Это заняло этот файл в вашем index.js , в комплекте все это хорошо, и добавил его все аккуратно в файле под названием main.js Отказ Тогда он ввел его в нашу index.html файл. Очень круто!
Давайте добавим реакцию
Прохладная вещь, все наши зависимости уже установлены. И все уже настроено. Так что в вашем Приложение/SRC/index.js
Удалите весь код и замените его этим:
import React from 'react'; import ReactDOM from 'react-dom'; const App = () => { return (); }; ReactDOM.render(We are a most promising species, Mr. Spock, as predators go. Did you know that? I frequently have my doubts. I dont. Not any more. And maybe in a thousand years or so, we will be able to prove it.
- Captain Kirk
, document.getElementById('app'));
Теперь, если ваш терминал все еще работает WebPack-Dev-Server
Скрипт, просто проверьте браузер. Если нет, вот сценарий. Я не хочу, чтобы вы снова прокручились.
$ node_modules/.bin/webpack-dev-server --mode development --config config/webpack.base.config.js --open --hot --history-api-fallback
Это то, что вы увидите:
Теперь убедитесь, что вы не закрываете терминал и пошли в свой Приложение/SRC/index.js
и внести некоторые изменения в ваш <Приложение
/> Компонент. Попробуйте изменить предложение в абзаце. После изменившись, вернитесь к вашему браузеру, и контент уже там обновляется. Как это круто?: D.
Давайте добавим поддержку SCSS
Давайте начнем с обновления наших config/webpack.base.config.js
Добавляя другое правило для .scss
файлы
var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }, { test: /\.scss$/, use: [ 'style-loader', 'css-loader', 'sass-loader' ] }, ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: './index.html' }), ] }
Итак, использовать
Я использую здесь, принимает массив вместо объекта, как то, что я сделал для .js
файлы. Это потому, что нам нужно применить набор правил здесь:
use: [ 'style-loader','css-loader','sass-loader' ]
Итак, давайте прочитаем использовать
массив от Право налево
– Это важный. Что мы говорим WebPack – это взять на себя .scss
Файлы он находит и анализирует его для собственного понимания, используя Sass-Loader. Как только он преобразовал его в SASS, мы попросите WebPack преобразовать SASS в CSS. Для этого мы применяем CSS-Loader Отказ
По состоянию на этот момент мы преобразовали .scss в .css. Но для нас нет способа добавить преобразованные файлы в нашу .html
Отказ Для этого мы используем последний погрузчик под названием Стиль-погрузчик который берет все преобразованные .css и впрыскивает его в нашу index.html
файл.
Так что давайте добавим немного .scss
Чтобы проверить это. В вашем SRC/
Папка Добавить файл под названием mystyles.scss
Мой выглядит как один ниже:
body { background-color: skyblue; color: black; } .app { width: 450px; margin: 0 auto; padding-top: 50px; }
И мой SRC/index.js
Файл выглядит так:
import React from 'react'; import ReactDOM from 'react-dom'; import './myStyles.scss';; const App = () => { return (); }; ReactDOM.render(We are a most promising species, Mr. Spock, as predators go. Did you know that? I frequently have my doubts. I dont. Not any more. And maybe in a thousand years or so, we will be able to prove it.
- Captain Kirk
, document.getElementById('app'));
Перезапустите свой WebPack-Dev-Server
Запустив эту команду снова:
$ node_modules/.bin/webpack-dev-server --mode development --config config/webpack.base.config.js --open --hot --history-api-fallback
Ваш браузер откроется, это то, что он выглядит сейчас:
Теперь в вашем mystyles.scss
Файл, попробуйте сделать некоторые изменения. Как сделать Размер шрифта: белый;
Вернитесь в свой браузер. Это отражает эти изменения. Вам не нужно перезапустить свой сервер снова – только для .scss
Скомпилировать.
С этим большая часть нашей конфигурации разработки сделана. Наше приложение React Live, и имеет замену горячего модуля для .js
файлы, а также .scss
файлы
Итак, прежде чем мы будем двигаться дальше, давайте добавим WebPack-Dev-Server
Сценарий в нашем Package.json
Отказ В вашем Сценарии Раздел, добавьте следующий код:
"scripts": { "start": "webpack-dev-server --mode development --config config/webpack.base.config.js --open --hot --history-api-fallback --env.PLATFORM=local --env.VERSION=stag", "prebuild": "webpack --mode production --config config/webpack.prod.config.js --env.PLATFORM=production --env.VERSION=stag --progress", "build": "node server", },
Пока поговорим о Начать
команда. Я поговорю о Prebuild
и построить
Сценарии позже в разделе «Конфигурация производства».
Так что делает эта команда: NPM запустить начало
"start": "webpack-dev-server --mode development --config config/webpack.base.config.js --open --hot --history-api-fallback"
Давайте сломаемся. Когда мы бежим NPM запустить начало
Мы говорим ему, чтобы запустить пакет под названием WebPack-Dev-Server
Отказ Затем мы передаем это некоторые конфигурации.
WebPack-Dev-Server
Служит приложение WebPack и обновляет браузер по изменениям.- Развитие Mode
рассказываетWebPack
Чтобы скомпилировать код в режиме разработки. Это в основном, чтобы сделать время компиляции быстрее.- Config Config/webpack.base.config.js
Так что по умолчанию, если у вас естьwebpack.config.js
файл в вашем корнеприложение
Папка, вам не нужно предоставлять--config
Флаг к этому. Но так как я хочу явно добавить все свои конфигурации, связанные с WebPack вconfig
. Папка, я проезжаю в--config
Опция, которая говорит WebPack, где искать конфигурацию--Open
Команда открывает браузер, когда WebPack выполняется с его компиляцией.--hot
Флаг рассказывает WebPack активно наблюдать за изменениями кода вSRC
папка. Если какие-либо изменения произойдут, он перезагружает браузер.--history-API-Foxback
Эта опция позволяет История API Foxback Поддержка вWebPack-Dev-Server
, эффективно спрашивая сервер в отступление кindex.html
В случае, если запрошенный ресурс не найден.--env.platform
&--env.version
Пользовательские флаги, которые я пропускаю в моей конфигурации (больше на это позже).
Теперь, когда мы закончили, давайте переехать на наш Производство конфигурации.
Но прежде чем мы сделаем это, давайте поговорим о WebPack-Merge
Отказ Теперь это настоящий победитель. Это берет в одну конфигурацию и другую и объединяет их оба вместе, чтобы дать нам один. Как работает, вам нужно обернуть вашу конфигурацию с помощью слияние
как тот ниже. Давайте начнем, сделав наши WebPack.base.config.js
Файл в WebPack-Merge
Используемый кусок:
const webpack = require('webpack'); const merge = require("webpack-merge"); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = env => { const { PLATFORM, VERSION } = env; return merge([ { module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }, { test: /\.scss$/, use: [ 'style-loader', 'css-loader', 'sass-loader' ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: './index.html' }), new webpack.DefinePlugin({ 'process.env.VERSION': JSON.stringify(env.VERSION), 'process.env.PLATFORM': JSON.stringify(env.PLATFORM) }), ], } ]) };
Раньше, где мы где экспортируем объект
Теперь мы экспортируем Функция
который возвращает слияние
и принимает в конфигурацию.
Давайте сломаем это как к чему это делает. Первое, о чем мы говорим, это это:
module.exports = function(env) {}
Новые флаги добавлены в наше Начать
команда - -
передаются на наши конфигурации WebPack, которые мы можем получить доступ к env
PARAL в module.exports (env) {}
Отказ Так что мы можем сделать с этим?
- Мы можем настроить условное утверждение в нашем конфигурации WebPack, что если определенное условие выполняется, то сделайте это или что (больше на это позже). В основном мы изменим нашу конфигурацию на компиляцию времени, чтобы удовлетворить любезную среду, – это прогона – производство или развитие.
- Другая вещь, которую мы можем сделать здесь, пропускают их в нашем коде. Так что я имею в виду под пропуском в нашем коде? Один новый плагин, который я добавил для этого, называется Новый WebPack.defineplugin Отказ (Также именно поэтому мне пришлось включить WebPack в верхней части
WebPack.base.config.js
.) Что это делает: «DefinePlugin
позволяет создавать глобальные константы, которые могут быть Настроен в компиляционное время. «Вы можете прочитать больше об этом здесь Отказ
Далее мы возвращаем конфигурацию внутри функции, как это:
return merge({ // our webpack configuration here });
Ну не многое изменилось здесь. Все, что мы сделали, была обернуть нашу конфигурацию в слияние
Отказ Это дает нам возможность слияние
вся эта конфигурация в другой, которую мы создадим.
Добавлено одно добавлено новый плагин Офиниругин
о которых я уже говорил.
Прежде чем перейти к Производство
Настройки, давайте проверим, работают ли наши базовые конфигурации.
В вашем SRC/index.js
Файл добавить это где-то:
console.log('process.env.VERSION', process.env.VERSION);
console.log('process.env.PLATFORM', process.env.PLATFORM);
console.log('process.env.NODE_ENV', process.env.NODE_ENV);
В вашем терминале работает NPM запустить начало
Отказ Подождите, пока ваш браузер загрузится. Откройте свой терминал.
Первые два, которые вы видите в консоли, является результатом нас, передавая --env
Флаги от нашего сценария на наш конфигурацию WebPack и установка его с дефином. Третий с - Mode
Флаг, который мы проходим в нашем скрипте. Если в режиме разработка или производство, то это настроено в нашем process.env.node_env
флаг.
Теперь, когда это очистилось, давайте перейдем дальше.
В вашем config
. Папка, создайте новый файл под названием webpack.prod.config.js
и добавьте следующий код в него, как показано ниже:
var merge = require('webpack-merge'); // Plugins var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); var UglifyJsPlugin = require('uglifyjs-webpack-plugin'); var Visualizer = require('webpack-visualizer-plugin'); var baseConfig = require('./webpack.base.config'); const prodConfiguration = env => { return merge([ { optimization: { runtimeChunk: 'single', splitChunks: { cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all' } } }, minimizer: [new UglifyJsPlugin()], }, plugins: [ new OptimizeCssAssetsPlugin(), new Visualizer({ filename: './statistics.html' }) ], }, ]); } module.exports = env => { return merge(baseConfig(env), prodConfiguration(env)); }
Давайте начнем снизу с module.exports =>
{}
Мы объединяем две конфигурации: один – наше BaseConfig
а другой – Продконфигурация
Отказ --env
Флаги, которые мы проходим в наших сценариях, передаются как объект в env =>
{} Пармы в нашей функции. Затем мы передаем их как T Он BaseCon
Рис & prodcon
инжир.
Это в основном список оптимизаций, которые мы хотим выполнить, когда наш код поднимется на производство.
Оптимизация. МИНИМИЗЕР
берет в New Uglifyjsplugin
Отказ Что это делает ULLIFY и министерству наших файлов .js.
Оптимизация .splitchunks
на самом деле принимает весь ваш общий код и создает vendor.bundle.js
файл. Это не собирается сделать один сейчас. Но, поскольку наша кодовая база растет, у нас есть несколько маршрутов, и есть разные модули, используемые как Дата FNS
момент
Лоташ
Материал-ui
И т.д. Это займет весь общий код от всего приложения и сделать общий файл под названием vendor.bundle.js
Отказ Таким образом, повторяющийся код не используется снова и снова. (Я против этого подхода, но для образовательных целей я описал это здесь.)
Сдвиньте вперед, я комментирую Оптимизация .splitchunks
Но это будет существовать там в репозитории кода, если вы хотите использовать его. Вы просто должны вотвориться в этом разделе. Я предпочитаю разделить свой код на основе маршрутов. Имея общий код, разбитый в отдельный модуль, означает, что весь ваш общий код будет загружен первым. Это может быть огромным, и, как следствие, впервые взаимодействие пользователя займет больше времени (потому что теперь все эти зависимости загружаются, что может не должно быть на соответствующей странице, что пользователь виден/просмотр).
Далее у нас есть пара плагинов. Один из них случается, чтобы быть Новый OptimizecsSassetsPlugin ()
Отказ Все это делает, это принять все наши сгенерированные .css
и министерзировать/оптимизировать его. Это сейчас не работает, потому что мы используем Стиль-погрузчик
и стиль погрузчика напрямую впрыскивает сгенерированный .css
в домо.
Во-первых, нам нужно сообщить WebPack для извлечения всех сгенерированных .css
в отдельный файл, а затем применяется оптимизация, добавленные этим плагином. (Мы сделаем это немного позже.)
Другой плагин, добавленный здесь, называется Новый визуализатор ({имя файла: './statistics.html'})
. Это плагин потрясающий: он генерирует Статистика .html
Файл в Dist/
Папка для вас. Откройте файл, и вы увидите графику, подобную ниже.
Прямо сейчас у нас есть только один модуль, называемый main.js
Отказ Но со временем, как мы добавляем больше модулей, и у меня добавляли расщепление кода. Больше модулей начнут появиться здесь, и мы можем увидеть, какие модули принимают какой размер. Это может быть действительно полезно, когда вы пытаетесь уменьшить размер вашего приложения.
Возвращаться в Optimizecssassetsplugin ()
Отказ Чтобы оптимизировать генерируемые .CS, нам нужно переместить это в отдельный модуль. Для этого я собираюсь использовать Мини-CSS-экстракт-плагин
Это потребует от нас вносить изменения в оба наших файла WebPack, .base
и .Проход
файлы.
// webpack.base.config.js const webpack = require('webpack'); const merge = require("webpack-merge"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = env => { const { PLATFORM, VERSION } = env; return merge([ { module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }, { test: /\.scss$/, use: [ PLATFORM === 'production' ? MiniCssExtractPlugin.loader : 'style-loader', 'css-loader', 'sass-loader' ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: './index.html' }), new webpack.DefinePlugin({ 'process.env.VERSION': JSON.stringify(env.VERSION), 'process.env.PLATFORM': JSON.stringify(env.PLATFORM) }), ], } ]) };
// webpack.prod.config.js /* eslint-disable */ const merge = require('webpack-merge'); // Plugins const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); const Visualizer = require('webpack-visualizer-plugin'); // Configs const baseConfig = require('./webpack.base.config'); const prodConfiguration = env => { return merge([ { optimization: { // runtimeChunk: 'single', // splitChunks: { // cacheGroups: { // vendor: { // test: /[\\/]node_modules[\\/]/, // name: 'vendors', // chunks: 'all' // } // } // }, minimizer: [new UglifyJsPlugin()], }, plugins: [ new MiniCssExtractPlugin(), new OptimizeCssAssetsPlugin(), new Visualizer({ filename: './statistics.html' }) ], }, ]); } module.exports = env => { return merge(baseConfig(env), prodConfiguration(env)); }
Давайте поговорим о изменениях, которые я сделал в WebPack.base.config.js
.Only один модуль был добавлен под названием const (mini-css-экстракт-плагин ");
Отказ Тогда в нашем .scss
Правила, которые мы проверили, если Платформа
Флаг прошла имеет значение Производство
Отказ Если это так, мы добавляем Minicssextractplugin.loader
и в противном случае мы добавляем Стиль-погрузчик
Отказ
Стиль-погрузчик
используется для активного просмотра и изменения наших компиляций .css
В режиме развития, пока Minicssextractplugin.loader
Используется, когда нам нужно извлечь, что генерируемые CSS в отдельный модуль. Это только для производства.
В другом файле webpack.prod.config.js
У нас есть эти два плагина, добавленные:
new MiniCssExtractPlugin(), new OptimizeCssAssetsPlugin(),
Первый извлекит это в отдельный модуль, называемый main.csss
а другой будет министвовать/усовершенствовать сгенерированные CSS.
Сделав это, мы сделали почти 90%. Если вы остались далеко, слава вам.
Прежде чем мы продолжим, вот что капитан Кирк должен сказать
Давайте добавим дополнительную функциональность, в наш код. Теперь есть два способа добавления файлов в свой код. Один использует другой погрузчик под названием файловой погрузчик
Что поможет вам добавить файлы любого типа в ваши файлы .js, как мы сделали с файлами .scsss.
Я хочу поговорить о другом подходе здесь, потому что я думаю, что активы, такие как шрифты, изображения и другие, должны загружаться параллельно, а не в ваших файлах .js. Это помогает предоставить лучший опыт для пользователя. Таким образом, чтобы это предложить мы загрузим наши изображения статически.
Для этого мы будем использовать плагин под названием Copy-WebPack-Plugin
Отказ Лучшее обо всем этом, у вас уже есть это установлено. В вашем WebPack.base.config.js
Добавьте еще один плагин, как показано ниже:
const CopyWebpackPlugin = require('copy-webpack-plugin'); // Add this in top module.exports = env => { return merge([ { module: {}, plugins: [ new CopyWebpackPlugin([ { from: 'src/static' } ]), // Add this in the plugins section ], } ]) };
Copy-WebPack-Plugin
принимает аргумент под названием от
Отказ Это говорит плагину, где найти статические файлы, а затем скопировать их в Dist
папка. Здесь я говорю это искать папку под названием SRC/статический
и скопируйте все его содержание в Dist/
папка.
Как только вы добавили это и настроить, все, что вам нужно сделать, в вашем Приложение/SRC
Папка, создайте новую папку под названием Статический
Отказ В этой папке создайте еще одну папку под названием Изображения
Таким образом, ваша папка будет иметь такое каталог: Приложение/SRC/статические/изображения
Я собираюсь поставить изображение здесь, называемое header.jpg
, но вы можете назвать это, что вам нравится. Это изображение, которое я использую: https://unsplash.com/photos/idi6i490p7i (Фото Felix Mittermeier на Unsplash ).
Теперь, чтобы это работать, вам нужно запустить NPM запустить Prebuild
Команда (я расскажу больше о NPM Run Prebuild
& NPM Run Build
позже, когда мы настроим наш Nodejs Server с Expressjs), потому что нам нужно наши Статический
файлы будут скопированы. NPM запустить начало
Команда не будет скопировать это на Dist/
папка, потому что она не компилируйте код для Dist/
папка.
Как только вы запустите NPM запустить Prebuild
Команда это то, что вы увидите:
Так как мы можем получить доступ к этому файлу в нашем коде?
Я собираюсь внести некоторые изменения в моем index.js
Файл вместе с mystyles.scss
. Вы можете следовать, а также мы просто добавляем /> вместе с
некоторые
.scss
import React from 'react'; import ReactDOM from 'react-dom'; import './myStyles.scss'; const App = () => { return (); }; ReactDOM.render(![]()
We are a most promising species, Mr. Spock, as predators go. Did you know that? I frequently have my doubts. I dont. Not any more. And maybe in a thousand years or so, we will be able to prove it.
- Captain Kirk
, document.getElementById('app'));
body { background-color: skyblue; color: black; } .app { width: 450px; margin: 0 auto; padding-top: 50px; & .app-header { height: 250px; width: inherit; object-fit: cover; } }
Единственное, что нужно отметить здесь в index.js
Файл, где я добавляю изображение:
Главное – путь, который мы даем в SRC
Отказ
Как только вы добавите это, давайте проверим, как это выглядит в браузере. Иди и беги NPM запустить начало
команда.
Давайте повторимся, что мы достигли до сих пор
- Настройка WebPack 4 с Babel 7 для реагирования
- Поддержка .scss
- Окружающая среда с HMR [для как .js и .scsss]
- Конфигурация производства
- Разделение конфигурации вашего веб-папа в куски
- Создание визуализатора в создании производства, чтобы проверить, какой кусок кода на том, насколько велики и какие зависимости кусков. Супер полезный.
- Поддержка статических файлов
Вещи, которые нам все еще нужно выполнить
- Добавить поддержку для
Async/await
В нашем коде - Создайте Nodejs Server с использованием Expressjs для нашей производственной сборки
- Расщепление кода
Давайте начнем с Async/await
первый. Для этого я собираюсь сделать умный <Приложение
/> Компонент. Внутри этого компонента я собираюсь назвать API, который поможет мне информацию о капитане Кирке, потому что он потрясающий. Так что в нашем index.js
Добавьте следующий код:
import React from 'react'; import ReactDOM from 'react-dom'; import './myStyles.scss'; class App extends React.Component { state = { CaptainKirkBio: {}, }; componentDidMount() { this.onGetKirkBio(); } onGetKirkBio = async () => { try { const URL = 'http://stapi.co/api/v1/rest/character/search'; const result = await fetch(URL, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: { title: 'James T. Kirk', name: 'James T. Kirk', }, }); const resultJSON = await result.json(); const character = resultJSON.characters[0]; this.setState({ CaptainKirkBio: character }); } catch (error) { console.log('error', error); } }; render() { const { CaptainKirkBio } = this.state; return (); } } ReactDOM.render(![]()
We are a most promising species, Mr. Spock, as predators go. Did you know that? I frequently have my doubts. I dont. Not any more. And maybe in a thousand years or so, we will be able to prove it.
- Captain Kirk
{Object.values(CaptainKirkBio).length === 0 ? ( Loading User Information
) : ({JSON.stringify(CaptainKirkBio)}
)}, document.getElementById('app'));
Все, что я делаю, здесь звонит API, используя попробуйте/поймать
Async/await
и получать информацию о капитане Кирк. Просто правильно? Это должно работать. Давайте устреммся в браузере.
Запустите команду:
npm run start
Если вы ударили Ctrl + Shift + J
Ваша консоль откроется, и вы увидите ошибку, называемую там Регенераторрунтиит Отказ Так что такое эта ошибка и как мы избавимся от этого?
Эта ошибка брошена, когда браузер не поддерживает Async/await
или Генераторы
в этом отношении.
Да! Вот что Генри Чжу Удивительный чувак за Вавилом должен сказать об этом:
Теперь вы знаете, почему это существует, так что давайте решим это. Нам нужно внести некоторые изменения в нашу WebPack.base.config.js
:
const path = require('path'); const webpack = require('webpack'); const merge = require("webpack-merge"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const APP_DIR = path.resolve(__dirname, '../src'); // <===== new stuff added here module.exports = env => { const { PLATFORM, VERSION } = env; return merge([ { entry: ['@babel/polyfill', APP_DIR], // <===== new stuff added here module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }, { test: /\.scss$/, use: [ PLATFORM === 'production' ? MiniCssExtractPlugin.loader : 'style-loader', 'css-loader', 'sass-loader' ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: './index.html' }), new webpack.DefinePlugin({ 'process.env.VERSION': JSON.stringify(env.VERSION), 'process.env.PLATFORM': JSON.stringify(env.PLATFORM) }), new CopyWebpackPlugin([ { from: 'src/static' } ]), ], } ]) };
Проверьте Линия № 8
и Линия № 14
в фрагменте добавлено выше.
По умолчанию WebPack 4 принимает точку входа SRC/
Отказ Но если мы хотим иметь несколько точек входа, мы можем настроить Вход
точка также. В моей точке входа я просто расскажу об этом две вещи:
entry: ['@babel/polyfill', APP_DIR],
@ Babel/Polyfill
Babel плагин, который включает в себя Polyfill который включает в себя пользовательский Регенератор времени выполнения и Core-JS ОтказApp_dir
Путь к нашемуSRC/
папка, которую я написал наЛиния № 8
const.resolve (__ dirname, '../SRC');
Все эта строка делает, указывает на путьSRC/
папка в нашемприложение/
папка.
Итак, Вход
Просто берет в «очки» относительно того, что компилировать.
Теперь, когда это очищено, давайте запустим NPM запустить начало
команда снова.
Все идет нормально!
Теперь, когда все настроено, давайте создадим сервер Nodejs с помощью ExpressJS.
Первое, что мы должны установить, выражается, так что в вашем терминале написать это:
npm install express --save
Или если вы используете пряжа (Как я делаю):
yarn add express
Далее в корне приложение
Папка создает новую папку под названием Сервер
Отказ Внутри папки Создайте index.js
файл, как показано ниже:
const express = require('express'); const path = require('path'); const http = require('http'); const app = express(); // Point static path to dist app.use('/', express.static(path.join(__dirname, '..', 'dist'))); app.use('/dist', express.static(path.join(__dirname, '..', 'dist'))); const routes = require('./routes'); app.use('/', routes); /** Get port from environment and store in Express. */ const port = process.env.PORT || '3000'; app.set('port', port); /** Create HTTP server. */ const server = http.createServer(app); /** Listen on provided port, on all network interfaces. */ server.listen(port, () => console.log(`Server Running on port ${port}`));
Давайте обсудим этот код, прежде чем мы продолжим дальше.
Мы создали наше приложение с Express ()
а затем создать статическую публичную папку под названием Dist Отказ Это одна и та же папка, созданная WebPack, когда мы запустим нашу команду производства.
Мы включаем наши маршруты Файл – мы создадим это через секунду – и установить маршруты Файл к /
каталог.
Далее мы настроили порт. Если ни один не предоставляется через CLI Node, мы используем порт 3000
Отказ После этого мы создаем HTTP-сервер и прослушайте этот сервер через порт. В самом последнем, мы консоль к нашему терминалу, что мы запуская сервер на этом определенном порту.
Давайте создадим наш последний файл под названием Маршруты/index.js :
const path = require('path'); const router = require('express').Router(); router.get('*', (req, res) => { const route = path.join(__dirname, '..', '..', 'dist', 'index.html'); res.sendFile(route); }); module.exports = router;
Здесь мы проверяем, что все, что наступает пользователь, путь перенаправляет пользователь на dist/index.html где живет наше наложение реагирования.
И это все. Мы сделали.
Теперь иди в свой терминал и введите:
npm run build
Это займет момент. Это покажет вам прогресс, пока он компилирует. После этого он придерживается сообщения, которое оно Прослушивание порта 3000
Если порт не предоставляется.
Теперь перейдите в свой браузер http: localhost: 3000/
И ваша заявка жива.
Так как мы на этом, давайте подробно поговорим о том, что NPM запустить Prebuild
и NPM запустить сборку
делать.
В основном, если мы пишем слово до
Для скрипта в этом случае Prebuild
каждый раз, когда мы управляем нашей командой NPM запустить сборку
Сначала будет выполняться NPM запустить Prebuild
а затем запустить скрипт NPM запустить сборку
Отказ
Все NPM запустить сборку
работает ?| Узел сервер/index.js (Вам не нужно писать/index.js) в команде. Nodejs достаточно умны, чтобы знать, что он должен запустить
index.js внутри
Сервер папка.
Это подводит также наши настройки приложения Nodejs.
Одна последняя тема, чтобы пойти. Я дам очень короткий обзор по разделению кода, и как вы можете достичь этого.
Расщепление кода
В начале этого учебника мы добавили @ Babel/Plugin-синтаксис-динамический импорт
Это дает нам возможность лениво загружать наш код внутри нашего приложения.
Внутри моих SRC/
Папка, я собираюсь создать компонент под названием Foo.js
Что выглядит что-то вроде этого.
import React from 'react'; export default () => ();I am Foo! Pleasure to meet you.
Ничего особенного в отношении foo здесь.
Особые вещи начинаются, когда мы включаем этот компонент в нашем SRC/index.js
файл.
Вы можете думать что-то вроде этого:
import Foo from './Foo'; class App extends React.Component { state = {}; render() { return () } }I am App
Ну нет, для динамического импорта мы должны сделать это:
import React from 'react'; import ReactDOM from 'react-dom'; import './myStyles.scss'; class App extends React.Component { state = { CaptainKirkBio: {}, Foo: null, // Foo is out component }; componentDidMount() { this.onGetKirkBio(); import(/* webpackChunkName: 'Foo' */ './Foo').then(Foo => { this.setState({ Foo: Foo.default }); }); } onGetKirkBio = async () => { try { const result = await fetch('http://stapi.co/api/v1/rest/character/search', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: { title: 'James T. Kirk', name: 'James T. Kirk', }, }); const resultJSON = await result.json(); const character = resultJSON.characters[0]; this.setState({ CaptainKirkBio: character }); } catch (error) { console.log('error', error); } }; render() { const { CaptainKirkBio, Foo } = this.state; return (); } } ReactDOM.render(![]()
We are a most promising species, Mr. Spock, as predators go. Did you know that? I frequently have my doubts. I dont. Not any more. And maybe in a thousand years or so will be able to prove it.
- Captain Kirk
{Object.values(CaptainKirkBio).length === 0 ? ( {Foo ?Loading User Information
) : ({JSON.stringify(CaptainKirkBio)}
)}: Foo is loading
}, document.getElementById('app'));
Вещи, чтобы отметить здесь в линия 9
Строка 14, 15, 16
линия 40
линия 57
:
Линия 9
: Мы устанавливаемFoo
какзначение NULL
Строка 14, 15, 16
: Как только наше компонент монтируется, мы импортируем нашу/> Компонент
Давайте поговорим больше об этом:
import(/* webpackChunkName: 'Foo' */ './Foo').then(Foo => { this.setState({Foo: Foo.default }); })
Давайте сломаемся еще больше.
Импорт (/* WebPackChunkName: 'foo' */'./foo')
: Это имеет 2 части к нему, мы устанавливаем имя лопатки под названием Foo
в /* WebPackChunkName: 'foo' */
Отказ Вы можете назвать это все, что вы хотите. Что это делает, когда ваше приложение загружает ./Foo
Файл, он будет загружен именем Foo
Как определено в /* WebPackChunkName: 'foo' */
Эта функция называется Magic Comments в WebPack, потому что она позволяет назвать файл при загрузке его в свой код.
Другая часть Импорт (/* WebPackChunkName: 'foo' */'./foo')
это './Foo'
в самом конце утверждения. Это путь откуда мы включаем наш файл.
Это возвращает нам обещание .then (foo =>
{}). С нашего экспорта из <
Foo/ > Был экспорт
T по умолчанию, когда мы устанавливаем наши sta
Te Foo мы Это к этому. SettState ({foo: foo.de
неисправность}); Для того, чтобы присваивать компонент FO для переменной состояния FOO.
линия 57
: Это где мы показываем наш LT; FOO/> Компонент мы показываем это.
И что, мои друзья, это кодовое расщепление.
Я действительно надеюсь, что это было полезно для вас. Если бы это было, пожалуйста, дайте мне знать, чтобы я мог написать больше, как это так. Вы всегда можете добраться до меня на Twitter И снова, если вы соблюдате до конца, я действительно горжусь вами, ребята. Вы, ребята, качаете это!
Эта статья была первоначально опубликована в публикации FreeCodecamp ранее на среднем. Читайте здесь