I have a TensorFlow.js model that I want to use both in the browser and from a script run at the command line via Node. The model is defined in a CommonJS module, so I can easily load it in both environments. I am using Webpack to bundle the browser app. But I can’t figure out how to load the appropriate version of TensorFlow.js. I want to use tfjs-node
when running the script, but tfjs
in the browser.
I tried using dynamic import to load the right module at runtime, but this forces me to use a CDN for tfjs
, since it’ll be loading it in the browser. What I want to do is build my app using tfjs
, but require
the model into an independent Node script, and use tfjs-node
in that context. This must be a reasonably common scenario, but I cannot see a way to do it. What am I missing?
Edit: I’m thinking maybe I can achieve this by bundling for both the browser and node? That’s possible using the target
property in webpack.config.js
. It’s possible to specify multiple targets. But how to set the version of TensorFlow.js for each target? Possibly by aliasing the relevant package within each target config? So I would just use the same alias, but it would map to tfjs
for the browser target config, and tfjs-node
in the Node target config.
2
Answers
I did find a way to sort of achieve what I want to do using npm package aliasing, with multiple
package.json
s. Basically the idea is to installtfjs
with an alias (say, tfjs), in the top-levelpackage.json
, as in:Then have a
scripts
subfolder with a secondpackage.json
, with just the following contents:Then
cd
into thescripts
folder and executenpm install
. This will create a newnode_modules
folder under scripts, with@tensorflow/tfjs-node
aliased totfjs
.It works... but I don't really like it as a solution. Mainly because of having to
npm install
a second time, to create a newnode_modules
.OK, I eventually found a satisfactory way to achieve this using environment variables.
It’s possible to pass environment variables to Webpack and access them during the compilation process, so their values can be substituted into your code. We need to modify
webpack.config.js
to do this, in the following way:We need to define the exported config object as a function, so any environment variables passed via the command line are accessible via the
env
argument. Then we use Webpack’sDefinePlugin
to make the environment variables available in our code at compile time. Here we are exposing the variableTFJS
, passed via the command line inpackage.json
like this:So in the file where I define my model I
require
TensorFlow like this:For the build file Webpack will substitute
@tensorflow/tfjs
. The neat thing is if werequire
this module directly in a node script we can access a different value forprocess.env.TFJS
, passed via the command line. This is what I am doing:So inside the script
process.env.TFJS
will be set totfjs-node
, which will be interpolated into therequire
call. It works! Neat.