3

I have NodeJS code that I now need to move to an embedded system. It takes far too long to simply start NodeJS ("Hello World" ~11sec on a BeagleBone Black) so we needed an alternative. The IoT.js looks promising but it does not support some of the internal NodeJS modules (e.g. url, zlib, tty)--which my code needs. I am using Webpack 5.35.0 to create a single file for my code but this is where my problems lie. I want to use Webpack with a node target since IoT.js offers most of what node offers natively. However is there a way to force Webpack to use polyfills for some of the modules? For example, browserify-zlib instead of expecting nodes zlib.

My basic Webpack configuration is simple:

{ target: 'node10.17',
  entry: './index.js',
  output:
   { filename:      'index.js',
     path:          '/work/proj/dist',
     libraryTarget: 'umd' },
  stats: 'errors-only',
  resolve:
   { modules:    [ '/work/proj/node_modules' ],
     extensions: [ '.js', '.json' ],
   }
}

I have done some reading where people claim adding a simple resolve.fallback.zlib = false and resolve.alias should do the trick--which is not working for me.

I tried to simply add resolve.fallback.zlib = false in the hopes to just have zlib omitted from the Webpacked output and this did not work. No matter what I do the standard Webpack boilerplate "node" zlib include code exists.

Standard Webpack boilerplate when using node target.

/***/ "zlib":
/*!***********************!*\
  !*** external "zlib" ***!
  \***********************/
/***/ ((module) => {

"use strict";
module.exports = require("zlib");;

/***/ })

Other things I tried were--ALL of which did not work:

I was hoping this would alias zlib and actually put in the browserify-zlib code.

resolve:
   { modules:    [ '/work/proj/node_modules' ],
     extensions: [ '.js', '.json' ],
     alias:      { zlib: '/work/proj/node_modules/browserify-zlib/lib/index.js' },
     fallback:   {} } }

Same as the previous example but thought by disabling the fallback the alias/polyfill would go into the output. This is what others online had success with.

resolve:
   { modules:    [ '/work/proj/node_modules' ],
     extensions: [ '.js', '.json' ],
     alias:      { zlib: '/work/proj/node_modules/browserify-zlib/lib/index.js' },
     fallback:   { zlib: false } } }

Here I just hoped to not include zlib to see if Webpack would omit it with a node target.

resolve:
   { modules:    [ '/work/proj/node_modules' ],
     extensions: [ '.js', '.json' ],
     fallback:   { zlib: false } } }

Lastly I tried to use the plugin node-polyfill-webpack-plugin but with the node target it does not seem to do anything. If I chose a web target the plugin seems to work as I'd expect (taken from here). Again, I'd prefer a node target so it uses native modules and the setup seems cleaner; but maybe this is the only approach. If this is the approach then how to support fs and other non-browser modules that IoT.js supports natively?

...
plugins = [ new NodePolyfillPlugin({ excludeAliases: [] }) ];

It seems that when the node target is selected there is no way to override any of the default/boilerplate code added to the output file. Does anyone have experience with IoT.js and Webpack, or overriding the default Webpack 5 code for node and use a polyfill instead? Not sure if a Webpack plugin is an approach. I am a little new to Webpack. Could this be a problem with Webpack? Any help would be appreciated.

piezontm
  • 103
  • 6
  • Did you find solution for this? I am in the same boat: I am using es2019 as my target and want to run the compiled bundle in QuickJS, which is lacking some built-in modules that I need polyfilled. – F21 Oct 11 '22 at 04:26

0 Answers0