I have a library that can be used with both node.js and the browser. I am using CommonJS then publishing for the web version using webpack. My code looks like this:
// For browsers use XHR adapter
if (typeof window !== 'undefined') {
// This adapter uses browser's XMLHttpRequest
require('./adapters/xhr');
}
// For node use HTTP adapter
else if (typeof process !== 'undefined') {
// This adapter uses node's `http`
require('./adapters/http');
}
The problem I am encountering is that when I run webpack (browserify would do the same) the generated output includes http along with all it's dependencies. This results in a HUGE file which is not optimal for browser performance.
My question is how can I exclude the node code path when running a module bundler? I solved this temporarily by using webpack's externals and just returning undefined when including './adapters/http'. This doesn't solve the use case where other developers depend on my library using CommonJS. Their build will end up with the same problem unless they use similar exclude config.
I've looked at using envify, just wondering if there is another/better solution.
Thanks!
You may use IgnorePlugin for Webpack. If you are using a webpack.config.js file, use it like this:
var webpack = require('webpack')
var ignore = new webpack.IgnorePlugin(new RegExp("^(canvas|mongoose|react)$"))
module.exports = {
//other options goes here
plugins: [ignore]
}
To push it further, you may use some flags like process.env.NODE_ENV to control the regex filter of IgnorePlugin
You can use require.ensure for bundle splitting. For example
if (typeof window !== 'undefined') {
console.log("Loading browser XMLHttpRequest");
require.ensure([], function(require){
// require.ensure creates a bundle split-point
require('./adapters/xhr');
});
} else if (typeof process !== 'undefined') {
console.log("Loading node http");
require.ensure([], function(require){
// require.ensure creates a bundle split-point
require('./adapters/http');
});
}
See code splitting for more information and a sample demo usage here
This worked best for me
var _process;
try {
_process = eval("process"); // avoid browserify shim
} catch (e) {}
var isNode = typeof _process==="object" && _process.toString()==="[object process]";
as Node will return true and not only will the browser return false, but browserify will not include its process shim when compiling your code. As a result, your browserified code will be smaller.