Skip to content

Commit 09af3fe

Browse files
committed
Merge branch '3.4' into 4.1
* 3.4: adding a small entry about ajax code splitting fixing build errors Documenting copyFiles() and a few small things finishing read-through more work on encore Adding docs for runtime.js and fixed a few other things documenting the new split chunks and Twig helper functions for Encore
2 parents 44aa31e + 637be9f commit 09af3fe

23 files changed

+572
-365
lines changed

frontend.rst

+4-1
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,18 @@ Adding more Features
4848
* :doc:`PostCSS and autoprefixing </frontend/encore/postcss>`
4949
* :doc:`Enabling React.js </frontend/encore/reactjs>`
5050
* :doc:`Enabling Vue.js (vue-loader) </frontend/encore/vuejs>`
51+
* :doc:`/frontend/encore/copy-files`
5152
* :doc:`Configuring Babel </frontend/encore/babel>`
5253
* :doc:`Source maps </frontend/encore/sourcemaps>`
5354
* :doc:`Enabling TypeScript (ts-loader) </frontend/encore/typescript>`
5455

5556
Optimizing
5657
..........
5758

58-
* :doc:`Versioning (and the manifest.json file) </frontend/encore/versioning>`
59+
* :doc:`Versioning (and the entrypoints.json/manifest.json files) </frontend/encore/versioning>`
5960
* :doc:`Using a CDN </frontend/encore/cdn>`
61+
* :doc:`/frontend/encore/code-splitting`
62+
* :doc:`/frontend/encore/split-chunks`
6063
* :doc:`Creating a "Shared" entry for re-used modules </frontend/encore/shared-entry>`
6164
* :doc:`/frontend/encore/url-loader`
6265

frontend/encore/babel.rst

+27-21
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ Configuring Babel
22
=================
33

44
`Babel`_ is automatically configured for all ``.js`` and ``.jsx`` files via the
5-
``babel-loader`` with sensible defaults (e.g. with the ``env`` preset and
6-
``react`` if requested).
5+
``babel-loader`` with sensible defaults (e.g. with the ``@babel/preset-env`` and
6+
``@babel/preset-react`` if requested).
77

88
Need to extend the Babel configuration further? The easiest way is via
99
``configureBabel()``:
@@ -16,17 +16,37 @@ Need to extend the Babel configuration further? The easiest way is via
1616
Encore
1717
// ...
1818
19-
// first, install any presets you want to use (e.g. yarn add babel-preset-es2017)
20-
// then, modify the default Babel configuration
2119
.configureBabel(function(babelConfig) {
2220
// add additional presets
23-
babelConfig.presets.push('es2017');
21+
// babelConfig.presets.push('@babel/preset-flow');
2422
2523
// no plugins are added by default, but you can add some
2624
// babelConfig.plugins.push('styled-jsx/babel');
25+
}, {
26+
// node_modules is not processed through Babel by default
27+
// but you can whitelist specific modules to process
28+
// include_node_modules: ['foundation-sites']
29+
30+
// or completely control the exclude
31+
// exclude: /bower_components/
2732
})
2833
;
2934
35+
Configuring Browser Targets
36+
---------------------------
37+
38+
The ``@babel/preset-env`` preset rewrites your JavaScript so that the final syntax
39+
will work in whatever browsers you want. To configure the browsers that you need
40+
to support, see :ref:`browserslist_package_config`.
41+
42+
After change our "browerslist" config, you will need to manually remove the babel
43+
cache directory:
44+
45+
.. code-block:: terminal
46+
47+
$ On Unix run this command. On Windows, clear this directory manually
48+
$ rm -rf node_modules/.cache/babel-loader/
49+
3050
Creating a .babelrc File
3151
------------------------
3252

@@ -37,21 +57,7 @@ Babel, but it has a downside: as soon as a ``.babelrc`` file is present,
3757
if you call ``Encore.enableReactPreset()``, the ``react`` preset will *not*
3858
automatically be added to Babel: you must add it yourself in ``.babelrc``.
3959

