Adding Webpack in your WordPress plugin or theme might feel scary. I stepped out from my comfort zone while working on a new plugin. Since that plugin might be using React or Vue in a future version, I wanted to have Babel and similar there. In this tutorial, I will show you the steps I used to configure Webpack in WordPress for my first time.

Since this is my first Webpack configuration, it may lack some of the useful plugins and scripts. If you think I should include something, you’re welcome to comment that at the end of this tutorial.

If you’re more of a person who rathers watches than reads, here is a video on it if you can spare 30min of your time. If not, just scroll down and scan the code;)

Getting Started with Webpack

To get started using Webpack, you must first install the pre-requisites. If you don’t have Node.js installed, go to the website and follow the install instructions. It will take you a few minutes of your time.

That’s it! Now we can move on. Just check npm -v if you have that there. If not, you might want to restart your computer. But in general, you should only quite and re-open the terminal (command line).

Since I have set this for my own plugin, I will talk about my plugin folder. For your own WordPress products, the only things that you will have to change is the path to your JavaScript or CSS (theme or plugin).

Go to your WordPress product folder through the terminal. I will assume now that you don’t have a package.json there. I had one since I have started my plugin folder through WP-CLI command wp scaffold plugin . If you’re interested, you can check that command here.

To create a package.json, you can just write npm init and then you will have to answer some questions to set the defaults. If you don’t feel like answering them, you can type npm init -f so you will get a basic package.json with a few defaults. You’re welcome to change the defaults such as the name of your product.

If you want to learn more about the possible options inside the package.json check this site then. Here is the JSON I got from running npm init -f:

Installing Webpack

Now that our package.json is done, we can start installing what we need. Since we are talking about Webpack, we will install Webpack. To install Webpack type this while being in the same directory where package.json is:

npm install --save-dev webpack

By using --save-dev we are installing Webpack locally inside our project. You might see that a folder node_modules was also created (if it was not there before). This folder is used to store various libraries which will be compiled inside our JavaScript or used to perform some tasks on it.

You won’t include that when building the plugin for production.

Automating the Build

So, now to start our Webpack in WordPress we could write everything inside the command line but who would want to do that. Every time we want to compile, we would need to enter the full path to Wepback, a path to our JavaScript and where the compiled one should be. It could look something like this:

./node_modules/.bin/webpack src/index.js dist/bundle.js

Do you really want to write this everytime you change something? I didn’t even want to this here, so I just copied it from the Webpack Getting Started manual.

To automate our Webpack in WordPress, we want to have some scripts. By reading the Getting Started manual, I saw how to create a build script. That is fine and it can be done like that. But after 5-10 changes, you would like that to be done automatically.

Let’s open our package.json and under "scripts" add this:

We have specified the script name and all the commands that have to be run. Now you can write npm run watch and Webpack will watch changes on your entry files. We still don’t have those, so we will use a configuration file.

Creating a Webpack Configuration File

In the same folder where you can find package.json, create a new one: webpack.config.js. Webpack will recognize that file and load it. Let’s copy all the content from the manual now. I did that before doing any changes.

What does all that mean?

  • entry – you can add a string to add the path to your JavaScript. Or it can be an object with many entry paths. For now, it would look for a script in our plugin under src/index.js
  • output – the output object will define where will the compiled JavaScript file reside and how it will be named. For now, it would saved under folder dist and name bundle.js

To try that out by writing npm run build in the command line. If you don’t have a src/index.js, it will throw an error. But that also means it works 😉

Adding More Files

If you’re like me, I like to have a script for the admin part and one for the front part. So, let’s say we have an admin.js and a public.js. And, since our compiled files will be minified in the end, let’s edit the configuration to get admin.min.js and public.min.js.

In the output object, we have specified that our entry point name will also be inside the output file before min.js by using .min.js.

You can also see that my uncompiled scripts will be inside the folder assets/js, but I also edited the configuration so my compiled scripts will also be saved inside assets/js. You can change that if you want.

Preparing for ES6 – Babel

