Skip to content

[WCM] Updating the Encore documentation + New recipe #10128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/encore/advanced-config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ prefer to build configs separately, pass the ``--config-name`` option:

.. code-block:: terminal

$ yarn run encore dev --config-name firstConfig
$ yarn encore dev --config-name firstConfig

.. _`configuration options`: https://webpack.js.org/configuration/
.. _`Webpack's watchOptions`: https://webpack.js.org/configuration/watch/#watchoptions
Expand Down
100 changes: 100 additions & 0 deletions frontend/encore/installation-no-flex.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
Encore Installation (without Symfony Flex)
==========================================

.. tip:

If your project uses Symfony Flex, read :doc:`/frontend/encore/installation`
for easier instructions.

Installing Encore
-----------------

Install Encore into your project via Yarn:

.. code-block:: terminal

$ yarn add @symfony/webpack-encore --dev

.. note::

If you prefer to use `npm`_, no problem! Run ``npm install @symfony/webpack-encore --save-dev``.

This command creates (or modifies) a ``package.json`` file and downloads dependencies
into a ``node_modules/`` directory. Yarn also creates/updates a ``yarn.lock``
(called ``package-lock.json`` if you use npm version 5+).

.. tip::

You *should* commit ``package.json`` and ``yarn.lock`` (or ``package-lock.json``
if using npm 5) to version control, but ignore ``node_modules/``.

Creating the webpack.config.js File
-----------------------------------

Next, create a new ``webpack.config.js`` file at the root of your project:

.. code-block:: js

var Encore = require('@symfony/webpack-encore');

Encore
// directory where compiled assets will be stored
.setOutputPath('public/build/')
// public path used by the web server to access the output path
.setPublicPath('/build')
// only needed for CDN's or sub-directory deploy
//.setManifestKeyPrefix('build/')

/*
* ENTRY CONFIG
*
* Add 1 entry for each "page" of your app
* (including one that's included on every page - e.g. "app")
*
* Each entry will result in one JavaScript file (e.g. app.js)
* and one CSS file (e.g. app.css) if you JavaScript imports CSS.
*/
.addEntry('app', './assets/js/app.js')
//.addEntry('page1', './assets/js/page1.js')
//.addEntry('page2', './assets/js/page2.js')

.cleanupOutputBeforeBuild()
.enableSourceMaps(!Encore.isProduction())
// enables hashed filenames (e.g. app.abc123.css)
.enableVersioning(Encore.isProduction())

// uncomment if you use TypeScript
//.enableTypeScriptLoader()

// uncomment if you use Sass/SCSS files
//.enableSassLoader()

// uncomment if you're having problems with a jQuery plugin
//.autoProvidejQuery()
;

module.exports = Encore.getWebpackConfig();

Next, create a new ``assets/js/app.js`` file with some basic JavaScript *and*
import some JavaScript:

.. code-block:: javascript

// assets/js/app.js

require('../css/app.css');

console.log('Hello Webpack Encore');

And the new ``assets/css/app.css`` file:

.. code-block:: css

// assets/css/app.css
body {
background-color: lightgray;
}

You'll customize and learn more about these file in :doc:`/frontend/encore/simple-example`.

.. _`npm`: https://www.npmjs.com/
48 changes: 12 additions & 36 deletions frontend/encore/installation.rst
Original file line number Diff line number Diff line change
@@ -1,46 +1,22 @@
Encore Installation
===================
Installing Encore (with Symfony Flex)
=====================================

First, make sure you `install Node.js`_ and also the `Yarn package manager`_.
.. tip:

Then, install Encore into your project with Yarn:
If your project does **not** use Symfony Flex, read :doc:`/frontend/encore/installation-no-flex`.

.. code-block:: terminal

$ yarn add @symfony/webpack-encore --dev

.. note::

If you want to use `npm`_ instead of `yarn`_:

.. code-block:: terminal

$ npm install @symfony/webpack-encore --save-dev
First, make sure you `install Node.js`_ and also the `Yarn package manager`_. Then
run:

.. tip::

If you are using Flex for your project, you can initialize your project for Encore via:

.. code-block:: terminal

$ composer require symfony/webpack-encore-pack
$ yarn install

This will create a ``webpack.config.js`` file, add the ``assets/`` directory, and add ``node_modules/`` to
``.gitignore``.

This command creates (or modifies) a ``package.json`` file and downloads dependencies
into a ``node_modules/`` directory. When using Yarn, a file called ``yarn.lock``
is also created/updated. When using npm 5, a ``package-lock.json`` file is created/updated.
.. code-block:: terminal

