我是Web Worker的新手,现在我要做的是导入我在workerCode in Web Worker下创建的函数,但"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;
};

推荐答案

我认为有两个问题:

  1. 当不涉及Bundle 器时,您必须包括通过importimportScripts导入的模块的完整文件名;本地Web平台不会try 猜测文件扩展名.因此,您需要:

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

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

  2. 我找不到它的具体引用,但我相信当您通过BLOB加载一个Worker时,您不能使用相对导入.四种可能的相互排他性解决方案:

    1. 不要使用Blob.将Worker代码放在其自己的文件中,并使用该文件的URL:

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

      这是一个简单而容易的答案.

    2. 或者,如果只需要在单个站点上运行此代码,则可以像对XLSX库所做的那样使用绝对导入.例如:

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

      或类似的.

    3. 或者,修改workerCode以在创建Blob之前将相对路径替换为绝对路径:

      let workerCode = /*...*/;
      const shared = new URL("../shared", location.href).toString();
      workerCode = workerCode.replace(/from "\.\.\/shared/g, `from ${shared}`);
      // ...build the worker
      
    4. 或者使用self.origin来获取Worker内部的来源(快速测试表明这在Chromium、Firefox和Safari上都有效),然后使用dynamic import.

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

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

Javascript相关问答推荐

如何通过onClick为一组按钮分配功能;

可以的.是否可以在不预编译的情况下使用嵌套 Select 器?

在分区内迭代分区

如何获取转换字节的所有8位?

对象和数字减法会抵消浏览器js中的数字

成帧器运动中的运动组件为何以收件箱开始?

IMDB使用 puppeteer 加载更多按钮(nodejs)

Chart.js V4切换图表中的每个条,同时每个条下有不同的标签.怎么做?

Angular中计算信号和getter的区别

如何在angular中从JSON值添加动态路由保护?

Msgraph用户邀请自定义邮箱模板

如何用拉威尔惯性Vue依赖下拉?

您能在卸载程序(QtInsteller框架)上添加WizardPage吗?

用于在路径之间移动图像的查询

是否可以在Photoshop CC中zoom 路径项?

如何使用抽屉屏幕及其子屏幕/组件的上下文?

Firebase函数中的FireStore WHERE子句无法执行

当一条路由在Reaction路由中命中时,如何有条件地渲染两个组件或更改两个插座?

Google OAuth 2.0库和跨域开放程序的问题-策略错误

如何在预览中显示html+css与数据URL?