Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine


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 we programmers are famously lazy, we don't usually run Webpack with all these cumbersome command-line options. Nope, we put them into a configuration file. At the root of your project, create a new webpack.config.js file. If you make a file with exactly this name, Webpack will automatically find it.

And what does this file look like? Oh, you're going to love this: we use, yep module.exports to export a configuration object!

module.exports = {
... lines 2 - 6


If you're using Webpack 4 or higher, add mode key:

// webpack.config.js

module.exports = {
    mode: 'development',

This will tell Webpack you're building in "development" mode. We'll talk about production builds later.

Inside, that config needs two major things. First, an entry key set to ./web/assets/js/RepLogApp.js:

module.exports = {
entry: './web/assets/js/RepLogApp.js',
... lines 3 - 6

Entry is Webpack's name for your input file: the one file it will load. Second, of course, we need to tell Webpack where to create the output. Set this to a hash with path set to the directory: __dirname plus /web/build:

module.exports = {
entry: './web/assets/js/RepLogApp.js',
output: {
path: __dirname+'/web/build',
... line 5

That __dirname is a special variable available inside of Node that points to the directory of this file. Then, add a filename key set to rep_log.js:

module.exports = {
entry: './web/assets/js/RepLogApp.js',
output: {
path: __dirname+'/web/build',
filename: 'rep_log.js',

Now, running Webpack is truly a lazy experience... we should probably lift our cat a few times for exercise. Just run:


And it works exactly like before.

Using the path module

Before we celebrate too much, head to webpack.js.org. Make sure you're here, and not on webpack.github.io - that's the old website for the old version 1 of Webpack. We're using the hipster version 3... and new versions of Webpack tend to come out fast. If there is already a new version when you're going through this tutorial, don't worry too much: there's a good chance the changes are minimal. And we'll add notes otherwise.

Under the main Concepts page, they talk about this configuration file. But check it out: for the output path, they use some path.resolve() thing.

This is a minor detail in Node that I want you guys to see. In Node, you never see path strings concatenated together like this. Nope, to keep things portable between Unix and Windows, you're supposed to call path.resolve() - or a similar function path.join() - to concatenate the path for you.

No big deal! Add path.resolve() passing it __dirname, then web then build:

module.exports = {
... line 2
output: {
path: path.resolve(__dirname, 'web', 'build'),
... line 5

You can pass as many arguments as you want: the args are built into one big path string.

Simple! But... does it work!? Try it:


Ah! An error!

path is not defined

Listen up! This is important: webpack.config.js is executed by Node... and this code will never run in our browser. So since this is a pure Node script, we can use any of the core libraries that you normally have access to, like the path module.

But to get access to it, you need to require it. At the top, add const path = require('path'):

const path = require('path');
module.exports = {
... lines 4 - 8

Now, everything is happy again!

Requiring Core or Vendor Modules

But notice, this is not ./path! The ./ would tell Node to look for a file relative to this file. But when we just say path, Node looks for either a core module inside the language itself called path - which is what happens in this case - or for a module called path inside node_modules. We'll see that very soon.

Making PhpStorm work with Node

Ok, but my editor isn't very happy: when I hover over path, it looks like there's an error:

Node.js coding assistance is disabled

Ok, that sounds like something we can improve! Open up the PhpStorm Preferences, which is Command+, on a Mac. Then, search for Node.js. Ah, there's a section called "Node.js and NPM". Find that "Enable" box and click it! Then hit Ok to exit.

And in a moment, yep! PhpStorm is happy again. And now, we will have auto-complete on core Node features.

Ok, next, we'll teach Webpack to watch for changes... and start installing and requiring vendor libraries - like jQuery - via Yarn.

Leave a comment!

Login or Register to join the conversation
Lijana Z. Avatar
Lijana Z. Avatar Lijana Z. | posted 4 years ago

it looks like other IDEs should have hard time to compete with PHPstorm when tutorials only show how to work with PHPStorm :) But PHPStorm is really good. Just that I still hope there will be competition, because monopoly is bad for customers :)


Hey Lijana Z.!

Yea, it's true! PhpStorm is WAY out in front, in my opinion. But, I would also be ok with competition - if someone can make something as good as PhpStorm, that would be an incredible accomplishment :).


Default user avatar
Default user avatar J.R. Jenkins | posted 4 years ago

if we are using path.resolve() to make the webpack.config.js file platform independent, should we use that when building the entry configuration as well? I don't see that in the example on webpack.js.org, but it seems like we would have to worry about path issues on input as much as output.


Hey J.R. Jenkins!

Ah, very good! I believe the answer is yes: unlike PHP, in Node, the / versus \ DOES make a difference (whereas in PHP you can use / and it'll work on Windows for file paths). So yes, I expect that the / will cause problems on Windows. But, you need to ask whether or not you need the portability. The *real* reason I showed path.resolve() was to talk about path() and requiring core modules. Honestly, I'm not sure why they show path.resolve in some places, but not others - this may help solve some edge-case issue, but I'm not aware of anything.

Anyways, not a completely concrete answer, but hopefully it helps :).


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