Skip to content

Webpack setup guide

George Bateman edited this page Mar 4, 2019 · 9 revisions

Webpack Encore is used to process (and minify for production use) JS and CSS files. It is a relatively thin wrapper around Webpack, a widely used system for packaging frontend assets.

JS files are compacted down to two files (vendor.js for rarely-changing external deps and app.js for Camdram code). SCSS is used for stylesheets, which is compiled down to one CSS file.

Folder structure

The development versions of JS an SCSS assets are checked into the assets/ folder of the repository.

Compiled JS and CSS files are served from web/build, which is not checked in. Webpack is used to create this folder.

Webpack Encore also outputs web/build/manifest.json, which is a map from JS/CSS file paths used in Twig templates (e.g. build/app.js) to actual filenames, which contain cache-busting extensions (e.g. build/app.6da44bae.js). Symfony will throw an error if this file is not present.

Download pre-built assets

If you are only making backend changes (i.e. not making changes to the assets/ directory), then you can run the command below to download minified assets from https://development.camdram.net/:

$ php app/console camdram:assets:download

This avoids the need to set up a Node.js toolchain locally if the assets from HEAD of master are sufficient. The command first downloads https://development.camdram.net/build/manifest.json (see above) to determine which files to download.

Set up Webpack toolchain

Node.js and the Yarn package manager are required to build assets.

Unfortunately, the Node.js version in most package managers is insufficient, so we recommend installing the latest NodeJS LTS version (10.x at the time of writing) using the instructions at https://nodejs.org/en/download/package-manager for your distro.

Yarn installation instructions can be found at https://yarnpkg.com/lang/en/docs/install/.

Once these are both installed, run the following to download the necessary Node.js modules to node_modules/:

$ yarn install

Development use

Run the following command to generate assets for development:

$ yarn dev

If you are making frequent changes, it is more convenient to run the following, which automatically triggers a recompile when you make changes, and triggers a system notification on a compilation error:

$ yarn dev --watch

Both the above also output source-maps back the original files in assets/ for easier debugging.

Production build

Run the following command to generate minified assets for production use:

$ yarn build

Javascript routing information

The FOSJSRoutingBundle is used to expose Symfony route names to Javascript to avoid duplication of URL information. This requires the file assets/js/fos_js_routes.json to be present for the Webpack build, which is generated by Symfony.

The commands above include a hook to automatically trigger Symfony to regenerate this prior to the build, but it can also be run manually using:

$ yarn js-routing

Content Security Policy

Camdram has a content security policy that forbids inline scripts, unless they have been previously noted to exist in the app/Resources/views directory wrapped in special comment tags like:

<script>
{#- begin-CSP-permitted-script -#}
// ...
{#- end-CSP-permitted-script -#}
</script>

Whitespace around the comment tags is fine. What is not fine is:

<script>
{#- begin-CSP-permitted-script -#}
document.write("{{some variable}}");
{#- end-CSP-permitted-script -#}
</script>

as there is now variable user content in the script, so the hash of the source code on the server is not the hash of the script that gets delivered to the client. This is managed by the Python script ./gen-csp-hashes.py. Webpack is configured to automatically run this as part of yarn dev and yarn build, although to save on compile time you can run it directly.

The policy can be effectively disabled with:

echo -n "'unsafe-inline'" > web/build/csp_hashes.txt

to speed up development; this persists until you next run yarn or ./gen-csp-hashes.py.