Encore: Setting up your Project
Warning: You are browsing the documentation for Symfony 3.x, which is no longer maintained.
Read the updated version of this page for Symfony 7.1 (the current stable version).
After installing Encore, your app already has one
CSS and one JS file, organized into an assets/
directory:
assets/js/app.js
assets/css/app.css
With Encore, think of your app.js
file like a standalone JavaScript
application: it will require all of the dependencies it needs (e.g. jQuery or React),
including any CSS. Your app.js
file is already doing this with a special
require()
function:
1 2 3 4 5 6
// assets/js/app.js
// ...
require('../css/app.css');
// var $ = require('jquery');
Encore's job (via Webpack) is simple: to read and follow all of the require()
statements and create one final app.js
(and app.css
) that contains everything
your app needs. Encore can do a lot more: minify files, pre-process Sass/LESS,
support React, Vue.js, etc.
Configuring Encore/Webpack
Everything in Encore is configured via a webpack.config.js
file at the root
of your project. It already holds the basic config you need:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// webpack.config.js
var Encore = require('@symfony/webpack-encore');
Encore
// directory where compiled assets will be stored
.setOutputPath('web/build/')
// public path used by the web server to access the output path
.setPublicPath('/build')
.addEntry('app', './assets/js/app.js')
// ...
;
// ...
The key part is addEntry()
: this tells Encore to load the assets/js/app.js
file and follow all of the require()
statements. It will then package everything
together and - thanks to the first app
argument - output final app.js
and
app.css
files into the web/build
directory.
To build the assets, run:
1 2 3 4 5 6 7 8
# compile assets once
$ yarn encore dev
# or, recompile assets automatically when files change
$ yarn encore dev --watch
# on deploy, create a production build
$ yarn encore production
Note
Stop and restart encore
each time you update your webpack.config.js
file.
Congrats! You now have three new files:
web/build/app.js
(holds all the JavaScript for your "app" entry)web/build/app.css
(holds all the CSS for your "app" entry)web/build/runtime.js
(a file that helps Webpack do its job)
Next, include these in your base layout file. Two Twig helpers from WebpackEncoreBundle can do most of the work for you:
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
{# app/Resources/views/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
<!-- ... -->
{% block stylesheets %}
{# 'app' must match the first argument to addEntry() in webpack.config.js #}
{{ encore_entry_link_tags('app') }}
<!-- Renders a link tag (if your module requires any CSS)
<link rel="stylesheet" href="/build/app.css"> -->
{% endblock %}
</head>
<body>
<!-- ... -->
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
<!-- Renders app.js & a webpack runtime.js file
<script src="/build/runtime.js"></script>
<script src="/build/app.js"></script> -->
{% endblock %}
</body>
</html>
That's it! When you refresh your page, all of the JavaScript from
assets/js/app.js
- as well as any other JavaScript files it included - will
be executed. All the CSS files that were required will also be displayed.
The encore_entry_link_tags()
and encore_entry_script_tags()
functions
read from an entrypoints.json
file that's generated by Encore to know the exact
filename(s) to render. This file is especially useful because you can
enable versioning or
point assets to a CDN without making any changes to your
template: the paths in entrypoints.json
will always be the final, correct paths.
If you're not using Symfony, you can ignore the entrypoints.json
file and
point to the final, built file directly. entrypoints.json
is only required for
some optional features.
0.21.0
The encore_entry_link_tags()
comes from WebpackEncoreBundle and relies
on a feature in Encore that was first introduced in version 0.21.0. Previously,
the asset()
function was used to point directly to the file.
Requiring JavaScript Modules
Webpack is a module bundler... which means that you can require
other JavaScript
files. First, create a file that exports a function:
1 2 3 4
// assets/js/greet.js
module.exports = function(name) {
return `Yo yo ${name} - welcome to Encore!`;
};
We'll use jQuery to print this message on the page. Install it via:
1
$ yarn add jquery --dev
Great! Use require()
to import jquery
and greet.js
:
1 2 3 4 5 6 7 8 9 10 11 12 13
// assets/js/app.js
// ...
+ // loads the jquery package from node_modules
+ var $ = require('jquery');
+ // import the function from greet.js (the .js extension is optional)
+ // ./ (or ../) means to look for a local file
+ var greet = require('./greet');
+ $(document).ready(function() {
+ $('body').prepend('<h1>'+greet('jill')+'</h1>');
+ });
That's it! If you previously ran encore dev --watch
, your final, built files
have already been updated: jQuery and greet.js
have been automatically
added to the output file (app.js
). Refresh to see the message!
The import and export Statements
Instead of using require()
and module.exports
like shown above, JavaScript
provides an alternate syntax based on the ECMAScript 6 modules that includes
the ability to use dynamic imports.
To export values, use export
:
1 2 3 4 5
// assets/js/greet.js
- module.exports = function(name) {
+ export default function(name) {
return `Yo yo ${name} - welcome to Encore!`;
};
To import values, use import
:
1 2 3 4 5 6 7 8 9
// assets/js/app.js
- require('../css/app.css');
+ import '../css/app.css';
- var $ = require('jquery');
+ import $ from 'jquery';
- var greet = require('./greet');
+ import greet from './greet';
Page-Specific JavaScript or CSS (Multiple Entries)
So far, you only have one final JavaScript file: app.js
. For small applications
or SPA's (Single Page Applications), that might be fine! However, as your app grows,
you may want to have page-specific JavaScript or CSS (e.g. checkout, account,
etc.). To handle this, create a new "entry" JavaScript file for each page:
1 2
// assets/js/checkout.js
// custom code for your checkout page
1 2
// assets/js/account.js
// custom code for your account page
Next, use addEntry()
to tell Webpack to read these two new files when it builds:
1 2 3 4 5 6 7
// webpack.config.js
Encore
// ...
.addEntry('app', './assets/js/app.js')
+ .addEntry('checkout', './assets/js/checkout.js')
+ .addEntry('account', './assets/js/account.js')
// ...
And because you just changed the webpack.config.js
file, make sure to stop
and restart Encore:
1
$ yarn run encore dev --watch
Webpack will now output a new checkout.js
file and a new account.js
file
in your build directory. And, if any of those files require/import CSS, Webpack
will also output checkout.css
and account.css
files.
Finally, include the script
and link
tags on the individual pages where
you need them:
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 %}
Now, the checkout page will contain all the JavaScript and CSS for the app
entry
(because this is included in base.html.twig
and there is the {{ parent() }}
call)
and your checkout
entry.
See Creating Page-Specific CSS/JS for more details. To avoid duplicating the same code in different entry files, see Preventing Duplication by "Splitting" Shared Code into Separate Files.
Using Sass/LESS/Stylus
You've already mastered the basics of Encore. Nice! But, there are many more
features that you can opt into if you need them. For example, instead of using plain
CSS you can also use Sass, LESS or Stylus. To use Sass, rename the app.css
file to app.scss
and update the import
statement:
1 2 3
// assets/js/app.js
- import '../css/app.css';
+ import '../css/app.scss';
Then, tell Encore to enable the Sass pre-processor:
1 2 3 4 5 6
// webpack.config.js
Encore
// ...
+ .enableSassLoader()
;
Because you just changed your webpack.config.js
file, you'll need to restart
Encore. When you do, you'll see an error!
1 2
> Error: Install sass-loader & node-sass to use enableSassLoader()
> yarn add sass-loader@^8.0.0 node-sass --dev
Encore supports many features. But, instead of forcing all of them on you, when you need a feature, Encore will tell you what you need to install. Run:
1 2
$ yarn add sass-loader@^8.0.0 node-sass --dev
$ yarn encore dev --watch
Your app now supports Sass. Encore also supports LESS and Stylus. See CSS Preprocessors: Sass, LESS, Stylus, etc..
Compiling Only a CSS File
Caution
Using addStyleEntry()
is supported, but not recommended. A better option
is to follow the pattern above: use addEntry()
to point to a JavaScript
file, then require the CSS needed from inside of that.
If you want to only compile a CSS file, that's possible via addStyleEntry()
:
1 2 3 4 5 6
// webpack.config.js
Encore
// ...
.addStyleEntry('some_page', './assets/css/some_page.css')
;
This will output a new some_page.css
.
Keep Going!
Encore supports many more features! For a full list of what you can do, see Encore's index.js file. Or, go back to list of Encore articles.