Instructor: Our application relies on React and ReactDOM. As it stands, webpack is going to include those libraries as part of our bundle every time we do a build. For a production build, we'd like to externalize these libraries and pull them in from a CDN instead.
We still want our imports inside of our bundle to work, but we want those to reference globally available versions of React and ReactDOM. We'll start with our webpack config. We're just going to do this for production, because we don't want to do this in development build. There, we'll just keep everything local.
We're going to add an externals key to our production webpack config, and that's going to take an object. In this object, we're going to pass it a key called react. Then it's referenced inside of our app as react. If we look here, we'll see that we're importing capital R, React from lowercase react.
Here, we have the lowercase react key, with the capitalized React value. Then we're going to do the same thing for ReactDOM. We're going to have react-dom. That's going to have a value of ReactDOM, with capital DOM. In a string, we'll do react-dom, with the value ReactDOM. With that in place, let's save our updated configuration.
In the terminal, we're going to do an npm run build. That's going to do a production build for us. We'll see that we have this output. webpack-bundle-analyzer saved a report, to this distBundleSizes.html. I'm going to open that.
When we look at this output, we'll see that our app bundle includes our source, a couple things from Node modules, but we're not going to see the React or the ReactDOM libraries. We've externalized those from our build. Now, if I take a look at the application itself, by running open dist, to my index.html file, we see that we'll get a blank page.
If I open up the dev tools, we're going to see that we have a reference error that React is not defined. This is expected behavior because we've told webpack not to include React or ReactDOM in the bundle. It's on us to make it available globally on the page. Let's go into our index.html, under source, which is our template for our output.
We want to add the CDN links for both React and ReactDOM, but we only want these available in a production build. We're going to keep React and ReactDOM in our bundle for development builds. We have the ability in this template, because of the way HTML webpack plugin processes this, to use variables and add some logic.
We're actually going to use EJS style syntax to add an if statement, based on process.env.node_env. This is going to be set based on the mode in our webpack config during build time. This is all going to happen during build time, and at runtime we're just going to get static HTML on the other end.
We're going to say if that is equal to production, we'll open a curly brace for this if. Then we have to close this tag with another percent angle bracket. Then we're going to close the if with a percent, closing curly brace, and another percent bracket. This syntax is a little weird. We don't have to use it a lot. Now we want our CDN links for React and ReactDOM to sit in here.
I'm going to jump to the React website where they provide CDN links, and I want to grab the production links. These two script tags, click point to unpackage. You can use any CDN you want. Then we're going to drop those script tags right in there. I'll save that index.html, and then let's jump into a terminal, and we can do npm run build to do a new production build.
Now, we can open dist index.html. This time we get our app. If we view source on this, you'll see that we have our script tags that we pulled from the CDN. If I come back to my terminal, I do an npm run dev, and if I view the source on this, we'll see that we do not have those CDN links. Our app.bundle includes React and ReactDOM in this case.
Now, we're set up to leverage a CDN in production, but still have the convenience of everything being run locally for our development builds.