如何导入我在Web Worker中创建的函数?

问题描述 投票:0回答:1

我是Web Worker的新手,现在我想做的是导入我在Web Worker中的workerCode下创建的函数,但“import”和“importScript”都不起作用;只有 XLSX 库工作正常,但其余部分则不然。

你能帮我弄清楚该怎么做吗?

export const consolidateWorkerV2 = () => {
 const workerCode = `
 /* Load standalone script from CDN */
 import * as XLSX from "https://cdn.sheetjs.com/xlsx-0.20.1/package/xlsx.mjs";
 import getDataRange from "../shared/util/GetDataRange";
 import modifyWorksheet from "../shared/util/modifyWorksheet.js";
 import headerStyling from "../shared/util/headerStyling";

 self.addEventListener('message', async (e) => {
  try {
    const files = e.data.files;
    const newWorkbook = XLSX.utils.book_new();
    console.log("message received from main thread");
    for (const [index, item] of files.entries()) {
      const file = item.file;
      const filename = item.file.name
      const data = await item.file.arrayBuffer();
      const workbook = XLSX.read(data);
      
      for (const sheetName of workbook.SheetNames) {
        if (newWorkbook.SheetNames.includes(journalType)) {
          const duplicateSheetName = workbook.SheetNames[0];
          const newWorksheet = newWorkbook.Sheets[journalType];
          const dupWorksheet = getDataRange(workbook.Sheets[duplicateSheetName]);
          const OPTIONS = { raw: false, defval: "", };
          const parsedDupWorksheet = XLSX.utils.sheet_to_json(dupWorksheet, OPTIONS);
          const updatedWorksheet = modifyWorksheet(dupWorksheet, parsedDupWorksheet, duplicateSheetName, journalType, reportDate);
          const newData = updatedWorksheet.map((row) => Object.values(row));
          XLSX.utils.sheet_add_aoa(newWorksheet, newData, { origin: -1, skipHeader: true });
        } else {
          // if no existing sheet name, then add new sheet
          for (const sheetName of workbook.SheetNames) {
            const worksheet = workbook.Sheets[sheetName];
            const worksheetData = getDataRange(worksheet);
            const parsedWorksheet = XLSX.utils.sheet_to_json(worksheet, { raw: false, defval: "", });
            const updatedWorksheet = modifyWorksheet(worksheetData, parsedWorksheet, sheetName, journalType, reportDate);
            const styledSheet = headerStyling(updatedWorksheet);
            XLSX.utils.book_append_sheet(newWorkbook, styledSheet, journalType);
          }
        }
      }
    }
    
    const consolidateFilename = namingConvention("Consolidated_Final_Report", date);
    const excelBuffer = XLSX.write(newWorkbook, { bookType: "xlsx", type: "array", });
    const blob = new File([excelBuffer], fileName + ".xlsx");
    postMessage({ blob: blob });   
  } catch(e) {
    /* Pass the error message back */
    postMessage({ error: String(e.message || e).bold() });
  }
}, false);
`;

  const blob = new Blob([workerCode], { type: "text/javascript" });
  const worker = new Worker(URL.createObjectURL(blob), { type: "module" });
  return worker;
};
javascript reactjs web-worker sheetjs
1个回答
0
投票

我看到两个问题:

  1. 当不涉及捆绑程序时,您必须包含通过

    import
    importScripts
    导入的模块的完整文件名;本机网络平台不会尝试猜测文件扩展名。所以你需要:

    import getDataRange from "../shared/util/GetDataRange.js";
    // −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^
    

    ...假设这是资源的完整路径。

  2. 我找不到它的具体引用,但我相信当你通过 blob 加载工作人员时,你不能使用相对导入。四种可能的互斥解决方案:

    1. 不要使用 Blob,为以通常方式加载的工作线程使用单独的脚本:

      const worker = new Worker("./path/to/worker.js", { type: "module" });
      

      这是简单易行的答案。

    2. 如果您只需要在单个站点上运行此代码,请像使用

      XLSX
      库一样使用绝对导入。例如:

      import getDataRange from "https://example.com/shared/util/GetDataRange.js";
      

      或类似的。

    3. 在创建 Blob 之前修改

      workerCode
      以将相对路径替换为绝对路径:

      let workerCode = /*...*/;
      const shared = new URL("../shared", location.href).toString();
      workerCode = workerCode.replace(/from "\.\.\/shared/g, `from ${shared}`);
      // ...build the worker
      
    4. 使用

      self.origin
      获取工作线程中的源(快速测试表明这适用于 Chromium、Firefox 和 Safari)并使用 动态导入

      const getDataRange = (await import(new URL("../shared/util/GetDataRange", self.origin).toString())).default;
      

      我怀疑其他三种解决方案中的任何一种都比这个更好,但同样,它似乎确实适用于主要浏览器。

© www.soinside.com 2019 - 2024. All rights reserved.