bundle.js 2.83 kB 0 [emitted] main
bundle.js.map 3.36 kB 0 [emitted] main
When I add the code below with the custom externals, I can remove the node_modules
from being directly included in the bundle.js
output.
bundle.js 743 kB 0 [emitted] main
bundle.js.map 864 kB 0 [emitted] main
This significantly reduces the bundle size. But I get an error in the browser saying: Uncaught ReferenceError: require is not defined
in the browser. Does anyone know how to fix this issue?
var path = require("path"),
fs = require("fs");
// return what's in the node modules folder apart from ".bin"
const nodeModules = fs
.readdirSync("./node_modules")
.filter(d => d != ".bin");
/**
* Remove non-direct references to modules from bundles
*
* @param {any} context
* @param {any} request
* @param {any} callback
* @returns
*/
function ignoreNodeModules(context, request, callback) {
// IF someone is importing a module e.g. "import {chatModule} from
// "./components/chat" using a relative path, then we're okay with them bringing
// in into the bundle
if (request[0] == ".")
return callback();
// IF someone is doing "import {Subject} from "rxjs/Subject" only want to know
// if first part is a node_module
const module = request.split("/")[0];
if (nodeModules.indexOf(module) !== -1) {
// append "commonjs " - tells webpack to go and grab from node_modules instead
// of including in bundle
return callback(null, "commonjs " + request);
}
return callback();
}
module.exports = {
entry: "./src/index.tsx",
output: {
filename: "bundle.js"
},
devtool: "source-map",
resolve: {
extensions: ["", ".ts", ".tsx", ".js"]
},
module: {
loaders: [
{
test: /\.ts(x?)$/,
loader: "ts-loader"
}
]
},
// Runs our custom function everytime webpack sees a module
externals: [ignoreNodeModules]
}
Your bundle is smaller because you're not including your node_modules
, but this leads to a fundamental problem: you no longer send your dependencies to the browser, so your code can't run at all. As you probably know, browsers don't natively support require()
, so your current ignoreNodeModules
function tells Webpack to skip bundling them and leave in the require()
, but the browser doesn't know how to handle it.
If you want to reduce bundle size, consider using Webpack's code splitting so that you only bundle dependencies that are needed for each page/section. Alternatively, you could consider using a browser-side require()
loader such as RequireJS.
Using externals
is only really useful for distributing server-side Node libraries, where you would expect consumers of your library to provide your dependencies rather than bundling them with your library.
The comments on the documentation about externals
are also worth reading for some further context on the issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With