symfony/webpack-encore-bundle
Symfony bundle integrating Webpack Encore into your app. Adds asset building, versioning, and entrypoint management with simple Twig helpers for scripts/styles, plus sane defaults and easy configuration for modern JS/CSS workflows.
Installation:
composer require symfony/webpack-encore-bundle
Ensure WebpackEncoreBundle is registered in config/bundles.php (auto-registered in Symfony Flex projects).
Configure Webpack Encore:
Update webpack.config.js to use Encore:
const Encore = require('@symfony/webpack-encore');
Encore
.setOutputPath('public/build/')
.setPublicPath('/build')
.addEntry('app', './assets/app.js')
.splitEntryChunks()
.enableSingleRuntimeChunk()
.cleanupOutputBeforeBuild()
.enableBuildNotifications()
.enableSourceMaps(!Encore.isProduction())
.enableVersioning(Encore.isProduction())
.enableSassLoader()
.enableStimulusBridge('./assets/controllers.json');
First Use Case: Render dynamic assets in a Twig template:
{{ encore_entry_script_tags('app') }}
{{ encore_entry_link_tags('app') }}
Dynamic Asset Rendering:
Use encore_entry_script_tags() and encore_entry_link_tags() to inject Webpack Encore-generated assets dynamically:
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{{ encore_entry_script_tags('admin') }}
{% endblock %}
Conditional Asset Loading: Check if an entrypoint exists before rendering:
{% if encore_entry_exists('app') %}
{{ encore_entry_script_tags('app') }}
{% endif %}
Stimulus Integration: Use Twig filters for Stimulus controllers/actions:
<div {{ stimulus_controller('hello-controller') }} data-hello-target="world">
{{ stimulus_action('hello-controller', 'sayHello') }}
</div>
Remote entrypoints.json:
Host entrypoints.json remotely (e.g., CDN) and configure in config/packages/webpack_encore.yaml:
webpack_encore:
entrypoints:
remote: true
url: 'https://cdn.example.com/entrypoints.json'
Custom Attributes: Add custom attributes to script/link tags:
{{ encore_entry_script_tags('app', { defer: true, 'data-custom': 'value' }) }}
php bin/console cache:warmup --env=prod to pre-generate entrypoints.json during deployment.webpack_encore.yaml to override settings per environment:
when@prod:
webpack_encore:
output_path: 'public/build/prod'
public_path: '/build/prod'
.enableVersioning(Encore.isProduction())
Stimulus Deprecation:
stimulus_controller(), stimulus_action(), and stimulus_target() are deprecated. Use symfony/stimulus-bundle instead:
composer require symfony/stimulus-bundle
Sub-Requests:
{{ render(controller(...)) }}). Use encore_reset_assets() in parent templates:
{% encore_reset_assets %}
Remote entrypoints.json:
curl -I https://cdn.example.com/entrypoints.json
PHP Version Mismatch:
composer require symfony/webpack-encore-bundle:^1.17
Double Escaping:
toArray() is called explicitly:
{{ form_row(form.password, { attr: stimulus_action('controller', 'action').toArray() }) }}
Missing Assets:
entrypoints.json exists in public/build/ (or remote URL). Clear cache if needed:
php bin/console cache:clear
yarn encore dev --watch
Integrity Hash Errors:
integrity attributes are included in preload tags (fixed in v2.2.0). Update Webpack config:
.configureBabelPresetEnv((config) => {
config.useBuiltIns = 'usage';
config.corejs = 3;
})
Custom Entrypoint Lookup:
Override the default EntrypointLookup service for custom logic:
services:
App\Custom\EntrypointLookup:
decorates: 'webpack_encore.encore.entrypoint_lookup'
Twig Extensions: Extend Twig functionality by creating a custom extension:
class CustomEncoreExtension extends \Twig\Extension\AbstractExtension
{
public function getFunctions()
{
return [
new \Twig\TwigFunction('custom_encore_tag', [$this, 'renderCustomTag']),
];
}
public function renderCustomTag(string $entrypoint): string
{
// Custom logic
}
}
Register in config/packages/twig.yaml:
twig:
extensions:
- App\Custom\EncoreExtension
Build-Time Hooks: Use Symfony’s event system to hook into Webpack Encore’s build process:
// config/services.yaml
services:
App\EventListener\EncoreBuildListener:
tags:
- { name: kernel.event_listener, event: webpack.encore.build.start, method: onBuildStart }
How can I help you explore Laravel packages today?