.. tip::
$ composer require webpack-encore
$ yarn install

You should commit ``package.json`` and ``yarn.lock`` (or ``package-lock.json``
if using npm 5) to version control, but ignore ``node_modules/``.
This will create a ``webpack.config.js`` file, add the ``assets/`` directory, and
add ``node_modules/`` to ``.gitignore``.

Next, create your ``webpack.config.js`` in :doc:`/frontend/encore/simple-example`!
Nice work! Write your first JavaScript and CSS by reading :doc:`/frontend/encore/simple-example`!

.. _`install Node.js`: https://nodejs.org/en/download/
.. _`Yarn package manager`: https://yarnpkg.com/lang/en/docs/install/
.. _`npm`: https://www.npmjs.com/
.. _`yarn`: https://yarnpkg.com/
60 changes: 31 additions & 29 deletions frontend/encore/shared-entry.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,55 @@ Creating a Shared Commons Entry

Suppose you have multiple entry files and *each* requires ``jquery``. In this
case, *each* output file will contain jQuery, slowing down your user's experience.
In this case, you can *extract* these common libraries to a "shared" entry file
that's included on every page:
To solve this, you can *extract* the common libraries to a "shared" entry file
that's included on every page.

.. code-block:: javascript
Suppose you already have an entry called ``app`` that's included on every page.
Update your code to use ``createSharedEntry()``:

.. code-block:: diff

Encore
// ...
.addEntry('page1', 'assets/js/page1.js')
.addEntry('page2', 'assets/js/page2.js')

// this creates a 'vendor.js' file with jquery and the bootstrap JS module
// these modules will *not* be included in page1.js or page2.js anymore
.createSharedEntry('vendor', [
'jquery',
'bootstrap',

// you can also extract CSS - this will create a 'vendor.css' file
// this CSS will *not* be included in page1.css or page2.css anymore
'bootstrap/scss/bootstrap.scss'
])
- .addEntry('app', 'assets/js/app.js')
+ .createSharedEntry('app', 'assets/js/app.js')
.addEntry('homepage', './assets/js/homepage.js')
.addEntry('blog', './assets/js/blog.js')
.addEntry('store', './assets/js/store.js')

As soon as you make this change, you need to include two extra JavaScript files
on your page before any other JavaScript file:
As soon as you make this change, you need to include *one* extra JavaScript file
in your layout, *before* ``app.js``:

.. _encore-shared-entry-script:

.. code-block:: twig

<!-- these two files now must be included in every page -->
{# templates/base.html.twig #}
<!-- these two files now must be included on every page -->
<script src="{{ asset('build/manifest.js') }}"></script>
<script src="{{ asset('build/vendor.js') }}"></script>

<!-- here you link to the specific JS files needed by the current page -->
<script src="{{ asset('build/app.js') }}"></script>

<!-- if you extracted some CSS, include vendor.css -->
<link rel="stylesheet" href="{{ asset('build/vendor.css') }}" />
<!-- you can still include page-specific JavaScript, like normal -->
<script src="{{ asset('build/store.js') }}"></script>

<!-- continue including app.css on every page -->
<link rel="stylesheet" href="{{ asset('build/app.css') }}" />

Before making this change, if both ``app.js`` and ``store.js`` require ``jquery``,
then ``jquery`` would be packaged into *both* files, which is wasteful. By making
``app.js`` your "shard" entry, *any* code required by ``app.js`` (like jQuery) will
*no longer* be packaged into any other files. The same is true for any CSS.

The ``vendor.js`` file contains all the common code that has been extracted from
the other files, so it's obvious that it must be included. The other file (``manifest.js``)
is less obvious: it's needed so that Webpack knows how to load those shared modules.
Because ``app.js`` contains all the common code that other entry files depend on,
it's obvious that its script (and link) tag must be on every page. The other file
(``manifest.js``) is less obvious: it's needed so that Webpack knows how to load
these shared modules.

.. tip::

The ``vendor.js`` file works best when its contents are changed *rarely*
The ``app.js`` file works best when its contents are changed *rarely*
and you're using :ref:`long-term caching <encore-long-term-caching>`. Why?
If ``vendor.js`` contains application code that *frequently* changes, then
If ``app.js`` contains application code that *frequently* changes, then
(when using versioning), its filename hash will frequently change. This means
your users won't enjoy the benefits of long-term caching for this file (which
is generally quite large).
Loading