You might want to use new JavaScript features which some of them could not be supported by all browsers. So we need to compile them into an older version. We can use babel for that. To load babel onto our JavaScript, we will need to use loaders.

We will need to use the babel-loader. To include such loader in our Webpack, first we need to install it by running this script:

npm install babel-loader babel-core babel-preset-env --save-dev

Without --save-dev, we would install them globally so that such libraries would be available elsewhere. But we don’t want that.

To use such loader, we need to edit the configuration. This could be a bit longer, but right after the output object, add the module object.

Minifying the Scripts

Now, we also want to minify such scripts. To do such thing, we need to use Webpack plugins. We will use the UglifyJS plugin which can be installed by this script:

npm install --save-dev uglifyjs-webpack-plugin

To be able to use such plugin, we need to require it in a constant and then add it inside our configuration:

Using CSS in JavaScript

Webpack allows writing CSS and importing them in JavaScript. This might not be something you are used. We will extract that at the end, but before that, we will import CSS in our JavaScript. If we had several components and each with their own CSS, Webpack would load only the CSS needed on the page.

We can try it with our current configuration. Just create a CSS file at assets/css/style.css. I have only put body { display:none !important; }. If loaded correctly, we should not be able to see anything on our site (if you are enqueing our public.min.js on the page). Let’s add that to our public.js like this:

Now, run npm run build. You should get an error saying that our CSS is unexpected.

Error while importing CSS without Style & CSS Loader

To be able to import CSS we will need to use the style-loader and css-loader libraries. Let’s run:

npm install --save-dev style-loader css-loader

This is not enough of course. Since we are using new loaders, we will need to add some rules to it so that our Webpack can know what to do when it comes to CSS. Similar to what we did with Babel before. Open our webpack.config.js and add new rules:

Try to run npm run build. It should work and you could get something like this:

Success after installing Style and CSS Loaders

You should now see a blank screen while loading your page (if you have enqueued our JavaScript). Pretty amazing since we did not enqueue any CSS, only JavaScript.

Writing SASS

To be able to write SASS instead of CSS, we need to configure our Webpack in WordPress. Again, we will need a loader. This time it is called sass-loader. But for our node (npm) to be able to compile SASS (SCSS), we also need to have a library that will process SASS. That is why we will also install node-sass.

Let’s now run this command:

npm install sass-loader node-sass --save-dev

Open our webpack.config.js again and let’s add a new rule. This time, add this after the JS rule and before the CSS rule:

You may wonder why did I leave the other CSS rules out there. I wanted to leave that there since you never know if you might just want to add a simple CSS file somewhere. With this rules, Webpack will process it without errors.

Extracting CSS to a Separate File

You may wonder why would you want to load CSS only per component in production. That can be done in some situations. Probably, in most cases, you would want to move CSS to a separate file so that you can enqueue it in WordPress. When using Webpack in WordPress, you don’t want to load CSS only per component because then, others will have a hard time overriding your CSS.

To extract CSS, you need to use another plugin. Let’s install it with this command:

npm install extract-text-webpack-plugin --save-dev

We will now have to edit our webpack.config.js in several places:

First, we are adding them as variables at the beginning so that we can use it later on. You can modify to extract your CSS files somewhere else.

After that, we must also inform our Webpack in WordPress that we will use this variable as a plugin.

The last thing is to edit the rule for our SCSS so that our Webpack knows how to process it. Now, try to run npm run build and check your folder assets/css/ for a file public.min.css. The word public is coming from our entry points.

As a challenge, try to edit the rules for CSS also and see what will happen. You can check the github of the Extract Text Webpack plugin for hints.

Adding External jQuery or other Libraries

Even though we are using Webpack so we can actually use ES6 and be on the top of JavaScript, you will probably want to use jQuery somewhere. If you won’t, that is also fine. But if you need it, you will need to add that to Webpack in WordPress.

We could install a new jQuery through npm but that does not make any sense since WordPress is already packed with a jQuery version and it is considered bad practice including other jQuery versions.