40-
An example ``.babelrc`` file might look like this:
41-
42-
.. code-block:: json
43-
44-
{
45-
presets: [
46-
['env', {
47-
modules: false,
48-
targets: {
49-
browsers: '> 1%',
50-
uglify: true
51-
},
52-
useBuiltIns: true
53-
}]
54-
]
55-
}
60+
As soon as a ``.babelrc`` file is present, it will take priority over the Babel
61+
configuration added by Encore.
5662

5763
.. _`Babel`: http://babeljs.io/

frontend/encore/bootstrap.rst

+11-18
Original file line numberDiff line numberDiff line change
@@ -41,29 +41,17 @@ Bootstrap JavaScript requires jQuery and Popper.js, so make sure you have this i
4141

4242
.. code-block:: terminal
4343
44-
$ yarn add jquery --dev
45-
$ yarn add popper.js --dev
44+
$ yarn add jquery popper.js --dev
4645
47-
Next, make sure to call ``.autoProvidejQuery()`` in your ``webpack.config.js`` file:
48-
49-
.. code-block:: diff
50-
51-
// webpack.config.js
52-
Encore
53-
// ...
54-
+ .autoProvidejQuery()
55-
;
56-
57-
This is needed because Bootstrap expects jQuery to be available as a global
58-
variable. Now, require bootstrap from any of your JavaScript files:
46+
Now, require bootstrap from any of your JavaScript files:
5947

6048
.. code-block:: javascript
6149
6250
// app.js
6351
6452
const $ = require('jquery');
65-
// JS is equivalent to the normal "bootstrap" package
66-
// no need to set this to a variable, just require it
53+
// this "modifies" the jquery module: adding behavior to it
54+
// the bootstrap module doesn't export/return anything
6755
require('bootstrap');
6856
6957
// or you can include specific pieces
@@ -74,8 +62,13 @@ variable. Now, require bootstrap from any of your JavaScript files:
7462
$('[data-toggle="popover"]').popover();
7563
});
7664
77-
Thanks to ``autoProvidejQuery()``, you can require any other jQuery
78-
plugins in a similar way:
65+
Using other Bootstrap / jQuery Plugins
66+
--------------------------------------
67+
68+
If you need to use jQuery plugins that work well with jQuery, you may need to use
69+
Encore's :ref:`autoProvidejQuery() <encore-autoprovide-jquery>` method so that
70+
these plugins know where to find jQuery. Then, you can include the needed JavaScript
71+
and CSS like normal:
7972

8073
.. code-block:: javascript
8174

frontend/encore/cdn.rst

+3-9
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,6 @@ e.g. ``https://my-cool-app.com.global.prod.fastly.net/dashboard.js``.
3636
directly from your web server.
3737

