Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Your First Webpack

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

Since the require() key doesn't work in a browser:

... lines 1 - 2
const Helper = require('./RepLogHelper');
... lines 4 - 217

We're going to use Webpack to... pack it all together! Let's jump straight in to see how it works!

Installing webpack

In the last tutorial, we installed Babel:

13 lines package.json
{
... lines 2 - 7
"devDependencies": {
"babel-cli": "^6.22.2",
"babel-preset-env": "^1.1.8"
}
}

We're going to use Babel again. But for now, let's remove it. In your terminal, run yarn remove babel-cli then babel-preset-env:

yarn remove babel-cli babel-preset-env

After this, we have absolutely nothing in our app: package.json is empty:

10 lines package.json
{
... lines 2 - 7
"devDependencies": {}
}

And so is node_modules/. We're starting from scratch.

Now, add webpack:

yarn add webpack@3 --dev

Tip

This tutorial uses Webpack v3, so please double check that you install that version. If you do want to use Webpack 4 or higher, we've done our best to add tips throughout the tutorial to help you. If you're installing Webpack 4 (or higher), you also need to install webpack-cli:

yarn add webpack webpack-cli --dev

As it's downloading, let's talk strategy. Webpack is an executable, and we will point it at RepLogApp.js. Webpack is amazing because it will actually read the require() call inside that:

... lines 1 - 2
const Helper = require('./RepLogHelper');
... lines 4 - 217

Open RepLogAppHelper.js, and finally dump one big file with both modules inside. Yes, this means we will get to use the require() function and our browser will still get one, streamlined, simple, beautiful JS file.

Create a new directory in web/ called build/: we'll put our finished file here.

Running webpack

Back in our terminal, awesome! Yarn finished its work... and now node_modules/ is filled with goodies. To run Webpack, use ./node_modules/.bin/webpack. This needs 2 arguments: the input file - so web/assets/RepLogApp.js - and the output file - web/build/rep_log.js - a different filename to avoid confusion.

Deep breath. Run webpack:

./node_modules/.bin/webpack web/assets/js/RepLogApp.js web/build/rep_log.js

Tip

If you are using Webpack 4 or higher, add the --mode and -o options:

./node_modules/.bin/webpack web/assets/js/RepLogApp.js -o web/build/rep_log.js --mode development

Yes! No errors... and it looks like it did something. Check the web/build directory... we do have a rep_log.js file. In index.html.twig, update the script src to point here: build/rep_log.js:

... lines 1 - 53
{% block javascripts %}
... lines 55 - 57
<script src="{{ asset('build/rep_log.js') }}"></script>
... lines 59 - 65
{% endblock %}

Now, refresh! Everything works! Holy cats Batman! We just unlocked the require() function for front-end JavaScript. Game. Changer.

Checking out the Compiled File

Check out the compiled file. Webpack adds some bootstrap code at the top: this helps it do its job internally. Then, below that, you see our code: RepLogApp first and then, the Helper class.

Yep, webpack, um, packs all our modules into one file. Well, it's actually much, much more powerful than that. But this is already huge.

Ignore the build Directory

