0% found this document useful (0 votes)
144 views11 pages

Webpack Configs for Dev and Prod

This document provides an overview of using separate configuration files for development and production builds in Webpack. It discusses creating a base configuration file that both share, then extending that base with dev- and prod-specific configurations. It also covers using the webpack-merge plugin to combine the base and environment-specific configurations. Finally, it briefly introduces the concept of creating multiple output bundles, such as for public and admin sections of an app.

Uploaded by

Carlos
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
144 views11 pages

Webpack Configs for Dev and Prod

This document provides an overview of using separate configuration files for development and production builds in Webpack. It discusses creating a base configuration file that both share, then extending that base with dev- and prod-specific configurations. It also covers using the webpack-merge plugin to combine the base and environment-specific configurations. Finally, it briefly introduces the concept of creating multiple output bundles, such as for public and admin sections of an app.

Uploaded by

Carlos
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Learn webpack

The sample chapter

By Jakob Lind
[Link]

In this sample chapter, you’ll first learn how to create two webpack config files - one for dev and
one for prod. Then you will continue to learn how to create two different bundles - one for admin
and one for the public facing site.

To be able to follow this you must have an existing project to start from. You can download a
minimalistic webpack project on ​[Link]

The full book can be purchased on ​[Link]

Enjoy!
Separate prod and dev configs
A simple webpack config for a React app looks something like this as you already
learned:

const​ webpack = ​require​(​'webpack'​);


​ equire​(​'path'​);
const​ path = r

const​ config = {
entry: ​'./src/[Link]'​,
output: {
path: [Link](__dirname, ​'dist'​),
filename: ​'[Link]'
},
module: {
rules: [
{
test: ​/\.(js|jsx)$/​,
use: ​'babel-loader'​,
exclude: ​/node_modules/
}
]
},
resolve: {
extensions: [
​'.js'​,
​'.jsx'
]
}
}

module​.exports = config;

And you have scripts in ​[Link]​ to start it and build it:


​"scripts"​: {

1
​"build-dev"​: ​"webpack -d --mode development"​,
​"build-prod"​: ​"webpack -p --mode production"
},

If this doesn’t look familiar, take a look at ​Part 1​ of the book again.

Now, the problem with this is that there is only one webpack config for both production
and development. That means if you add some extra optimizations meant for production
in the webpack config, you will also get those optimizations in your development build.

What you want to do is to have ​separate​ webpack configs for development and
production.

