Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack2 node-libs-browser exclude?

I've upgraded to webpack 2 and before tree shaking my bundle size has increased. When investigating why it seems I have large files like bn.js and eliptic (some dependencies of node-libs-browser - which itself is now a dependency of webpack2). Is there any way to remove these or exclude them? In webpack1 they weren't being added to my bundle.

like image 767
CWright Avatar asked Nov 07 '16 14:11

CWright


People also ask

What is node libs browser?

node-libs-browser is a peer dependency of Webpack. As stated in the package page it provides certain Node libraries for browser usage. Obviously modules such as fs won't be available there but you can still use quite a few.

What is __ Dirname in Webpack?

__dirname returns the the directory name of the current module. Let's take a look at some code that uses __dirname . Without webpack. This is what the output of it looks like.

Does Webpack work with node?

Webpack provieds a Command Line Interface (CLI), which we can call as webpack filename. js target/index. js from the terminal; and Node. js API, which we can use in our Node.


Video Answer


1 Answers

The problem is because webpack by default applies its internal plugin NodeSourcePlugin here or here for webworker, and if you have a module that even references a NodeJS module like crypto, ie: var Crypto = canUseDom ? null : require("crypto"), webpack will bundle a bunch of big files to simulate NodeJS. See issue filed here https://github.com/webpack/webpack/issues/4976.

The solution is to avoid any code that references NodeJS internal modules, even if they are not used on the browser.

To catch these, you can remove NodeSourcePlugin by overriding the target option.

const webpack = require("webpack");
const FunctionModulePlugin = require("webpack/lib/FunctionModulePlugin");

const output = {
  path: process.cwd() + "/build",
  filename: "bundle.[hash].js"
};

{
  target: () => undefined,
  output,
  plugins: [
    new webpack.JsonpTemplatePlugin(output),
    new FunctionModulePlugin(output),
    new webpack.LoaderTargetPlugin("web"),
  ]
}

Edit: with webpack 3, it's now as simple as:

const webpackConfig = {
  node: false
}

If you must have code that's for server side only and references NodeJS modules, it's better to separate those into their own module, and export a dummy copy through the browser field in package.json.

Edit: I wrote a blog related to this issue here https://medium.com/walmartlabs/webpack-optimization-a-case-study-92b130334b6c.

like image 164
Joel Chen Avatar answered Oct 03 '22 02:10

Joel Chen