在构建时在 node/babel/webpack 堆栈中计算查找表以用于生产构建

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

我正在使用大量使用查找表的经典 node/babel/webpack 堆栈开发 javascript 应用程序。典型的代码如下所示:

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

export const LookupTable = computeLookupTable();

这总体上运行良好,但有一个主要缺点:用户的设备必须在应用程序启动时进行所有预计算。这似乎是不必要的,因为计算结果总是相同的。值得为生产构建指定一些构建时间以改善用户体验。

如何更改此行为,例如 computeLookupTable 在构建过程中是 运行,并直接在发送给用户的生成的 blob 中获取其中的数据?

选项 1

不确定这是否是最好的方法,但您可以使用 Webpack 的 define 插件来替换值:

webpack.config.js中:

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

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

但请注意,您不能传递函数或任何东西,只能传递普通对象或基元。在您的代码中,您可以假装变量神奇地存在:

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

需要注意的是,您必须创建一个新变量以避免像 { data: "..." }.data 这样的无效语法,而是 const results = { data: "..." }; results.data.

选项 2

更明显的 not-as-eeky/natural 方法是在打包之前生成静态文件,然后让 Webpack 为我们打包它。

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);

然后假设您的 JS 文件是 src/index.js:

import table from "./data/generated";

// do something with it...