> ## Content Index
> Fetch the complete content index at: https://www.jonathancreamer.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# How WebPack decides what entry to load from a package.json
- URL: https://www.jonathancreamer.com/how-webpack-decides-what-entry-to-load-from-a-package-json/
- Published: 2019-05-08T13:04:36.000Z
- Updated: 2019-05-08T13:04:36.000Z
- Author: Jonathan Creamer
- Tags: webpack, mainFields

Today I was working on creating a node.js bundle using webpack 4, and came across a fun little doozie of an error which lead me to do a bit of code spelunkery into how Webpack actually decides on what to load when you `require` something from `node_modules`.

Most `package.json` files have a `main` in them, because it tells the "requirer" of the package what the entry point of the package is.

> The main field is a module ID that is the primary entry point to your program. [https://docs.npmjs.com/files/package.json#main](https://docs.npmjs.com/files/package.json?ref=jonathancreamer.com#main)

Well, there's also a spec for defining other targets, namely the "browser" field.

[https://docs.npmjs.com/files/package.json#browser](https://docs.npmjs.com/files/package.json?ref=jonathancreamer.com#browser)

There is even a proposal to add a "module" field. [https://github.com/dherman/defense-of-dot-js/blob/master/proposal.md](https://github.com/dherman/defense-of-dot-js/blob/master/proposal.md?ref=jonathancreamer.com), which some libraries are already taking advantage of, and Webpack can also understand it.

In terms of Webpack, the 3 most important ones are `main`, `browser`, and `module`.

- `browser` should point to a browser compatible bundle
- `module` should point to a folder of ES modules
- `main` should point to whatever whatever you want the default entry to be

If the `target` of your app is `web` or a few others (which is default). It will look first at the `browser` field, and if it doesn't exist, it'll look for the `module`, and lastly `main`.

```
if (
    options.target === "web" ||
    options.target === "webworker" ||
    options.target === "electron-renderer"
) {
    return ["browser", "module", "main"];
} else {
    return ["module", "main"];
}

```

[https://github.com/webpack/webpack/blob/52184b897f40c75560b3630e43ca642fcac7e2cf/lib/WebpackOptionsDefaulter.js#L336](https://github.com/webpack/webpack/blob/52184b897f40c75560b3630e43ca642fcac7e2cf/lib/WebpackOptionsDefaulter.js?ref=jonathancreamer.com#L336).

If your package is simply only meant to work in the browser, you can get away with only using `main`, but if you're looking to support both the web and node, then take advantage of the `browser` field by pointing it to your browser compatible bundle.

For me what was happening was, there's an import in one of our libraries for `isomorphic-fetch`. Well, since the target is `node` in the Webpack build I was working with, `node-fetch` actually got required. And `node-fetch` requires a library which can't be lazily loaded by Webpack. Aka this issue. [https://github.com/andris9/encoding/issues/18](https://github.com/andris9/encoding/issues/18?ref=jonathancreamer.com).

**tldr; if your Webpack target is `node`, it looks at the `module` and `main` for entry. Otherwise, it goes to the `browser`, then `module`, then `main`.**