3838
You *do* need to make sure that the ``script`` and ``link`` tags you include on your
39-
pages also use the CDN. Fortunately, the ``manifest.json`` paths are updated to
40-
point to the CDN. In Symfony, as long as you've configured
41-
:doc:`Asset Versioning </frontend/encore/versioning>`, you're done! The ``manifest.json``
42-
file includes the full CDN URL:
43-
44-
.. code-block:: twig
45-
46-
{# Your script/link tags don't need to change at all to support the CDN #}
47-
<script src="{{ asset('build/dashboard.js') }}"></script>
39+
pages also use the CDN. Fortunately, the
40+
:ref:`entrypoints.json <encore-entrypointsjson-simple-description>` paths are updated
41+
to include the full URL to the CDN.

frontend/encore/code-splitting.rst

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
Async Code Splitting
2+
====================
3+
4+
When you require/import a JavaScript or CSS module, Webpack compiles that code into
5+
the final JavaScript or CSS file. Usually, that's exactly what you want. But what
6+
if you only need to use a piece of code under certain conditions? For example,
7+
what if you want to use `video.js`_ to play a video, but only once a user has
8+
clicked a link:
9+
10+
.. code-block:: javascript
11+
12+
// assets/js/app.js
13+
14+
import $ from 'jquery';
15+
// a fictional "large" module (e.g. it imports video.js internally)
16+
import VideoPlayer from './components/VideoPlayer';
17+
18+
$('.js-open-video').on('click', function() {
19+
// use the larger VideoPlayer module
20+
const player = new VideoPlayer('some-element');
21+
});
22+
23+
In this example, the VidePlayer module and everything it imports will be packaged
24+
into the final, built JavaScript file, even though it may not be very common for
25+
someone to actually need it. A better solution is to use `dynamic imports`_: load
26+
the code via AJAX when it's needed:
27+
28+
.. code-block:: javascript
29+
30+
// assets/js/app.js
31+
32+
import $ from 'jquery';
33+
34+
$('.js-open-video').on('click', function() {
35+
// you could start a loading animation here
36+
37+
// use import() as a function - it returns a Promise
38+
import('./components/VideoPlayer').then(({ default: VideoPlayer }) => {
39+
// you could stop a loading animation here
40+
41+
// use the larger VideoPlayer module
42+
const player = new VideoPlayer('some-element');
43+
44+
}).catch(error => 'An error occurred while loading the component');
45+
});
46+
47+
By using ``import()`` like a function, the module will be downloaded async and
48+
the ``.then()`` callback will be executed when it's finished. The ``VideoPlayer``
49+
argument to the callback will be the loaded module. In other words, it works like
50+
normal AJAX calls! Behind the scenes, Webpack will package the ``VideoPlayer`` module
51+
into a separate file (e.g. ``0.js``) so it can be downloaded. All the details are
52+
handled for you.
53+
54+
The ``{ default: VideoPlayer }`` part may look strange. When using the async
55+
import, your ``.then()`` callback is passed an object, where the *actual* module
56+
is on a ``.default`` key. There are reasons why this is done, but it does look
57+
quirky. The ``{ default: VideoPlayer }`` code makes sure that the ``VideoPlayer``
58+
module we want is read from this ``.default`` property.
59+
60+
For more details and configuration options, see `dynamic imports`_ on Webpack's
61+
documentation.
62+
63+
.. _`video.js`: https://videojs.com/
64+
.. _`dynamic imports`: https://webpack.js.org/guides/code-splitting/#dynamic-imports

frontend/encore/copy-files.rst

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
Copying & Referencing Images
2+
============================
3+
4+
Need to reference a static file - like the path to an image for an ``img`` tag?
5+
That can be tricky if you store your assets outside of the public document root.
6+
Fortunately, depending on your situation, there is a solution!
7+
8+
Referencing Images from Inside a Webpacked JavaScript File
9+
----------------------------------------------------------
10+
11+
To reference an image tag from inside a JavaScript file, *require* the file:
12+
13+
.. code-block:: javascript
14+
15+
// assets/js/app.js
16+
17+
// returns the final, public path to this file
18+
// path is relative to this file - e.g. assets/images/logo.png
19+
const logoPath = require('../images/logo.png');
20+
21+
var html = `<img src="${logoPath}">`;
22+
23+
When you ``require`` (or ``import``) an image file, Webpack copies it into your
24+
output directory and returns the final, *public* path to that file.
25+
26+
Referencing Image files from a Template
27+
---------------------------------------
28+
29+
To reference an image file from outside of a JavaScript file that's processed by
30+
Webpack - like a template - you can use the ``copyFiles()`` method to copy those
31+
files into your final output directory.
32+
33+
.. code-block:: diff
34+
35+
// webpack.config.js
36+
37+
Encore
38+
// ...
39+
.setOutputPath('web/build/')
40+
41+
+ .copyFiles({
42+
+ from: './assets/images',
43+
+
44+
+ // optional target path, relative to the output dir
45+
+ //to: 'images/[path][name].[ext]',
46+
+
47+
+ // only copy files matching this pattern
48+
+ //pattern: /\.(png|jpg|jpeg)$/
49+
+ })
50+
51+
This will copy all files from ``assets/images`` into ``web/build`` (the output
52+
path). If you have :doc:`versioning enabled <versioning>`, the copied files will
53+
include a hash based on their content.
54+
55+
To render inside Twig, use the ``asset()`` function:
56+
57+
{# assets/images/logo.png was copied to web/build/logo.png #}
58+
<img src="{{ asset('build/logo.png') }}"
59+
60+
{# assets/images/subdir/logo.png was copied to web/build/subdir/logo.png #}
61+
<img src="{{ asset('build/subdir/logo.png') }}"
62+
63+
Make sure you've enabled the :ref:`json_manifest_path <load-manifest-files>` option,
64+
which tells the ``asset()`` function to read the final paths from the ``manifest.json``
65+
file. If you're not sure what path argument to pass to the ``asset()`` function,
66+
find the file in ``manifest.json`` and use the *key* as the argument.

frontend/encore/css-preprocessors.rst

+16-60
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,7 @@
1-
CSS Preprocessors: Sass, LESS, etc.
2-
===================================
1+
CSS Preprocessors: Sass, LESS, Stylus, etc.
2+
===========================================
33

4-
Using Sass
5-
----------
6-
7-
To use the Sass pre-processor, install the dependencies:
8-
9-
.. code-block:: terminal
10-
11-
$ yarn add --dev sass-loader node-sass
12-
13-
And enable it in ``webpack.config.js``:
14-
15-
.. code-block:: javascript
16-
17-
// webpack.config.js
18-
// ...
19-
20-
Encore
21-
// ...
22-
.enableSassLoader()
23-
;
24-
25-
That's it! All files ending in ``.sass`` or ``.scss`` will be pre-processed. You
26-
can also pass options to ``sass-loader``:
4+
To use the Sass, LESS or Stylus pre-processors, enable the one you want in ``webpack.config.js``:
275

286
.. code-block:: javascript
297
@@ -32,46 +10,24 @@ can also pass options to ``sass-loader``:
3210
3311
Encore
3412
// ...
35-
.enableSassLoader(function(options) {
36-
// https://github.com/sass/node-sass#options
37-
// options.includePaths = [...]
38-
});
39-
;
40-
41-
Using LESS
42-
----------
43-
44-
To use the LESS pre-processor, install the dependencies:
4513
46-
.. code-block:: terminal
14+
// enable just the one you want
4715
48-
$ yarn add --dev less-loader less
49-
50-
And enable it in ``webpack.config.js``:
51-
52-
.. code-block:: javascript
53-
54-
// webpack.config.js
55-
// ...
16+
// processes files ending in .scss or .sass
17+
.enableSassLoader()
5618
57-
Encore
58-
// ...
19+
// processes files ending in .less
5920
.enableLessLoader()
60-
;
6121
62-
That's it! All files ending in ``.less`` will be pre-processed. You can also pass
63-
options to ``less-loader``:
22+
// processes files ending in .styl
23+
.enableStylusLoader()
24+
;
6425
65-
.. code-block:: javascript
26+
Then restart Encore. When you do, it will give you a command you can run to
27+
install any missing dependencies. After running that command and restarting
28+
Encore, you're done!
6629

67-
// webpack.config.js
68-
// ...
30+
You can also pass configuration options to each of the loaders. See the
31+
`Encore's index.js file`_ for detailed documentation.
6932

70-
Encore
71-
// ...
72-
.enableLessLoader(function(options) {
73-
// https://github.com/webpack-contrib/less-loader#examples
74-
// http://lesscss.org/usage/#command-line-usage-options
75-
// options.relativeUrls = false;
76-
});
77-
;
33+
.. _`Encore's index.js file`: https://github.com/symfony/webpack-encore/blob/master/index.js

0 commit comments

Comments
 (0)