Encore: Налаштування вашого проекту
Дата оновлення перекладу 2022-12-15
Encore: Налаштування вашого проекту
Після установки Encore, ваш застосунок вже має
по одному файлу CSS і JS, організованих в каталозі assets/
:
assets/app.js
assets/bootstrap.js
assets/controllers.json
assets/styles/app.css
assets/controllers/hello_controller.js
З Encore вам необхідно думати про ваш файл app.js
, як про окремий застосунок
JavaScript: він буде вимагати всі необхідні йому залежності (наприклад, jQuery
або React), включно з будь-яким CSS. Ваш файл app.js
вже робить це з твердженням
JavaScript import
:
1 2 3 4
// assets/app.js
// ...
import './styles/app.css';
Робота Encore (через Webpack) проста: читати та слідувати усім твердженням require()
і створювати один фінальний app.js
(та app.css
), який містить все необхідне вашому
додатку. Encore може робити набагато більше: мінімізувати файли, попередьно обробляти Sass/LESS,
підтримувати React, Vue.js, і т.д.
Інші файли - bootstrap.js
, controllers.json
та hello_controller.js
-
повʼязані з темою, про яку ви скоро дізнаєтеся: Stimulus і Symfony UX.
Конфігурування Encore/Webpack
Все в Encore конфігурується через файл webpack.config.js
в корені вашого проекту.
Він вже містить необхідну вам базову конфігурацію:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// webpack.config.js
const Encore = require('@symfony/webpack-encore');
Encore
// каталог, де будуть зберігатися всі скомпільовані ресурси
.setOutputPath('public/build/')
// публічний шлях, який використовується веб-сервером для доступу до попереднього каталогу
.setPublicPath('/build')
.addEntry('app', './assets/app.js')
// розкоментуйте це, якщо ви хочете використати jQuery у наступному прикладі
.autoProvidejQuery()
;
// ...
Ключовою частиною є addEntry()
: він повідомляє Encore, що необхідно завантажити файл
assets/app.js
та слідувати всім твердженням require()
. Потім він запакує все разом
і - завдяки першому аргументи - виведе фінальні файли app.js
і app.css
в каталог
public/build
.
Щоб створити ресурси, виконайте наступне, якщо ви використовуєте менеджер пакетів Yarn:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# скомпілювати ресурси один раз
$ yarn encore dev
# або
$ npm run watch
# або автоматично рекомпілювати ресурси при зміні файлів
$ yarn encore dev --watch
# або
$ npm run dev-server
# при розгортанні, створити збірку промислового коду
$ yarn encore production
# або
$ npm run build
Якщо ви використовуєте менеджер пакетів npm, виконайте замість цього наступні команди:
1 2 3 4 5 6 7 8
# скомпілювати ресурси один раз
$ npm run dev
# або автоматично рекомпілювати ресурси при зміні файлів
$ npm run watch
# при розгортанні, створити збірку промислового коду
$ npm run build
Всі ці команди - наприклад, dev
або watch
- є скороченнями, визначеними
у вашому файлі package.json
.
Caution
Зупиняйте та перезапускайте encore
кожний раз, коли оновлюєте свій файл
webpack.config.js
.
Вітаємо! Тепер у вас є три нових файли:
public/build/app.js
(містить весь JavaScript для вашого запису "app")public/build/app.css
(містить весь CSS для вашого запису "app")public/build/runtime.js
(файл, який допомагає Webpack працювати)
Note
У реальності, у вас напевно є ще декілька файлів у public/build
. Деякі з них
зʼявились через розщеплення коду, оптимізації,
яка допомагає продуктивності, але не впливає на роботу речей. Інші допомагають Encore
робити свою роботу.
Далі, додайте їх у ваш базовий файл шаблону. Два помічника Twig та WebpackEncoreBundle можуть зробити більшість роботи за вас:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
{# templates/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
<!-- ... -->
{% block stylesheets %}
{# 'app' має співадати з першим аргументом addEntry() у webpack.config.js #}
{{ encore_entry_link_tags('app') }}
<!-- Відображає тег посилання (якщо ваш модуль потребує якогось CSS)
<link rel="stylesheet" href="/build/app.css"> -->
{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
<!-- Відображає app.js та файл webpack runtime.js
<script src="/build/runtime.js" defer></script>
<script src="/build/app.js" defer></script>
See note below about the "defer" attribute -->
{% endblock %}
</head>
<!-- ... -->
</html>
Ось і все! Коли ви оновите свою сторінку, весь JavaScript з assets/app.js
- а також будь-які інші файли JavaScript, які він мав - буде виконаний. Всі
файли CSS, які були обов'язковими, також будуть відображені.
Функції encore_entry_link_tags()
та encore_entry_script_tags()
читають з
файлу entrypoints.json
, який генерується Encore, щоб знати точне(і) ім'я(імена)
для відображення. Цей файл особливо корисний, так як ви можете
включити версіонування або
вказати ресусрвам на CDN не роблячи ніяких змін у
вашому шаблоні: шляхи в entrypoints.json
завжди будуть фінальними, правильними
шляхами. А якщо ви використовуєте splitEntryChunks()
(де Webpack розділяє виведення на більшу кількість рівних файлів), всі необхідні теги
script
та link
будуть відображені автоматично.
Якщо ви не використовуєте Symfony, ви можете ігнорувати файл entrypoints.json
та
вказати на фінальний створений файл напряму. entrypoints.json
потребується лише для
деяких необов'язкових функцій.
1.9.0
Атрибут defer
в тегах script
відкладає виконання JavaScript поки завантажується
сторінка (схоже на розміщення script
внизу сторінки). Здатність завжди додавати цей
атрибут буле представлена в WebpackEncoreBundle 1.9.0 і вона автоматично увімкнена у
рецепті цього пакету в файлі config/packages/webpack_encore.yaml
. Див.
WebpackEncoreBundle Configuration, щоб дізнатися більше деталей.
Вимагання модулів JavaScript
Webpack - це модульний пакувальник, що означає, що ви можете import
інші
файли JavaScript. Для початку, створіть файл, який експортує функцію:
1 2 3 4
// assets/greet.js
export default function(name) {
return `Yo yo ${name} - welcome to Encore!`;
};
Ми будемо використовувати jQuery, щоб надрукувати це повідомлення на сторінці. Встановіть його через:
1 2 3 4 5
# якщо ви використовуєте менеджер пакетів Yarn
$ yarn add jquery --dev
# якщо ви використовуєте менеджер пакетів npm
$ npm install jquery --save-dev
Чудово! Використайте import
, щоб імпортувати jquery
та greet.js
:
1 2 3 4 5 6 7 8 9 10 11 12 13
// assets/app.js
// ...
+ // завантажує пакет jquery з node_modules
+ import jquery from 'jquery';
+ // імпортує функцію з greet.js (розширення .js необов'язкове)
+ // ./ (or ../) means to look for a local file
+ import greet from './greet';
+ $(document).ready(function() {
+ $('body').prepend('<h1>'+greet('jill')+'</h1>');
+ });
Ось і все! Якщо ви раніше виконували encore dev --watch
, ваші финальні створені файли вже
були оновлені: jQuery та greet.js
були автоматично додані до файлу виведення (app.js
).
Оновіть, щоб побачити повідомлення!
Stimulus і Symfony UX
Яким би простим не був приклад вище, замість створення вашого додатку всередині app.js
,
ми рекомендуємо Stimulus: маленький фреймворк JavaScript, який полегшує процес доєднання
поведінки до HTML. Він потужний і ви у нього закохаєтесь! Symfony навіть надає пакети, щоб
додати більше функцій до Stimulus. Вони називаються пакетами Symfony UX.
Якщо ви дотримувалися інструкцій з налаштування, Stimulus має бути вже встановлений і
готовий до роботи! Насправді, у цьому полягає ціль файлу assets/bootstrap.js
: ініціалізувати
Stimulus та автотматично завантажити всі "контролери" з каталогу assets/controllers/
.
Давайте розглянемо простий приклад Stimulus. У шаблоні Twig, уявіть, що ви маєте:
1 2 3 4 5 6 7 8 9
<div {{ stimulus_controller('say-hello') }}>
<input type="text" {{ stimulus_target('say-hello', 'name') }}>
<button {{ stimulus_action('say-hello', 'greet') }}>
Greet
</button>
<div {{ stimulus_target('say-hello', 'output') }}></div>
</div>
stimulus_controller('say-hello')
відображає атрибут data-controller="say-hello"
.
Коли цей елемент зʼявляється на сторінці, Stimulus автоматично шукає та інціалізує контролер
під назвою say-hello-controller.js
. Створіть це у вашому каталозі assets/controllers/
:
1 2 3 4 5 6 7 8 9 10
// assets/controllers/say-hello-controller.js
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static targets = ['name', 'output']
greet() {
this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!`
}
}
Результат? Коли ви натискаєте на кнопку "Greet", вона виводить ваше імʼя! А якщо на сторінку
додати більше елементів {{ stimulus_controller('say-hello') }}
- наприклад, через Ajax -
вони миттєво працюватимуть: необхідності повторно ініціалізувати щось немає.
Готові дізнатися більше про Stimulus?
- Прочитайте Документацію Stimulus
- Дізнайтеся більше про те, як працює система Symfony UX
- Перегляньте список усіх пакетів Symfony UX
Дізнайтеся більше про Symfony Stimulus Bridge - включно із суперсилою, яка робить ваші контролери ліниво завантажуваними!
Screencast
Або перегляньте Stimulus Screencast на SymfonyCasts.
Turbo: Досвід блискавично-швидкого односторінкового додатку
Symfony постачається з тісною інтеграцією з ще однією бібліотекою JavaScript, яка має назву Turbo. Turbo автоматично перетворює всі натискання на посилання та відправки форм на виклик Ajax, з нульовими (або майже нульовими) змінами у вашому коді Symfony! Результат? Ви отримуєте швидкість односторінкового додатку, без потреби написання JavaScript.
Щоб дізнатися більше, розгляньте пакет symfony/ux-turbo.
Screencast
Або перегляньте Turbo Screencast на SymfonyCasts.
Специфічний для сторінки JavaScript або CSS
На даний момент у вас є лише один фінальний файл JavaScript: app.js
. Encore може бути
розщеплено на декілька файлів з міркувань продуктивності (див. шматки розщеплення),
але весь цей код досі завантажується на кожній сторінці.
Але що, якщо у вас є деякий додатковий JavaScript або CSS (наприклад, для продуктивності), який ви хочете додати тільки на конкретні сторінки?
Ліниві контролери
Одним дуже гарним рішенням за умови використання Stimulus є використання лінивих контролерів.
Щоб активувати це у контролері, додайте спеціальни stimulusFetch: 'lazy'
над вашим
класом контролера:
1 2 3 4 5 6 7
// assets/controllers/lazy-example-controller.js
import { Controller } from '@hotwired/stimulus';
/* stimulusFetch: 'lazy' */
export default class extends Controller {
// ...
}
Ось і все! Цей код контролера - та будь-які модулі, які він експортує - буде розщеплено
на окремі файли Encore. Потім, ці файли не будуть завантажені до моменту появи співпадіння
елемента на сторінці (наприклад, <div data-controller="lazy-example">
)
Note
Якщо ви пишете свої контролери з використанням TypeScript, переконайтеся, що
removeComments
не встановлено як true
у вашій конфігурації TypeScript.
Множинні записи
Ще однією опцією є створення специфічного для сторінки JavaScript або CSS (наприклад, оформлення замовлення, акаунт і т.д.). Щоб зробити це, створіть новий файл "запису" JavaScript для кожної сторінки:
1 2
// assets/checkout.js
// користувацький код для вашої сторінки оформлення замовлення
1 2
// assets/account.js
// користувацький код для вашої сторінки акаунту
Далі, використайте addEntry()
, щоб сказати Webpack прочитати ці два нових файли
під час побудови:
1 2 3 4 5 6 7
// webpack.config.js
Encore
// ...
.addEntry('app', './assets/app.js')
+ .addEntry('checkout', './assets/checkout.js')
+ .addEntry('account', './assets/account.js')
// ...
І через те, що ви щойно змінили файл webpack.config.js
, переконайтеся в тому, що
ви зупинили та перезапустили Encore:
1 2 3 4 5
# якщо ви використовуєте менеджер пакетів Yarn
$ yarn watch
# якщо ви використовуєте менеджер пакетів npm
$ npm run watch
Webpack тепер виведе новий файл checkout.js
та новий файл account.js
у вашому
каталозі побудови. І, якщо якісь з цих файлів вимагають/імпортують CSS, Webpack також
виведе файли checkout.css
та account.css
.
Нарешті, додайте теги script
та link
на окремих сторінках, де вам потрібно:
1 2 3 4 5 6 7 8 9 10 11 12
{# templates/.../checkout.html.twig #}
{% extends 'base.html.twig' %}
+ {% block stylesheets %}
+ {{ parent() }}
+ {{ encore_entry_link_tags('checkout') }}
+ {% endblock %}
+ {% block javascripts %}
+ {{ parent() }}
+ {{ encore_entry_script_tags('checkout') }}
+ {% endblock %}
Тепер сторінка оформлення замовлення міститиме весь JavaScript та CSS для запису app
(через те, що його включено до base.html.twig
і є виклик {{ parent() }}
) та
ваш запис checkout
. З цим, JavaScript та CSS, потрібні для кожної сторінки, можуть
жити всередині запису app
, а код, потрібний лише для сторінки оформлення замовлення,
може жити всередині checkout
.
Використання Sass/LESS/Stylus
Ви вже опанували основи Encore. Чудово! Але існує багато інших функцій, які ви можете
вирішити використовувати, якщо вони вам знадобляться. Наприклад, замість використання
звичайного CSS, ви можете також використовувати Sass, LESS або Stylus. Щоб використати Sass,
переіменуйте файл app.css
в app.scss
та оновіть твердження import
:
1 2 3
// assets/app.js
- import './styles/app.css';
+ import './styles/app.scss';
Потім, повідомте Encore увімкнути попередній процесор Sass:
1 2 3 4 5 6
// webpack.config.js
Encore
// ...
+ .enableSassLoader()
;
Так як ви щойно змінили ваш файл webpack.config.js
, вам знадобиться перезапустити
Encore. Коли ви це зробите, ви побачите помилку!
1 2
> Error: Встановіть sass-loader та sass, щоб використовувати enableSassLoader()
> yarn add sass-loader@^12.0.0 sass --dev
Encore підтримує багато функцій. Але, замість того, щоб гвалтувати вас ними, коли вам буде потрібна функція, Encore повідомить вам, що необхідно встановити. Виконайте:
1 2 3 4 5 6 7
# якщо ви використовуєте менеджер пакетів Yarn
$ yarn add sass-loader@^12.0.0 sass --dev
$ yarn encore dev --watch
# якщо ви використовуєте менеджер пакетів npm
$ npm install sass-loader@^12.0.0 sass --save-dev
$ npm run watch
Тепер ваш застосунок підтримує Sass. Encore також підтримує LESS та Stylus. Див. Предпроцессоры CSS: Sass, LESS, Stylus, и др..
Компіляція лише CSS-файлу
Caution
Використання addStyleEntry()
підтримується, але не рекомендується. Кращою опцією
буде слідувати патерну вище: використовувати addEntry()
, щоб вказати на файл
JavaScript, а потім вимагати необхідний CSS зсередини.
Якщо ви хочете лише скомпілювати CSS-файл, це можливо через addStyleEntry()
:
1 2 3 4 5 6
// webpack.config.js
Encore
// ...
.addStyleEntry('some_page', './assets/styles/some_page.css')
;
Це виведе новий some_page.css
.
Продовжуйте!
Encore підтримує ще багато функцій! Щоб побачити весь перелік того, що ви можете зробити, див. файл Encore's index.js. Або поверніться до списку статей Encore.