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.