With the current configuration, you should not have any problems. But, if you change the configuration or if for some reason Webpack in WordPress is informing you that jQuery is unexpected while compiling, you will need to add it as an external file. For that, we need to edit our configuration.

Now, when using jQuery in a file, you just need to add this at the top of your file:

import "jquery";

Now, jQuery will be available in your script.

Conclusion

Configuring Webpack in WordPress was not so difficult as I have thought it would be. I just had to sit down and read the documentation on Webpack. By following the guidelines I might have encountered some errors. But then, you just google it a bit and try other things. After a few tries, I had a configuration that suits my workflow.

Have you ever configured Webpack yourself? What were the difficulties you have encountered? Should I have done something differently to enhance it? Please share in comments.

Become a Sponsor

Posted by Igor Benic

Web Developer who mainly uses WordPress for projects. Working on various project through Codeable & Toptal. Author of several ebooks at https://leanpub.com/u/igorbenic.

12 Comments

  1. The https://github.com/webpack-contrib/extract-text-webpack-plugin/ no longer works for Webpack 4, do you use an alternative now?

    Reply

    1. I haven’t yet tried upgrading to Webpack 4 and I’ll probably wait until this plugin is stable. But if you really want to use Webpack 4 then you can try https://github.com/webpack-contrib/mini-css-extract-plugin for extracting CSS.

      Reply

    2. Instructions for using this tutorial with Webpack 4.

      1. Install an additional module => `npm install –save-dev webpack-cli`
      The webpack CLI was moved into a separate package, this package must be installed in order to run wepback from
      the cli (npm commands…).

      2. Replace the `extract-text-webpack-plugin` with a newer version by running the following command `npm i -D extract-text-webpack-plugin@next`, this version matches the schema that Webpack 4 expects.

      Theses Fixes should do the job, I did this tutorial with Webpack 4 and works perfectly!

      Reply

      1. @yaron

        I’m trying that but seem to be running into some issues. I’m very new to using Webpack though, so maybe I’m missing a very simple step that should be obvious.

        I install the webpack cli. I then install the extra-text-webpack-plugin@next (which as I understand it is the beta version of extract text that is Webpack 4 compliant, yes?)

        When I run npm build after all the other steps have been done (except for the jquery stuff) I don’t get a public.min.css as the tutorial seems to say I should. Any idea why? What else am I supposed to change?

        I tried changing my const declaration in webpack.config to have the @next on the end but that just made npm wig out and throw a bunch of errors. I also changed the listed extract text name in package.json to also have @next in it. Is that correct?

        Reply

    3. use :
      npm i -D extract-text-webpack-plugin@next

      Reply

  2. You can use this: `test: /\.(css|scss|sass)$/` and have a single rule
    for handling the style (css | sass | scss …) there is no need to use 2 separates rules.

    Thank you @Igor Benic for taking the time and effort in creating this tutorial !!!.

    Reply

    1. Thank you, Yaron for both suggestions! I’ll try it out with Webpack 4 and update the tutorial 🙂

      Reply

  3. @Yaron Miro But for webpack 4, they are officially suggesting mini-css-extract-plugin[https://github.com/webpack-contrib/mini-css-extract-plugin] not extract-text-webpack-plugin, can you check with this plugin. there is some confusion I have when using that plugin, when using that plugin In dev mode no hot loading is happening[for css] also not minifying the css, can you show how can we do this.

    Reply

  4. Mistake in this line : “quite and re-open the terminal” – needs to be “quit and…”

    Reply

  5. Loved the tutorial! Just an updated for anyone looking at this in 2018: When you’re installing the babel core and babel preset env you’ll need to install them as @babel/core and @babel/preset-env or you’ll need to use babel-loader v7

    Reply

  6. Great Article!

    It got me started with my plugin.

    Just one thing Extract text webpack plugin doesn’t work with Webpack 4, We need to use mini-css-extract-plugin.

    Reply

  7. I recommend also to check this: https://github.com/wwwebman/gulp-webpack-starter#eyes-2-wordpress. It can be really helpful for custom theme development.

    Reply

Leave a reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.