Create a new file: webpack.config.js. Here's how Webpack works: we create a config file that tells it which file to load, where to save the final file, and a few other things. Then... it does the rest!

But... Webpack's configuration is complex. A fully-featured setup will probably be a few hundred lines of complicate config! Heck, our Webpack tutorial was over 3 hours long! Very simply: Encore is a tool that helps generate that complex config.

Setting up webpack.config.js

Click on the documentation to find the "First Example". Hey! A webpack.config.js file to get us started! Copy that! Then, paste it in our file. But, I'm going to simplify and delete a few things: we'll add this stuff back later. Just keep setOutputPath(), setPublicPath() and addEntry():

var Encore = require('@symfony/webpack-encore');
Encore
// the project directory where all compiled assets will be stored
.setOutputPath('public/build/')
// the public path used by the web server to access the previous directory
.setPublicPath('/build')
.addEntry('rep_log', './public/assets/js/RepLogApp.js')
;
// export the final configuration
module.exports = Encore.getWebpackConfig();

And hey, check out that first line! Since this file will be executed by Node, we can require stuff! This imports the Encore object:

var Encore = require('@symfony/webpack-encore');
... lines 2 - 15

Then, at the bottom, we ask Encore to give us the final config, and we export it:

... lines 1 - 12
// export the final configuration
module.exports = Encore.getWebpackConfig();

There are only three things we need to tell Webpack: the directory where we want to save the final files - public/build - the public path to that directory - so /build since public/ is the document root - and an "entry":

... lines 1 - 2
Encore
// the project directory where all compiled assets will be stored
.setOutputPath('public/build/')
// the public path used by the web server to access the previous directory
.setPublicPath('/build')
.addEntry('rep_log', './public/assets/js/RepLogApp.js')
;
... lines 12 - 15

Point this to our JavaScript file: ./public/assets/js/RepLogApp.js. Change the first argument to rep_log:

... lines 1 - 2
Encore
... lines 4 - 9
.addEntry('rep_log', './public/assets/js/RepLogApp.js')
;
... lines 12 - 15

This tells Webpack to work its magic on RepLogApp.js. The first argument will be the name of the final file, .js - so rep_log.js.

Running Encore

And... that's it! Find your terminal. Encore has its own executable. To use it, run:

Tip

Wait! Before running encore, first delete the .babelrc file (if you have one). This is left-over from the previous tutorial and is not needed: Encore handles it for us.

./node_modules/.bin/encore dev

The "dev" part tells Encore to create a "development" build. And... cool! Two files written to public/build. Let's check them out! Alright! There's rep_log.js. We'll talk about manifest.json later.

Cool! Let's point our script tag at the new file. Open templates/lift/index.html.twig. This is the template that runs our main page. At the bottom, change the path to build/rep_log.js:

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

If you're not a Symfony user, don't worry, the asset() function isn't doing anything special. Ok, let's try it! Find your browser and, refresh! Woo! It works! People, this is amazing! We can finally organize JavaScript into multiple files and not worry about "forgetting" to add all the script tags we need. The require function is a game-changer!

If you look at the compiled rep_log.js file, you can see a bunch of Webpack code at the top, which helps things work internally - and... below, our code! It's not minimized because this is a development build. We'll talk about production builds later.

Making PhpStorm Happy

If you're using PhpStorm like me, there are a few things we can do to make our life much more awesome. Open Preferences and search for ECMAScript. Under "Languages & Frameworks" -> "JavaScript", make sure that ECMAScript 6 is selected.

Then, search for "Node" and find the "Node.js and NPM" section. Click to "Enable" the Node.js Core library.

And finally, if you're using Symfony, search for Symfony. If you don't see a Symfony section, you should totally download the Symfony plugin - we have some details about this in a different screencast. Make sure it's enabled, and - most importantly - change the web directory to public. This will give auto-completion on the asset function.

Watching for Changes

Back to Encore! There's one big bummer when introducing a "build" system for JavaScript like we just did: each time you change a file, you will need to re-run Encore! Lame! That's why Encore has a fancy "watch" option. Run:

./node_modules/.bin/encore dev --watch

This will build, but now it's watching for changes! Let's just add a space here and save. Yes! Encore already re-built the files. Stop this whenever you want with Ctrl+C.

Oh, and since this command is long, there's a shortcut:

yarn run encore dev

or, better... use the --watch flag:

yarn run encore dev --watch

