First, unnecessary bloat: libraries, such as Vue and React, have built-in debugging tools that are essential for development but add extraneous code to a live application. Left unmanaged, code bloat can cause significant performance issues in production.
Second, test data: your development environment will likely include mock data that you don’t want in production output.
In the rest of this post I’ll run through how to configure Webpack to manage builds from separate config files. Webpack expects to see a
webpack.config.js file in your app directory.
The module.exports value, in a simple Webpack config file, is usually set to a config object. However, in order to use the env variable, we set module.exports to a function. This function accepts the environment as a parameter and returns a config object.
Now we can specify the environment when we run Webpack through the command line.
Once we have access to the environment variable, we can add logic to our config based on it. In this case, our config function will look for an environment specific config file, such as:
The prod config can have additional plugins specified, like uglify which will compress and minify your js.
package.json, you can add scripts that include the correct syntax, so you can quickly type a command without having to remember all the arguments.
Now instead of typing
You can just type:
Or if you’re using yarn:
If you’re using a library like Vue, you may require it as a dev dependency in your
package.json, which means the entire development library will be in
node_modules. Vue in particular has excellent debugging tools to help you find problems and step through your application.
However, in your
webpack.prod.js you could make this external by adding:
And in your application or website include the production library with
The production version is minified and is a much smaller file. Webpack magic will see the Vue dependency in
package.json but instead of building it into your production ready file, it will just expect your page to load it separately.
You can verify this by watching the network panel in your browser inspector; your js will be reduced in filesize and you’ll see the Vue library load from a cdn.
##Webpack Dev Server Another advantage of this “split” is when running a test version of your app that focuses on just the component you’re working on.
Then add to your scripts in
--env dev which tells Webpack to use your dev config.
...will start up a local server pointing to your
index.html file make sure to have the element your app will load itself into, and add a script tag for wherever your dev js is being built to- specified in
webpack.dev.js in the output property:
Your script tag should point to that filename.
This file doesn’t even have to exist on your computer. Webpack will build it and load it into memory for the dev server. Any js changes will trigger a hot reload so you can immediately see your progress.
Mocking Development Data
The env variable has other uses, too. Your development environment may not match production, or in this example, depends on data provided by another website. When running the
webpack-dev-server you may not have access to this external data and want to mock an example.
For this example application, I wanted to build a list of content from Drupal which I’ll add to drupalSettings, a global Drupal uses to pass data from the server to the client. I’ll use this to then load data into a small menu component that I’ll build with Vue.
The production application should use the external dependency though, and should not include any of your mock data.
If all your data is loaded in a file called
app-data.js, at the simplest it could be something like
Then in your application load that object with:
This of course will break if there is no drupalSettings object.
Just like the config file, any other dependency in your build could be split from a single file into environment specific files.
Webpack can replace any string during a build, you could add a unique string like APP_TARGET and tell it to replace that with the current env variable.
In both your Webpack configs (dev and prod) add the NormalModuleReplacementPlugin to plugins:
This tells Webpack to replace any occurrences of the string “APP_TARGET” with that env value.
Now replace your
app-data.js with 2 new files,
In the prod file use the string that points to drupalSettings since this will only be used on your site.
In the dev file return a stub object with dummy data.
Tip: If you already added some data to drupalSettings, you can load it up from your browser console, stringify it, and then paste that right into your file to ensure you’re testing against the same data structures your site will use.
Type this in your console:
This will format the object and print it to your console. To save even more time, wrap that in a “copy” function to add it directly to your clipboard.
With your 2 new app-data files, in your app you can change the import statement in your application:
Now when Webpack builds your dev or prod environment it will replace that string and import the appropriate file.
There is a lot more you can do with this, for example the
--env variable can be an object instead, so you could pass more config inside it for additional build settings. You could also split some of your duplicate config into something like a
webpack.common.js so that you have more generic boilerplate for your next project.
Webpack gets better every release, but the documentation can be difficult to sort through, especially keeping track of different versions and the changes each one brings. It can be confusing but chances are there is already a solution to any problem you come across!