Home > Net >  Compute lookup tables at build time in a node/babel/webpack stack for production build
Compute lookup tables at build time in a node/babel/webpack stack for production build

Time:03-21

I'm working on a javascript app using the classic node/babel/webpack stack that makes heavy use of lookup tables. The typical code look like this:

const computeLookupTable = () => {
    // Expensive computation here
};

export const LookupTable = computeLookupTable();

This work well overall, but there is a major downside: the user's device has to do all the precomputation when the app starts. This seems rather unnecessary as the result of the computation will always be the same. It is worth specding some build time for production build to improve the user's experience.

How can I change this behavior, such as computeLookupTable is run during the build process, and directly get the data in there in the generated blob that is shipped to users?

CodePudding user response:

Option 1

Not sure if this is the best way, but you can use Webpack's define plugin to replace the values:

In webpack.config.js:

import webpack from "webpack";
import { LookupTable } from "./computeLookupTable";

module.exports = {
  // ...
  plugins: {
    new webpack.DefinePlugin({
      "lookupResults": JSON.stringfify(LookupTable)
    })
  }
}

Do realize though, that you can't pass functions or anything, just plain objects or primitives. In your code you could just pretend the variable magically exists:

export default function Something() {
  const results = lookupResults;
  return results.data;
}

One caveat is that you have to create a new variable to avoid invalid syntax like { data: "..." }.data, but instead const results = { data: "..." }; results.data.

Option 2

The more obvious and not-as-eeky/natural way to go this is to generate static files before bundling, then allow Webpack to bundle it up for us.

In webpack.config.js:

import fs from "fs";
import webpack from "webpack";
import { LookupTable } from "./computeLookupTable";

module.exports = (staticData => {
  fs.writeFileSync("./src/data/generated.js", "export default "   JSON.stringify(staticData)); // change this to something
  // or with JSON (needs plugin): fs.writeFileSync("./src/data/generated.json", JSON.stringify(staticData));
  return { /* webpack configs... */ };
})(LookupTable);

And then let's say your JS file is src/index.js:

import table from "./data/generated";

// do something with it...
  • Related