JavaScript for PHP Geeks: Webpack for Module Loading Awesomeness

Buy Access

In JavaScript, if you're still manually including each JavaScript file you depend on with a script tag... there's a better way! ES6 introduced the concept of modules: the ability (finally!) to isolate our JavaScript into small components that live in different files (like we do with classes in JavaScript).

But, to get this to work on the web, we need some help. We need something that's able to read our imports and aggregate everything we need into a single JavaScript file. We need webpack:

  • Using npm... and then yarn for package management
  • Webpack setup: package all modules into a single file
  • Calling Babel from webpack via a loader
  • Webpack dev tools for fast development
  • Webpack Hot Reloading!?
  • Handling multiple files ("entry points")
  • Using Uglify and prepping for production
  • Cache-busting with hashed filenames
  • CommonsChunkPlugin: package common modules together
  • Loading & Packaging CSS/SCSS & images form JavaScript!?

And most importantly: become empowered to (finally) write organized JavaScript!


Your Guides

Ryan Weaver Leanna Pelham

Questions? Conversation?

  • 2017-08-30 Victor Bocharsky

    Hey J.R.

    Those steps are exactly what we do for KnpU during deploying, well, "git pull" except "git clone" for next deploys. And I think that's OK.Anyway, Composer and Yarn supply lock dependencies, so they will install exactly the same dependencies I have on my local machine. Well, full repository takes some HDD space, but that's not a huge problem now. The main benefit for me is that this way you can deploy project from any machine, even if you do not have working and bootstrapped project locally - it will build on the host machine during deploy. And using such tools as Ansistrano or Capistrano users won't see broken website, because those tools will switch to the new version only when it's fully bootstrapped. Or, you can replace the first step (git clone/git pull) with Rsync and do not clone repository at all, but I think running composer/yarn install is still a good idea.

    I hope that helps you.

    Cheers!

  • 2017-08-22 J.R. Jenkins

    Hey weaverryan -

    Thanks for the update. Once I removed that comma on my windows box everything worked just fine, all the paths seemed to be tolerant of the difference between '/' and '\', so perhaps the use of path.resolve() moving forward is to just remove that as being a possible issue even though it "might work" currently.

    I am usually on the Mac, but I had just noticed that and wanted to share. thanks again!

  • 2017-08-22 weaverryan

    Yo J.R. Jenkins!

    Hmmm... So, first.. this is very possible, unfortunately - because, yea, platform differences ;). About the line you mentioned... yea, that comma should not be there. It's curious it works on Unix, but seems to fail on Windows - I bet this is a Node version issue. Anyways, I'm pushing a fix right now to remove that - totally unnecessary! If you see any other issues, let me know. In Node, the / versus \ directory separators ARE important. So it's quite easy to write code that works on Unix but not Windows (or vice versa).

    Cheers!

  • 2017-08-18 J.R. Jenkins

    Hey KNP Team-

    I tried to take a look at the "finish" code on my Windows machine and node was very unhappy with the webpack.config.js file (although it worked on my Mac so yay for platform differences!). Just wanted to post this in case another Windows user runs into issues.

    I don't have the exact error in front of me today (I am in the office), but it seemed to be a parsing error. When I ran the webpack.config.js file through eslint it complained about an unexpected token on line 178


    /node_modules/.bin/eslint webpack.config.js

    /Users/jrjenk5/Downloads/js-webpack/finish/webpack.config.js
    178:5 error Parsing error: Unexpected token )

    ✖ 1 problem (1 error, 0 warnings)

    the relevant code is


    webpackConfig.plugins.push(
    new webpack.DefinePlugin({
    'process.env': {
    'NODE_ENV': JSON.stringify('production')
    }
    }),
    );

    if I remove the comma that shows up after the new webpack.DefinePlugin(), on line 178 of the original file, it seems to clean up that error.

    Then it complains about a missing semi-colon on line 7, because I always mess up ASI I always require them.

    Here was my .eslintrc.yml file


    env:
    es6: true
    node: true
    extends: 'eslint:recommended'
    parserOptions:
    sourceType: module
    rules:
    indent:
    - error
    - 4
    linebreak-style:
    - error
    - unix
    quotes:
    - error
    - single
    semi:
    - error
    - always

    So I just realized, I have an LTS version of node on my Windows box, v. 6.11.2. On my Mac at work I have a more recent version, v. 8.2.1

  • 2017-08-15 weaverryan

    Yo J.R. Jenkins

    Ah, interesting! I always like to hear about how other eco-systems handle things :). If you run into anything interesting or other questions along the way, let us know - I'm sure other people have the same questions.

    Cheers!

  • 2017-08-14 J.R. Jenkins

    Ryan-

    Thanks for the follow up, and I am glad to hear I am not overthinking it too badly, I will have to give the deploy process more thought to see if we can't streamline things.

    As for Aegir, the project's website is http://www.aegirproject.org/. While I am over simplifying, Aegir acts as front end to the "Drush Make" process to download Drupal and any designated add on modules or libraries as well as common migration/upgrade steps like checking dependencies, backing up the site, copying files/databases, running the update command, etc. When we build out a Drupal platform* it actually runs a 'drush make our-drush-makefile' on one server, and then copies those files to one of several web servers. But since it is just running a drush make having it build out all of the assets (i.e. SASS -> CSS) isn't really possible yet, so we tend to compile the SCSS and then commit the CSS as part of our theme. I won't fill up your comment section with more details, but if you want to know more just let me know.

    * We mostly use this to manage Drupal 7 sites right now, so we haven't investigated the how the build process in Drupal 8 might change.

  • 2017-08-14 weaverryan

    Hey J.R. Jenkins!

    No, it's a GREAT question. And you nailed it: it really comes down to your deploy mechanism. In a perfect world, it's exactly as you say: you would have some server (it could be your local machine) that fully builds everything you need, so that you have a final "artifact" (i.e. zip file with 100% of the files you need, including the built assets) that can then be just sent to a server. Heck, this artifact in a Symfony project could/should even include the warmed up cache. But, accomplishing this setup is non-trivial - we're not even that good here on KnpU. If you use a PAAS (like platform.sh), then you *do* get this: they have a build step where you can install any dependencies you need and build everything. Then, the final artifact is sent off to the real server (and so things like node are not present on the final server).

    So you're not supposed to commit the built assets to your repository, based mostly on the principal that you shouldn't need to commit anything to your repository that can be perfectly rebuilt from other things that live in your repository. However, if someone told me that they needed to commit their built assets to the repo to make their deploy go more smoothly, I'd say "Well, that's not ideal, but it makes a lot of sense!". Here in KnpU, we actually don't commit the assets, and then we build them on production during deploy with Ansistrano. As you mentioned, that's not ideal, because it means we need to have things like Node installed on the server. But, that's the solution we have currently.

    I'm not familiar with Aegir, but it sounds to me like this probably helps you build everything locally, and then sends the final stuff off to the remote servers. IS that right? Or does it do something different?

    Cheers!

  • 2017-08-10 J.R. Jenkins

    Ryan/KNP Team-

    I am loving this series, and your courses overall. I keep rewatching them and taking something new away each time.

    I know the answer may be controversial or you may yet answer this in one of the upcoming tutorials, but I was curious about your decision to exclude the built files from your git repository.

    I am sure Deployment to multiple environments (Dev, QA, Staging, Production) could be a course all on its own (looking forward to Animated Deployment with Ansistrano, but do you actually recommend putting the build toolchain on all of those servers and doing something like this on each server:


    $> git clone <repo> my-project
    $> cd my-project
    $> composer install
    $> yarn --install
    $> ./node_modules/.bin/webpack

    While I can see arguments for and against it just seems like you are then adding more and more dependencies to the servers for what should generally be a deployment process.

    I guess in a perfect world you would build once and then just move the built bits around, but that seems like you are opening yourself up to having different assets deployed if you are not exceedingly careful. I come from a Drupal background and we use a tool called Aegir which integrates tightly with Drush/drush make for our Deployment process, so I probably just have blinders on when it comes to different approaches.

    (sorry if this is a duplicate, comment seemed to vanish)

  • 2017-08-10 J.R. Jenkins

    Ryan/KNP Team-

    I am loving this series, and your courses overall. I keep rewatching them and taking something new away each time.

    I know the answer may be controversial or you may yet answer this in one of the upcoming tutorials, but I was curious about your decision to exclude the built files from your git repository.

    I am sure Deployment to multiple environments (Dev, QA, Staging, Production) could be a course all on its own (I am awaiting Animated Deployment with Ansistrano), but do you actually recommend putting the build toolchain on all of those servers and doing something like this on each server:


    $> git clone <repo> my-project
    $> cd my-project
    $> composer install [--no-dev]
    $> yarn --install
    $> ./node_modules/.bin/webpack

    While I can see arguments for and against it just seems like you are then adding more and more dependencies to the servers for what should generally be a deployment process.

    I guess in a perfect world you would build once and then just move the built bits around, but that seems like you are opening yourself up to having different assets deployed if you are not exceedingly careful. I come from a Drupal background and we use a tool called Aegir which integrates tightly with Drush for our Deployment process, so I probably just have blinders on when it comes to different approaches.

  • 2017-08-08 Diego Aguiar

    Just to inform you that this course is live!

  • 2017-07-24 weaverryan

    I'm the hold up on this! But I can tell you that it i AM writing this tutorial right now... finally :).

  • 2017-07-24 Victor Bocharsky

    Hey Juan,

    I totally agree with you! For now, we're releasing EasyAdminBundle, then we will start working on this one, but I can't tell you any estimated release date yet. We're going to release it after Ansistrano tutorial, see our roadmap for new courses: http://knpuniversity.com/co...

    Cheers!

  • 2017-07-23 Juan Luis Garcia

    Hi Knp!
    When this course begins?
    Unfortunately, javascript is very imperative today for any application however small .. =(

    Thanks!!!

  • 2017-07-21 Maria

    I love your tutorials guys. It's nice to learn things in a fun way))) Can't wait for the next releases

  • 2017-06-27 Shiraats

    Thank you for letting know.

    I'm really looking forward to see how this all works to together.

  • 2017-06-27 Victor Bocharsky

    Hey Shiraats,

    We're going to start releasing it in a few weeks - we were working on the new tool: Symfony Webpack Encore, that's why releasing this course is a bit delayed.

    Cheers!

  • 2017-06-27 Shiraats

    Hey

    any idea when this will be release date

  • 2017-06-19 weaverryan

    :) You got it! I'll start writing this tutorial quite soon (hopefully next week).

  • 2017-06-16 Zorpen

    Ah, The Webpack Encore :) Nice job! So i guess you were waiting with this tutorial till Encore was released? ;)

  • 2017-06-09 Nicolas Sauveur

    Can't wait for this one either !!

  • 2017-06-01 weaverryan

    Good question - it's a few weeks... or a month! But, we (Symfony) will have a surprise related to webpack (in the new few weeks)...

  • 2017-05-31 Zorpen

    Thanks Ryan.
    Can't wait for this and React Tutorial.
    How long it usually takes to make tutorial like this? A day, a week, a month? :P

  • 2017-05-31 weaverryan

    I'll start working next week on this! No release date yet :/... but I'm going to do my best! This tutorial will be fun :)

  • 2017-05-28 Zorpen

    Wheeen? ;)
    Can't wait!

  • 2017-04-07 Diego Aguiar

    Hey Babel!

    This tutorial should be released right after Ansible tutorial, you can check our roadmap to see what's coming next http://knpuniversity.com/co...
    Also you can subscribe to this mailing list, so you get notified inmediately when this course gets available.

    Have a nice day!

  • 2017-04-07 Babel Yaarrn

    When will this tut be availablu :D

  • 2017-03-25 SKS

    Thanks for the reply. and roadmap link.

  • 2017-03-24 Victor Bocharsky

    Hey Sks,

    We're working on this tutorial, it should be released right after Ansible tutorial, see our roadmap: http://knpuniversity.com/co... . For now you can subscribe to this course with "Notify me when course is available" button.

    Cheers!

  • 2017-03-24 SKS

    I am eagerly waiting for this tutorial to be available.