Now, the build/ directory is not something we need to commit to the repository: we can always rebuild this file whenever we need to. So, in .gitignore, ignore it: /web/build/*:

19 lines .gitignore
... lines 1 - 17
/web/build/*

Next, we'll create the all-important webpack.config.js file: they key to unlocking Webpack's full potential.

Leave a comment!

4
Login or Register to join the conversation
David P. Avatar
David P. Avatar David P. | posted 5 years ago | edited

Somewhere between this tutorial and Webpack V4.2.0, the webpack CLI was extracted into a separate package:

<blockquote>The CLI moved into a separate package: webpack-cli.
Please install 'webpack-cli' in addition to webpack itself to use the CLI.
-> When using npm: npm install webpack-cli -D
-> When using yarn: yarn add webpack-cli -D</blockquote>

It also appears the V4 wants the -o switch before the output file name.

And, If you don't have a webpack.config.js file with a

module.exports = {
    "mode": "development" // (or "production")

webpack will throw a warning about the mode not being defined.

You might want to add a note about these things.
Thanks!

2 Reply
Galen S. Avatar

Thank you for this. Can confirm this fixes the errors/warnings I was seeing after installing webpack and attempting to run the first webpack build command.

For anyone else searching, it fixed the following error:

ERROR in multi ./web/assets/js/RepLogApp.js web/build/rep_log.js
Module not found: Error: Can't resolve 'web/build/rep_log.js' in '/home/user/git/js'
@ multi ./web/assets/js/RepLogApp.js web/build/rep_log.js main[1]

1 Reply

./node_modules/.bin/webpack web/assets/RepLogApp.js web/build/rep_log.js

is invalid path.

Correct is


./node_modules/.bin/webpack web/assets/js/RepLogApp.js web/build/rep_log.js
Reply

Hey Сергей Бевзенко

Thanks for informing us! I already fixed it :)

Have a nice day

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial explains the concepts of an old version of Webpack using an old version of Symfony. The most important concepts are still the same, but you should expect significant differences in new versions.

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.2.0",
        "symfony/symfony": "3.3.*", // v3.3.16
        "twig/twig": "2.10.*", // v2.10.0
        "doctrine/orm": "^2.5", // v2.7.0
        "doctrine/doctrine-bundle": "^1.6", // 1.10.3
        "doctrine/doctrine-cache-bundle": "^1.2", // 1.3.5
        "symfony/swiftmailer-bundle": "^2.3", // v2.6.3
        "symfony/monolog-bundle": "^2.8", // v2.12.1
        "symfony/polyfill-apcu": "^1.0", // v1.4.0
        "sensio/distribution-bundle": "^5.0", // v5.0.22
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.26
        "incenteev/composer-parameter-handler": "^2.0", // v2.1.2
        "friendsofsymfony/user-bundle": "^2.0", // v2.1.2
        "doctrine/doctrine-fixtures-bundle": "~2.3", // v2.4.1
        "doctrine/doctrine-migrations-bundle": "^1.2", // v1.3.2
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "friendsofsymfony/jsrouting-bundle": "^1.6" // 1.6.0
    },
    "require-dev": {
        "sensio/generator-bundle": "^3.0", // v3.1.6
        "symfony/phpunit-bridge": "^3.0" // v3.3.5
    }
}

What JavaScript libraries does this tutorial use?

// package.json
{
    "dependencies": [],
    "devDependencies": {
        "babel-core": "^6.25.0", // 6.25.0
        "babel-loader": "^7.1.1", // 7.1.1
        "babel-plugin-syntax-dynamic-import": "^6.18.0", // 6.18.0
        "babel-preset-env": "^1.6.0", // 1.6.0
        "bootstrap-sass": "^3.3.7", // 3.3.7
        "clean-webpack-plugin": "^0.1.16", // 0.1.16
        "copy-webpack-plugin": "^4.0.1", // 4.0.1
        "core-js": "^2.4.1", // 2.4.1
        "css-loader": "^0.28.4", // 0.28.4
        "extract-text-webpack-plugin": "^3.0.0", // 3.0.0
        "file-loader": "^0.11.2", // 0.11.2
        "font-awesome": "^4.7.0", // 4.7.0
        "jquery": "^3.2.1", // 3.2.1
        "lodash": "^4.17.4", // 4.17.4
        "node-sass": "^4.5.3", // 4.5.3
        "resolve-url-loader": "^2.1.0", // 2.1.0
        "sass-loader": "^6.0.6", // 6.0.6
        "style-loader": "^0.18.2", // 0.18.2
        "sweetalert2": "^6.6.6", // 6.6.6
        "webpack": "^3.4.1", // 3.4.1
        "webpack-chunk-hash": "^0.4.0", // 0.4.0
        "webpack-dev-server": "^2.6.1", // 2.6.1
        "webpack-manifest-plugin": "^1.2.1" // 1.2.1
    }
}
userVoice