If we look at the docs for webpack-cli (​[Link] you can see that it
accepts an input parameter called ​--config​. Here you can specify which config file to
use when you build. You can use this parameter in the ​[Link]​ file where you
specify how to call the webpack cli:

​"scripts"​: {
​"build-dev"​: ​"webpack -d --mode development --config
[Link]"​,
​"build-prod"​: ​"webpack -p --mode production --config
[Link]"
},

Note that you now use two separate webpack configs: ​[Link]​ and
[Link]​. Now you just need to create these files. Let’s just do that by
copying the old ​[Link]​:

cp [Link] [Link]
mv [Link] [Link]

Now you have separate configs for prod and dev. You can add hot reloading to the dev
config and optimizations to the prod config.

2
But there is one problem.

There will be lots of duplicate code in these two config files.

Most of the dev config and the prod config will contain the same stuff. Things like the
entry​ and the ​loaders​ will be the same in prod and dev.

Let’s improve this.

Remove duplicated code with webpack-merge


To remove the duplicated code in the webpack configs, we’ll create a base webpack
config that’ll contain the things that dev and prod have in common. Then we will extend
from this base config when we create the dev config and the prod config.

There is an awesome library that is called ​webpack-merge​ that helps us merge two
webpack configs. We will use this library to merge the base config with the prod config
and the dev config.

Let’s start by installing ​webpack-merge​ as a dev dependency:

npm install --save-dev webpack-merge

And then we will create the ​[Link]​ which look exactly like our old
[Link]​:

const​ webpack = ​require​(​'webpack'​);


​ equire​(​'path'​);
const​ path = r

const​ config = {
entry: ​'./src/[Link]'​,
output: {
path: [Link](__dirname, ​'dist'​),
filename: ​'[Link]'

3
},
module: {
rules: [
{
test: ​/\.(js|jsx)$/​,
use: ​'babel-loader'​,
exclude: ​/node_modules/
}
]
},
resolve: {
extensions: [
​'.js'​,
​'.jsx'
]
}
}

module​.exports = config;

Now let’s extend from the base config in the ​[Link]​ file

const​ merge = ​require​(​'webpack-merge'​);


const​ base = ​require​(​'./[Link]'​);

const​ config = {
devServer: {
contentBase: ​'./dist'
}
}

module​.exports = merge(base, config);

This dev config will add the ​devServer​ section to the base config. You will learn more
about ​devServer​ in the next chapter where you’ll create an awesome dev experience.

4
Note how we use the function ​merge​ from the library ​webpack-merge​ to merge the base
config that we just created and the new dev config. The ​merge​ function creates a config
that looks like this:

{
entry: ​'./src/[Link]'​,
output: {
path: [Link](__dirname, ​'dist'​),
filename: ​'[Link]'
},
module: {
rules: [
{
test: ​/\.(js|jsx)$/​,
use: ​'babel-loader'​,
exclude: ​/node_modules/
}
]
},
resolve: {
extensions: [
​'.js'​,
​'.jsx'
]
},
devServer: {
contentBase: ​'./dist'
}
}

Next, we will create the webpack prod config in a similar way.

This is how ​[Link]​ looks like:


const​ merge = ​require​(​'webpack-merge'​);
const​ base = ​require​(​'./[Link]'​);

5
const​ config = {
optimization: {
splitChunks: {
chunks: 'all'
}
}
}

module​.exports = merge(base, config);

This prod config uses the ​optimization​ config item that will extract the dependencies
to its own bundle to improve caching. You will learn more about this in the caching
chapter

Again we use ​merge​ function to merge the ​[Link]​ with the prod
webpack config. The merge function creates a config that will look like this:

{
entry: ​'./src/[Link]'​,
output: {
path: [Link](__dirname, ​'dist'​),
filename: ​'[Link]'
},
module: {
rules: [
{
test: ​/\.(js|jsx)$/​,
use: ​'babel-loader'​,
exclude: ​/node_modules/
}
]
},
resolve: {
extensions: [
​'.js'​,
​'.jsx'

6
]
},
optimization: {
splitChunks: {
chunks: 'all'
}
}
}

That’s it. Now we have DRYed up the code. You can build the prod bundle and dev
bundle just like before:

npm run build-dev


npm run build-prod

And they will use different webpack configs!

More than one output


You have seen how you can create two webpack config files - one for prod and one for
dev - by using a common config file.

There are more use cases where it is useful to create two configs. That is when you
want two different outputs - that means creating two different bundles.

One use case for this is if your app has two distinctly different parts. It could be that one
part is the public part and the other is the admin. You don’t want the code for the admin
part to be visible in the public bundle because that would be a security vulnerability.

Another example is if you want to implement SSR (server-side rendering). Then you
want to run the client side code ​and​ the backend code through webpack. That means
you want two outputs.

We will look more into both of these cases.

7
How to make two bundles - public and admin
Let’s start looking at the case where you have two distinct parts of your website. The
authorized user might see the admin part of the app and everyone else can see only the
public facing site.

We start by creating the ​[Link]​ file that both our webpack configs
will merge with:

const​ webpack = ​require​(​'webpack'​);


​ equire​(​'path'​);
const​ path = r

const​ config = {
module: {
rules: [
{
test: ​/\.(js|jsx)$/​,
use: ​'babel-loader'​,
exclude: ​/node_modules/
}
]
},
resolve: {
extensions: [
​'.js'​,
​'.jsx'
]
}
}

module​.exports = config;

Note that we don’t specify the entry or the output because we will do that in the other
config files. Now let’s extend from the base config in the ​[Link]
file:

8
const​ merge = ​require​(​'webpack-merge'​);
const​ base = ​require​(​'./[Link]'​);

const​ config = {
entry: ​'./src/[Link]'​,
output: {
path: [Link](__dirname, ​'dist'​),
filename: ​'[Link]'
},
}

module​.exports = merge(base, config);

And in a similar way we extend the base config in the ​[Link]​:

const​ merge = ​require​(​'webpack-merge'​);


const​ base = ​require​(​'./[Link]'​);

const​ config = {
entry: ​'./src/[Link]'​,
output: {
path: [Link](__dirname, ​'dist'​),
filename: ​'[Link]'
},
}

module​.exports = merge(base, config);

Alright, now we have all the configs we need.

To build this you need to run webpack twice: once for the public bundle and once for the
admin bundle. Let’s create a script in ​[Link]​ that does this for us:

​"scripts"​: {
​"build-public"​: ​"webpack -d --mode production --config
[Link]"​,

9
​ build-admin"​: ​"webpack -p --mode production --config
"
[Link]",
​"build"​: ​"npm run build-public; npm run-build-admin"
},

If you now run ​npm run build​ it will run both ​build-public​ and ​build-admin​ which
will create two bundles for you.

But the full book to continue reading


More information at ​[Link]

10

Common questions

Powered by AI

Using npm scripts to run different webpack builds offers strategic advantages in script simplicity and standardization within a project. By defining scripts like `build-dev` and `build-prod` in the `package.json`, developers can easily switch between builds suited for development and production environments with straightforward and memorized commands. It promotes automation and reduces the cognitive load required to remember complex CLI arguments. Additionally, it centralizes the build configuration, making it easier for new team members to understand the build process .

The webpack-merge library helps implement DRY principles by allowing shared configurations to be defined in a base config file and then merging additional, environment-specific settings. By creating a `webpack.base.config.js` file containing common configurations like entry, output, and module rules, webpack-merge can merge these settings with additional configurations specific to development or production environments. This approach avoids redundant code by having the core configurations defined once, ensuring the build scripts only focus on unique aspects for each environment .

Having separate webpack configuration files for development and production environments helps tailor optimizations and functionalities to specific needs. In development, features like hot reloading are emphasized for a better developer experience. In contrast, production focuses on optimizations such as minification and split chunks for improved performance. These separate configurations allow fine-tuning without contaminating the development build with unnecessary production optimizations, or vice versa, leading to more efficient workflows and better application performance .

Creating multiple webpack outputs is particularly beneficial for server-side rendering because it allows both client-side and server-side code to be processed separately. This separation means the client-side code can be optimized for browser environments while server-side code is formatted for Node.js. Having distinct bundles for these runtimes ensures that server-specific modules are not included in client-side bundles, reducing size and improving performance. Additionally, it allows shared modules to be effectively managed and cached across both environments, optimizing load times and resource usage .

Bundling different parts of an application such as a public area and an admin area into separate outputs with webpack prevents the admin code from appearing in the public bundle. This separation minimizes the risk of a security vulnerability by ensuring that sensitive administrative code isn't exposed to unauthorized users. By creating different webpack configurations for public and admin components, you ensure proper encapsulation and safeguard sensitive functionalities from undesired exposure .

Webpack simplifies the management of multiple web bundles, such as separate public and admin interfaces, by allowing separate entry points and output configurations in different webpack config files. Each configuration can specify its own entry point, output naming, and location, ensuring that the public interface does not inadvertently bundle sensitive admin code. By creating distinct `webpack.config.js` files for each output and merging them with a shared base configuration, developers maintain a consistent setup while tailoring bundles specifically to the needs and security requirements of different application parts .

The `optimization.splitChunks` setting enhances a webpack production build by automatically splitting code into separate files or chunks. This process helps in creating cache-friendly bundles, reducing load times by minimizing redundant code downloads and maximizing cached code reuse. It breaks up larger bundles into smaller, manageable parts, meaning users only download the necessary code for specific functionalities they access. This reduces the initial load time for web applications and optimizes the delivery of static resources .

The `entry` property in a webpack configuration file specifies the entry point or points for the bundle. It tells webpack where to start building the dependency graph, which is essential for creating the bundle. In a base configuration file, the entry is often excluded so that different configurations can be specified in distinct config files (e.g., for public or admin sections). This approach allows flexibility in how different parts of the application are built and prevents the need for multiple base configs .

Using a single webpack config file for both dev and prod environments without employing the `--config` parameter means that both environments will share the same configuration settings. This lack of separation can cause development features like hot reloading and source maps to be included in the production bundle, which would increase its size unnecessarily, or cause production optimizations to be enabled in the development environment, potentially hindering debugging and rapid iteration. The approach lacks flexibility and efficiency, as it doesn’t tailor settings to their respective environments .

The `webpack.dev.config.js` file improves the development experience by incorporating features such as development server configurations, including hot module replacement (HMR), which reloads only the changed parts of a module, speeding up the development process by reducing the need for full page reloads. It also includes more source maps, making debugging easier by allowing developers to see exact errors and stack traces in their original source code. This setup creates a smoother, faster feedback loop during development .

You might also like