Продвинутая конфигурация Webpack
Дата обновления перевода 2024-07-25
Продвинутая конфигурация Webpack
Если подытожить, Encore генерирует конфигурацию Webpack, которая используется
в вашем файле webpack.config.js
. Encore не поддерживаетдобавление всех
опций конфигурации Webpack, так как многие вы можете с лёгкостью добавить сами.
Например, представьте, что вам нужно автоматически разрешить новое расширение. Чтобы сделать это, измените конфигурацию после её извлечения из Encore:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// webpack.config.js
const Encore = require('@symfony/webpack-encore');
// ... здесь вся конфигурация Encore
// получите конфигурацию, а потом измените её!
const config = Encore.getWebpackConfig();
// добавьте расширение
config.resolve.extensions.push('json');
// экспортируйте финальую конфигурацию
module.exports = config;
Но будьте осторожны, чтобы случайно не переопределить никакую конфигурацию из Encore:
1 2 3 4 5 6 7 8
// webpack.config.js
// ...
// ХОРОШО - изменяет массив config.resolve.extensions
config.resolve.extensions.push('json');
// ПЛОХО - заменяет любые расширения, добавленные Encore
// config.resolve.extensions = ['json'];
Конфигурация опций наблюдения и опросы
Encore предоставляет метод configureWatchOptions()
для конфигурации
Опций наблюдения при запуске encore dev --watch
или encore dev-server
:
1 2 3 4 5
Encore.configureWatchOptions(function(watchOptions) {
// включить опросы и проверять изменения каждые 250 мс
// опросы полезны при запуске Encore внутри виртуальной машины
watchOptions.poll = 250;
});
Определение множества конфигураций Webpack
Webpack поддерживает передачу массива конфигураций, которые обрабатываются
параллельно. Webpack Encore включает в себя объект reset()
, позволяющий
перезапустить состояние текущей конфигурации, чтобы построить новую:
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 27 28 29 30 31 32 33 34 35 36 37 38
// определить первую конфигурацию
Encore
.setOutputPath('public/build/first_build/')
.setPublicPath('/build/first_build')
.addEntry('app', './assets/app.js')
.addStyleEntry('global', './assets/styles/global.scss')
.enableSassLoader()
.autoProvidejQuery()
.enableSourceMaps(!Encore.isProduction())
;
// построить первую конфигурацию
const firstConfig = Encore.getWebpackConfig();
// Установить уникальное имя для конфигурации (понадобится позже!)
firstConfig.name = 'firstConfig';
// перезапустить Encore, чтобы построить вторую конфигурацию
Encore.reset();
// определить вторую конфигурацию
Encore
.setOutputPath('public/build/second_build/')
.setPublicPath('/build/second_build')
.addEntry('mobile', './assets/mobile.js')
.addStyleEntry('mobile', './assets/styles/mobile.less')
.enableLessLoader()
.enableSourceMaps(!Encore.isProduction())
;
// построить вторую конфигурацию
const secondConfig = Encore.getWebpackConfig();
// Установить уникальное имя для конфигурации (понадобится позже!)
secondConfig.name = 'secondConfig';
// экспортировать финальную конфигурацию в качестве массива множества конфигураций
module.exports = [firstConfig, secondConfig];
При запуске Encore, обе конфигурации будут построены параллельно. Если вы
предпочитаете строить конфигурации отдельно, передайте опцию --config-name
:
1
$ npm run dev -- --config-name firstConfig
Далее, определите каталоги вывода каждой компоновки:
1 2 3 4 5 6
# config/packages/webpack_encore.yaml
webpack_encore:
output_path: '%kernel.project_dir%/public/default_build'
builds:
firstConfig: '%kernel.project_dir%/public/first_build'
secondConfig: '%kernel.project_dir%/public/second_build'
Также определите манифесты ресурсов для каждой компоновки:
1 2 3 4 5 6 7 8
# config/packages/assets.yaml
framework:
assets:
packages:
first_build:
json_manifest_path: '%kernel.project_dir%/public/first_build/manifest.json'
second_build:
json_manifest_path: '%kernel.project_dir%/public/second_build/manifest.json'
Наконец, используйте третий необязательный параметр функций encore_entry_*_tags()
,
чтобы указать, какую компоновку использовать:
1 2 3 4 5 6 7
{# Использование файла entrypoints.json, расположенного в ./public/first_build #}
{{ encore_entry_script_tags('app', null, 'firstConfig') }}
{{ encore_entry_link_tags('global', null, 'firstConfig') }}
{# Использование файла entrypoints.json, расположенного в ./public/second_build #}
{{ encore_entry_script_tags('mobile', null, 'secondConfig') }}
{{ encore_entry_link_tags('mobile', null, 'secondConfig') }}
Избегание пропуска CSS при отображении нескольких шаблонов
Когда вы отображаете два или более шаблонов в одном запросе, например, два электронных письма,
необходимо вызвать метод reset()
для интерфейса EntrypointLookupInterface
.
Для этого внедрите интерфейс EntrypointLookupInterface
:
1 2 3 4 5 6 7
public function __construct(EntrypointLookupInterface $entryPointLookup) {}
public function send() {
$this->twig->render($emailOne);
$this->entryPointLookup->reset();
$this->render($emailTwo);
}
Если вы используете несколько конфигураций Webpack (например, одну для админа и одну
для писем), вам нужно будет внедрить правильный сервис EntrypointLookupInterface
.
Чтобы найти правильный сервис, воспользуйтесь следующей командой:
1 2 3 4 5 6 7 8 9
$ php bin/console console debug:container entrypoint_lookup
# Вы увидите результат, похожий на этот:
Выберите один из следующих сервисов, чтобы отобразить информацию о нем:
[0] webpack_encore.entrypoint_lookup_collection
[1] webpack_encore.entrypoint_lookup.cache_warmer
[2] webpack_encore.entrypoint_lookup[_default]
[3] webpack_encore.entrypoint_lookup[admin]
[4] webpack_encore.entrypoint_lookup[email]
В этом примере конфигурация, связанная с конфигурацией email
, та, которая
называется webpack_encore.entrypoint_lookup[email]
.
Чтобы внедрить этот сервис в свой класс, используйте опцию bind
:
1 2 3 4 5
# config/services.yaml
services:
_defaults
bind:
Symfony\WebpackEncoreBundle\Asset\EntrypointLookupInterface $entryPointLookupEmail: '@webpack_encore.entrypoint_lookup[email]'
Теперь вы можете внедрить сервис в ваш класс:
1 2 3 4 5 6 7
public function __construct(EntrypointLookupInterface $entryPointLookupEmail) {}
public function send() {
$this->twig->render($emailOne);
$this->entryPointLookupEmail->reset();
$this->render($emailTwo);
}
Генерирование объекта конфигурации Webpack без использования интерфейса командной строки
Обычно вы будете использовать ваш файл webpack.config.js
вызывая Encore из
интерфейса командной строки. Но иногда, доступ к сгенерированной конфигурации
Webpack можент понадобиться инструментам, не использующим Encore (например,
исполнителю тестов, вроде Karma).
Проблема в том, что если вы попробуете сгенерировать этот объект конфигурации
Webpack без использования команды encore
, вы столкнетесь со следующей ошибкой:
1
Error: Encore.setOutputPath() пока еще не может быть вызван, так как окружение рабочей среды похоже еще не было сконфигурировано. Убедитесь в том, что вы используете выполнимое encore или сначала вызовите Encore.configureRuntimeEnvironment(), если вы специально не вызываете Encore напрямую.
Причиной этого сообщения является то, что Encore необходимо знать несколько вещей перед тем, как создать объект конфигурации, и самая важная из них - каково целевое окружение.
Чтобы решить эту проблему, вы можете использовать configureRuntimeEnvironment
.
Этот метод должен быть вызван из файла JavaScript до требования webpack.config.js
.
Например:
1 2 3 4 5 6 7
const Encore = require('@symfony/webpack-encore');
// Установить окружение выполнения
Encore.configureRuntimeEnvironment('dev');
// Извлечь объект конфигурации Webpack
const webpackConfig = require('./webpack.config');
Если необходимо, вы также можете передать этому методу все опции, которые вы обычно использовали бы из интерфейса командной строки:
1 2 3 4 5 6
Encore.configureRuntimeEnvironment('dev-server', {
// Те же опции, которые вы бы использовали с
// утилитой CLI, с именами в camelCase.
https: true,
keepPublicPath: true,
});
Полный контроль над правилами загрузчиков
Метод configureLoaderRule()
предоставляет прямой путь для
конфигурации правил загрузчиков Webpack (module.rules
, см. Конфигурация).
Это метод нижнего уровня, Все ваши модификации будут применены прямо перед отправкой правил загрузчиков в Webpack. Это означает, что вы можете переопределеить конфигурацию по умолчанию предоставленную Encore, что может что-то сломать. Будьте осторожны при использовании.
Одним из способов применения может быть сконфигурировать eslint-loader
, чтобы контролировать
ещё и файлы Vue.
Следующий код эквивалентен:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Вручную
const webpackConfig = Encore.getWebpackConfig();
const eslintLoader = webpackConfig.module.rules.find(rule => rule.loader === 'eslint-loader');
eslintLoader.test = /\.(jsx?|vue)$/;
return webpackConfig;
// Используя Encore.configureLoaderRule()
Encore.configureLoaderRule('eslint', loaderRule => {
loaderRule.test = /\.(jsx?|vue)$/
});
return Encore.getWebpackConfig();
- Следующие загрузчики можно сконфигурировать с помощью
configureLoaderRule()
: -
javascript
(псевдонимjs
)css
images
(но вместо него используйтеconfigureImageRule()
)fonts
(но вместо него используйтеconfigureFontRule()
)sass
(псевдонимscss
)less
stylus
svelte
vue
eslint
typescript
(псевдонимts
)handlebars
Конфигурация псевдонимов во время импорта или запрашивания модулей
Опция Webpack resolve.alias позволяет создавать псевдонимы, чтобы упроститьimport
или require
определенных модулей (например, путем создания псевдонимов
для часто используемых папок src/
). В Webpack Encore вы можете использовать эту
опцию через метод addAliases()
:
1 2 3 4
Encore.addAliases({
Utilities: path.resolve(__dirname, 'src/utilities/'),
Templates: path.resolve(__dirname, 'src/templates/')
})
С конфигурацией, приведенной выше, вы теперь можете импортировать определенные модули лаконичнее:
1 2
-import Utility from '../../utilities/utility';
+import Utility from 'Utilities/utility';
Исключение некоторых зависимостей из пакетов вывода
Опция Webpack externals позволяет предотвратить упаковку определенных импортированных
пакетов и вместо этого получать эти внешние зависимости во время выполнения. Эта возможность
в основном полезна для разработчиков библиотек JavaScript, так что вам она, скорее всего, не понадобится.
В Webpack Encore вы можете использовать эту опцию через метод addExternals()
:
1 2 3 4 5 6 7
// это не будет включать jQuery и React в пакеты вывода, генерируемые
// Webpack Encore. Вам нужно будет самостоятельно загрузить эти зависимости.
// (например, с помощью тега `<script>`), чтобы приложение или сайт заработали.
Encore.addExternals({
jquery: 'jQuery',
react: 'react'
})