diff --git a/frontend/encore/advanced-config.rst b/frontend/encore/advanced-config.rst
index e66440ac43f..74b11d559dd 100644
--- a/frontend/encore/advanced-config.rst
+++ b/frontend/encore/advanced-config.rst
@@ -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
diff --git a/frontend/encore/installation-no-flex.rst b/frontend/encore/installation-no-flex.rst
new file mode 100644
index 00000000000..c495ebdc968
--- /dev/null
+++ b/frontend/encore/installation-no-flex.rst
@@ -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/
diff --git a/frontend/encore/installation.rst b/frontend/encore/installation.rst
index e0e13882d16..31bce801ea6 100644
--- a/frontend/encore/installation.rst
+++ b/frontend/encore/installation.rst
@@ -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/
diff --git a/frontend/encore/shared-entry.rst b/frontend/encore/shared-entry.rst
index 1eacdb76261..6958a331f43 100644
--- a/frontend/encore/shared-entry.rst
+++ b/frontend/encore/shared-entry.rst
@@ -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
-
+ {# templates/base.html.twig #}
+
-
-
-
-
-
+
+
+
+
+
+
+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 `. 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).
diff --git a/frontend/encore/simple-example.rst b/frontend/encore/simple-example.rst
index 38a3a06cd9e..609e095cc75 100644
--- a/frontend/encore/simple-example.rst
+++ b/frontend/encore/simple-example.rst
@@ -1,30 +1,38 @@
-First Example
-=============
+Encore: Setting up your Project
+===============================
-Imagine you have a simple project with one CSS and one JS file, organized into
-an ``assets/`` directory:
+After :doc:`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, you should think of CSS as a *dependency* of your JavaScript. This means,
-you will *require* whatever CSS you need from inside JavaScript:
+With Encore, think of your ``app.js`` file as a standalone JavaScript
+application: it will *require* all of the dependencies it needs (e.g. jQuery),
+*including* any CSS. Your ``app.js`` file is already doing this with a special
+``require`` function:
.. code-block:: javascript
// assets/js/app.js
+ // ...
+
+ // var $ = require('jquery');
+
require('../css/app.css');
- // ...rest of JavaScript code here
+ // ... the rest of your JavaScript...
-With Encore, we can easily minify these files, pre-process ``app.css``
-through PostCSS and a *lot* more.
+Encore's job is simple: to read *all* of ``require`` statements and create one
+final ``app.js`` (and ``app.css``) that contain *everything* your app needs. Of
+course, Encore can do a lot more: minify files, pre-process Sass/LESS, support
+React, Vue.js and a *lot* more.
Configuring Encore/Webpack
--------------------------
-Create a new file called ``webpack.config.js`` at the root of your project.
-Inside, use Encore to help generate your Webpack configuration.
+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:
.. code-block:: javascript
@@ -32,71 +40,49 @@ Inside, use Encore to help generate your Webpack configuration.
var Encore = require('@symfony/webpack-encore');
Encore
- // the project directory where all compiled assets will be stored
+ // directory where compiled assets will be stored
.setOutputPath('web/build/')
-
- // the public path used by the web server to access the previous directory
+ // public path used by the web server to access the output path
.setPublicPath('/build')
- // will create web/build/app.js and web/build/app.css
.addEntry('app', './assets/js/app.js')
- // allow legacy applications to use $/jQuery as a global variable
- .autoProvidejQuery()
-
- // enable source maps during development
- .enableSourceMaps(!Encore.isProduction())
-
- // empty the outputPath dir before each build
- .cleanupOutputBeforeBuild()
-
- // show OS notifications when builds finish/fail
- .enableBuildNotifications()
-
- // create hashed filenames (e.g. app.abc123.css)
- // .enableVersioning()
-
- // allow sass/scss files to be processed
- // .enableSassLoader()
+ // ...
;
- // export the final configuration
- module.exports = Encore.getWebpackConfig();
+ // ...
-This is already a rich setup: it outputs 2 files and enables source maps
-to help debugging.
+They *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 ``public/build`` directory.
.. _encore-build-assets:
-To build the assets, use the ``encore`` executable:
+To build the assets, run:
.. code-block:: terminal
# compile assets once
- $ ./node_modules/.bin/encore dev
+ $ yarn encore dev
- # recompile assets automatically when files change
- $ ./node_modules/.bin/encore dev --watch
+ # or, recompile assets automatically when files change
+ $ yarn encore dev --watch
- # compile assets, but also minify & optimize them
- $ ./node_modules/.bin/encore production
-
- # shorter version of the above 3 commands
- $ yarn run encore dev
- $ yarn run encore dev --watch
- $ yarn run encore production
+ # on deploy, create a production build
+ $ yarn encore production
.. note::
- Re-run ``encore`` each time you update your ``webpack.config.js`` file.
+ Stop and restart ``encore`` each time you update your ``webpack.config.js`` file.
-After running one of these commands, you can now add ``script`` and ``link`` tags
-to the new, compiled assets (e.g. ``/build/app.css`` and ``/build/app.js``).
-In Symfony, use the ``asset()`` helper:
+Congrats! You now have two new files! Next, add a ``script`` and ``link`` tag
+to the new, compiled assets (e.g. ``/build/app.css`` and ``/build/app.js``) to
+your layout. In Symfony, use the ``asset()`` helper:
.. code-block:: twig
- {# base.html.twig #}
+ {# templates/base.html.twig #}
@@ -109,34 +95,6 @@ In Symfony, use the ``asset()`` helper:
-Using Sass
-----------
-
-Instead of using plain CSS you can also use Sass. In order to do so, change the
-extension of the ``app.css`` file to ``.sass`` or ``.scss`` (based on the syntax
-you want to use):
-
-.. code-block:: diff
-
- // assets/js/app.js
- - require('../css/app.css');
- + require('../css/app.scss');
-
-And enable the Sass pre-processor:
-
-.. code-block:: diff
-
- // webpack.config.js
- Encore
- // ...
-
- // allow sass/scss files to be processed
- - // .enableSassLoader()
- + .enableSassLoader()
-
-Using ``enableSassLoader()`` requires to install additional packages, but Encore
-will tell you *exactly* which ones when running it.
-
Requiring JavaScript Modules
----------------------------
@@ -163,7 +121,7 @@ Great! Use ``require()`` to import ``jquery`` and ``greet.js``:
// assets/js/app.js
// loads the jquery package from node_modules
- const $ = require('jquery');
+ var $ = require('jquery');
// import the function from greet.js (the .js extension is optional)
// ./ (or ../) means to look for a local file
@@ -174,30 +132,116 @@ Great! Use ``require()`` to import ``jquery`` and ``greet.js``:
});
That's it! When you build your assets, jQuery and ``greet.js`` will automatically
-be added to the output file (``app.js``). For common libraries like jQuery, you
-may want to :doc:`create a shared entry ` for better
-performance.
+be added to the output file (``app.js``).
+
+The import and export Statements
+--------------------------------
-Multiple JavaScript Entries
----------------------------
+Instead of using ``require`` and ``module.exports`` like shown above, JavaScript
+has an alternate syntax, which is a more accepted standard. Choose whichever you
+want: they function identically:
-The previous example is the best way to deal with SPA (Single Page Applications)
-and very simple applications. However, as your app grows, you may want to have
-page-specific JavaScript or CSS (e.g. homepage, blog, store, etc.). To handle this,
-add a new "entry" for each page that needs custom JavaScript or CSS:
+To export values, use ``exports``:
+
+.. code-block:: diff
+
+ // assets/js/greet.js
+ - module.exports = function(name) {
+ + export default function(name) {
+ return `Yo yo ${name} - welcome to Encore!`;
+ };
+
+To import values, use ``import``:
+
+.. code-block:: diff
+
+ // assets/js/app.js
+ - var $ = require('jquery');
+ + import $ from 'jquery';
+
+ - require('../css/app.css');
+ + import '../css/app.css';
+
+.. _multiple-javascript-entries:
+
+Page-Specific JavaScript or CSS (Multiple Entries)
+--------------------------------------------------
+
+So far, you only have one final JavaScript file: ``app.js``. For simple apps 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. homepage, blog, store,
+etc.). To handle this, add a new "entry" for each page that needs custom JavaScript
+or CSS:
+
+.. code-block:: diff
+
+ Encore
+ // ...
+ .addEntry('app', './assets/js/app.js')
+ + .addEntry('homepage', './assets/js/homepage.js')
+ + .addEntry('blog', './assets/js/blog.js')
+ + .addEntry('store', './assets/js/store.js')
+ // ...
+
+Encore will now render new ``homepage.js``, ``blog.js`` and ``store.js`` files.
+Add a ``script`` tag to each of these only on the page where they are needed.
+
+.. tip::
+
+ Remember to restart Encore each time you update your ``webpack.config.js`` file.
+
+If any entry requires CSS/Sass files (e.g. ``homepage.js`` requires
+``assets/css/homepage.scss``), a CSS file will *also* be output (e.g. ``build/homepage.css``).
+Add a ``link`` to the page where that CSS is needed.
+
+To avoid duplicating the same code in different entry files, see
+:doc:`create a shared entry `.
+
+Using Sass
+----------
+
+Instead of using plain CSS you can also use Sass. To use Sass, rename
+the ``app.css`` file to ``app.scss``. Update the ``require`` statement:
+
+.. code-block:: diff
+
+ // assets/js/app.js
+ - require('../css/app.css');
+ + require('../css/app.scss');
+
+Then, tell Encore to enable the Sass pre-processor:
+
+.. code-block:: diff
+
+ // webpack.config.js
+ Encore
+ // ...
+
+ + .enableSassLoader()
+ ;
+
+Using ``enableSassLoader()`` requires to install additional packages, but Encore
+will tell you *exactly* which ones when running it. Encore also supports
+LESS and Stylus. See :doc:`/frontend/encore/css-preprocessors`.
+
+Compiling Only a CSS File
+-------------------------
+
+To compile CSS together, you should generally follow the pattern above: use ``addEntry()``
+to point to a JavaScript file, then require the CSS needed from inside of that.
+However, *if* you want to only compile a CSS file, that's also possible via
+``addStyleEntry()``:
.. code-block:: javascript
+ // webpack/config.js
Encore
// ...
- .addEntry('homepage', './assets/js/homepage.js')
- .addEntry('blog', './assets/js/blog.js')
- .addEntry('store', './assets/js/store.js')
+
+ .addStyleEntry('some_page', './assets/css/some_page.css')
;
-If those entries include CSS/Sass files (e.g. ``homepage.js`` requires
-``assets/css/homepage.scss``), two files will be generated for each:
-(e.g. ``build/homepage.js`` and ``build/homepage.css``).
+This will output a new ``some_page.css``.
Keep Going!
-----------