Build Notifications!

Great! But... sometimes... we're going to make mistakes. Yes, I know, it's hard to imagine. Let's make a syntax error. Back at the terminal, woh! The build failed! But if you weren't watching the terminal closely, you might not realize this happened!

No problem! Let's enable a build notification system! In webpack.config.js, just add enableBuildNotifications():

... lines 1 - 2
Encore
... lines 4 - 11
.enableBuildNotifications()
;
... lines 14 - 17

The "watch" functionality has one weakness: whenever you update webpack.config.js, you'll need to restart Encore before it sees those changes. So... stop it and run Encore again:

yarn run encore dev --watch

Bah, error! Scroll up! Check this out, it says:

Install webpack-notifier to use enableBuildNotifications()

And then it tells us to run a command. Cool! Encore has a ton of features... but to stay light, it doesn't ship with the all of the dependencies for these optional features. But, it's no problem: if you need to install something, Encore will tell you. Copy that command and run:

yarn add webpack-notifier --dev

Run encore again:

yarn run encore dev --watch

It works! And cool! A desktop notification. Now, make a mistake! Yes! An obvious build error. Fix it and... build successful!

Ok, we've got a pretty sweet system already. But Webpack is going to let us do so much more.

Leave a comment!

  • 2018-11-19 Victor Bocharsky

    Hey Jose,

    Oh, I see! Thank you for this report! We'll fix it and re-upload the video soon.

    Cheers!

  • 2018-11-18 Jose Diaz

    Oops! I think something has gone wrong with the icons on the video around 00:36

  • 2018-11-09 weaverryan

    Hey Galen Senogles !

    Ah, sorry about the issues! Encore got a brand new release only 5 days ago, so there are a few changes. We're working on adding some notes now to point those differences out in the tutorial :). However, I don't think you should have such a catastrophic failure this early!

    First, yes, delete that .babelrc file Phimaka is 100% correct. We actually delete that in a little while in this tutorial - but until the recent upgrade, it didn't cause any issues.

    Second, you can ignore the deprecation warnings from Encore. Those are referring to some new features we added in the latest version. It's cool stuff - but not important for following along with this tutorial successfully.

    If you have any other questions, please let us know! We want Encore to be a smooth process - which is why we're adding some notes right now!

    Cheers!

  • 2018-11-09 Phimaka

    Remove .babelrc file.

  • 2018-11-08 Galen Senogles

    I followed the instructions from the first video to this one as close as possible (I'm not sure if I accidentally missed something), but I ended up with the following error after attempting to run ./node_modules/.bin/encore dev

    /home/user/git/Webpack Encore A Party for your Assets/node_modules/@babel/core/lib/config/files/plugins.js:152
    throw e;
    ^
    Error: Cannot find module 'babel-preset-env' from '/home/user/git/Webpack Encore A Party for your Assets'
    - Did you mean "@babel/env"?
    at Function.module.exports [as sync] (/home/user/git/Webpack Encore A Party for your Assets/node_modules/resolve/lib/sync.js:43:15)

    I ran the command: yarn add babel-preset-env --dev

    Thinking that might help but it made another error trying to run the encore command again:

    $ ./node_modules/.bin/encore dev
    Running webpack ...

    DEPRECATION Either the Encore.enableSingleRuntimeChunk() or Encore.disableSingleRuntimeChunk() method should be called.
    DEPRECATION The recommended setting is Encore.enableSingleRuntimeChunk().
    DEPRECATION After calling Encore.enableSingleRuntimeChunk(), a new "runtime.js" will be output and should be included on your page before any other script tags for Encore files.
    ERROR Failed to compile with 1 errors 2:26:18 PM

    error in ./public/assets/js/RepLogApp.js

    Module build failed (from ./node_modules/babel-loader/lib/index.js):
    TypeError: Cannot read property 'bindings' of null

    I'm stuck at the current moment, I'll go back and try the tutorial again and see if I missed something.

  • 2018-09-05 weaverryan

    Hey Shaun!

    Ah, yep! So, 2 things:

    1) Encore does not yet support Webpack 4. Actually, support is VERY close - it's already done, I just haven't tagged a release yet. So, it will support it soon, but it does not support it yet.

    2) Somehow, an entry to Webpack at version ^4.5.0 was added to your package.json file. This is causing Webpack 4 to be installed, even though Encore wants Webpack 3 (dependency & version management in Node/npm is a little bit weird compared to PHP). I would recommend removing webpack, webpack-cli and extract-text-webpack-plugin from your package.json file. Then, remove your yarn.lock file, delete the node_modules directory, and run yarn install again. That should hopefully get you the correct versions of dependencies. By the way, the next version of Encore will (in many cases) give you a bit more warning if the version of your dependencies does not match what Encore needs.

    Cheers!

  • 2018-08-31 Shaun

    Sure, here you go!

    // package.json
    {
    "devDependencies": {
    "@symfony/webpack-encore": "^0.19.0",
    "extract-text-webpack-plugin": "^4.0.0-beta.0",
    "node-sass": "^4.8.3",
    "sass-loader": "^6.0.7",
    "webpack": "^4.5.0",
    "webpack-cli": "^2.0.13",
    "webpack-notifier": "^1.6.0"
    },
    "license": "UNLICENSED",
    "private": true,
    "scripts": {
    "dev-server": "encore dev-server",
    "dev": "encore dev",
    "watch": "encore dev --watch",
    "build": "encore production"
    },
    "dependencies": {
    "babel-core": "6",
    "babel-loader": "^7.1.4",
    "bootstrap": "4.1.3",
    "jquery": "3.3.1",
    "popper.js": "1.14.3"
    }
    }

    // webpack.config.js
    var Encore = require('@symfony/webpack-encore');

    Encore
    // the project directory where compiled assets will be stored
    .setOutputPath('public/build/')

    // public path used by the web server to access the output path
    .setPublicPath('/build')
    .cleanupOutputBeforeBuild()
    .enableSourceMaps(!Encore.isProduction())
    .autoProvidejQuery()
    .addEntry('js/app', [
    './node_modules/jquery/dist/jquery.slim.js',
    './node_modules/popper.js/dist/popper.min.js',
    './node_modules/bootstrap/dist/js/bootstrap.min.js'
    ])
    .addStyleEntry('css/app', [
    './node_modules/bootstrap/dist/css/bootstrap.min.css'
    ])
    ;

    module.exports = Encore.getWebpackConfig();

    This is the full error I am getting:

    vagrant@my-project:~/code/my-project$ ./node_modules/.bin/encore dev

    Running webpack ...

    (node:27168) DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead

    /home/vagrant/code/my-project/node_modules/webpack/lib/Chunk.js:468

    throw new Error(

    ^

    Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead

    at Chunk.get (/home/vagrant/code/my-project/node_modules/webpack/lib/Chunk.js:468:9)

    at /home/vagrant/code/my-project/node_modules/@symfony/webpack-encore/node_modules/extract-text-webpack-plugin/dist/index.js:176:48

    at Array.forEach (<anonymous>)

    at /home/vagrant/code/my-project/node_modules/@symfony/webpack-encore/node_modules/extract-text-webpack-plugin/dist/index.js:171:18

    at AsyncSeriesHook.eval [as callAsync] (eval at create (/home/vagrant/code/my-project/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:7:1)

    at AsyncSeriesHook.lazyCompileHook [as _callAsync] (/home/vagrant/code/my-project/node_modules/webpack/node_modules/tapable/lib/Hook.js:35:21)

    at Compilation.seal (/home/vagrant/code/my-project/node_modules/webpack/lib/Compilation.js:896:27)

    at hooks.make.callAsync.err (/home/vagrant/code/my-project/node_modules/webpack/lib/Compiler.js:479:17)

    at _done (eval at create (/home/vagrant/code/my-project/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:9:1)

    at _err1 (eval at create (/home/vagrant/code/my-project/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:32:22)

    at _addModuleChain (/home/vagrant/code/my-project/node_modules/webpack/lib/Compilation.js:764:12)

    at processModuleDependencies.err (/home/vagrant/code/my-project/node_modules/webpack/lib/Compilation.js:703:9)

    at _combinedTickCallback (internal/process/next_tick.js:131:7)

    at process._tickCallback (internal/process/next_tick.js:180:9)

    vagrant@my-project:~/code/my-project$

  • 2018-07-30 Diego Aguiar

    Hey Olivier

    I believe you only have to run it like this ./node_modules/.bin/encore dev-server (dev-server)
    instead of specifying in the code on which environment you want it to run

    Cheers!

  • 2018-07-30 Olivier

    ok !

    add
    .configureRuntimeEnvironment('dev-server') in the webpack.config.js
    it's work like a charm :)

  • 2018-07-30 Olivier

    Hello , does not work form me

    when i compile with : ./node_modules/.bin/encore dev

    throw new Error(`Encore.${prop}() cannot be called yet because the runtime environment doesn't appear to be configured. Make sure you're using the encore executable or call Encore.configureRuntimeEnvironment()

    Any ideas
    Thx

  • 2018-07-30 Victor Bocharsky

    Hey El,

    Thanks for sharing it with others! It's good to know for Windows OS users.

    Cheers!

  • 2018-07-28 El Tebe

    "Stop this whenever you want with Ctrl+C"

    Its not works on Windows if you use git-bash:
    The Ctrl+c combination will show somthing that the process was exited, BUT NOT!
    Not the whole process tree killed and some things just running hidden in the background.

    so, if you get a lot of weird errors, like:
    yarn error "ENOTEMPTY: directory not empty, rmdir" or "“EACCESS: permission denied, scandir" and/or you can't delete the
    build directory and contents because of a weird non-existed app.js/main.js or css .files...

    Switch from git-bash to another terminal (like cmder).
    Another solution (not tested): reinstall the git-bash with "Run Git from the Windows Command Prompt" option.

    (I hope it saves a lot of debugging..)

  • 2018-06-05 Victor Bocharsky

    Hey Xi,

    Yeah, "Git Bash" is very cool - it has most unix commands out of the box! I used to like it a lot when using Windows :)

    Cheers!

  • 2018-06-04 Xi Wang

    IMHO I would just use 'Git Bash' instead of 'Command Prompt' - it saves you from headaches of inconsistency issues and feels very close of using a native bash. (for those of us stuck with windows ;))

  • 2018-05-17 Diego Aguiar

    Yes, finally!
    It must to be something about paths, but I'm not 100% sure. Anyways I'm glad that you could fix your problem :)

    Cheers!

  • 2018-05-17 Andrea

    Don't ask me why but running
    > yarn run encore dev
    It works!

  • 2018-05-17 Andrea

    Thanks for the advice but... nothing, same error. :(

  • 2018-05-16 Diego Aguiar

    Ok, I have one last idea. Try using back slashes ".\node_modules\.bin\encore dev"
    If that doesn't work either, I'll ping Ryan to give it a check (it may take some time)

  • 2018-05-16 Andrea

    Unfortunally i tried both with same result.
    The last one is yarn.

  • 2018-05-16 Diego Aguiar

    Hmm, maybe if you try running it through "npm" or "yarn"?

  • 2018-05-16 Andrea

    Yes, but i'm on windows system, so without "node" it doesn't works at all.

  • 2018-05-16 Diego Aguiar

    Hey Andrea

    Have you tried running it without the word "node"? i.e `./node_modules/.bin/encore dev`

    Cheers!

  • 2018-05-16 Andrea

    Hi, when i run "node ./node_modules/.bin/encore dev" i've got this error:

    C:\..........\node_modules\.bin\encore:2
    basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
    ^^^^^^^

    SyntaxError: missing ) after argument list
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:616:28)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3

    Can you help me?

  • 2018-04-06 weaverryan

    Hey Shaun!

    Victor is right... though it’s a bit mysterious, because Encore should kick your Webpack at v3. Could you post your package.json and webpack.config.js file?

    Cheers!

  • 2018-04-06 Victor Bocharsky

    Hey Shaun,

    What Webpack version installed do you have? It may be related to the new Webpack 4, probably downgrade it to v3 wil lfix this issue. If not, can you give us a bit more context about what file threw this error, it would be good to see stack traces below the error

    Cheers!

  • 2018-04-05 Shaun

    When I try to run ./node_modules/.bin/encore dev I get the following error:

    Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead

  • 2018-03-02 Victor Bocharsky

    Hey Vince,

    Thanks for sharing it with others! That's probably because Windows has permissions problem. I think you can try to add "node" in front of "./node_modules/.bin/encore", i.e.:

    node ./node_modules/.bin/encore dev

    In order to execute this file though Node. This way it should work. But I'd recommend to use "yarn run encore dev" which is a nice shortcut.

    Cheers!

  • 2018-03-02 Vince Liem

    "./node_modules/.bin/encore dev" command line doesn't work in windows.
    neither does "node_modules/bin/encore dev".

    You can run "yarn run encore dev" instead