Rollup/Vite 在构建时包含 GeoTiff.js 和 Web Worker 时出现错误。

huangapple go评论59阅读模式
英文:

Rollup/Vite build error when including GeoTiff.js and Web Worker in build

问题

我正在使用Web Worker对GeoTiff文件进行计算。我从CalculateRidge.ts调用函数getRidgePoints,该函数创建一个Worker,向Worker发送消息,然后等待Worker返回结果,最后,在获取结果后终止Worker并返回结果。Worker被包装在一个"await"-函数中(我听说过Comlink,但我找到了这个解决方案,它很有效)。

Worker有一个addEventListener,执行函数CreateRidge_Init来进行计算。此函数加载GeoTiff文件,读取并根据从该文件中读取的值进行计算。

我的问题是:

此代码无法构建。尝试构建代码时出现以下错误:

错误 [RollupError]: 选项"output.format"的值"iife"无效 - 不支持UMD和IIFE输出格式用于代码拆分构建。
    在错误 (file:///C:/Users/ono/Documents/Programmering/solar-analysis-faroe-island/node_modules/rollup/dist/es/shared/node-entry.js:2125:30)
    在验证多块输出的选项时发生错误 (file:///C:/Users/ono/Documents/Programmering/solar-analysis-faroe-island/node_modules/rollup/dist/es/shared/node-entry.js:17493:16)
    在Bundle.generate (file:///C:/Users/ono/Documents/Programmering/solar-analysis-faroe-island/node_modules/rollup/dist/es/shared/node-entry.js:17384:17)
    在async (file:///C:/Users/ono/Documents/Programmering/solar-analysis-faroe-island/node_modules/rollup/dist/es/shared/node-entry.js:25683:27)
    在async catchUnfinishedHookActions (file:///C:/Users/ono/Documents/Programmering/solar-analysis-faroe-island/node_modules/rollup/dist/es/shared/node-entry.js:24770:20)
    在async serialBundleWorkerEntry (file:///C:/Users/ono/Documents/Programmering/solar-analysis-faroe-island/node_modules/vite/dist/node/chunks/dep-d305c21f.js:22316:61) {
  code: 'PLUGIN_ERROR',
  url: 'https://rollupjs.org/configuration-options/#output-format',
  pluginCode: 'INVALID_OPTION',
  plugin: 'vite:worker',
  hook: 'transform',
  id: 'C:/Users/ono/Documents/Programmering/solar-analysis-faroe-island/src/lib/Functions/CalculateRidgeWorker.ts?worker&url',
  watchFiles: [
    ... 项目中使用的几乎所有文件 ...
]

我尝试了不同的方法,注意到使用GeoTiff.js (fromArrayBuffer().getImage())与Web Worker的组合引起了错误:

  • 如果我绕过Web Worker,并在主线程上执行CreateRidge_Init,则构建成功。
  • 如果我在Web Worker中不使用fromArrayBuffer().getImage(),则构建成功。

我尝试了调整build.rollupOptions设置,但构建时没有错误变化。我想补充一点,在开发过程中,代码完全正常运行。

CalculateRidge.ts:

import workerUrl from "src/lib/Functions/CalculateRidgeWorker?worker&url";
import type { Pos, Point } from "../Stores";

// 调用Worker的函数。
export async function getRidgePoints(pos: Pos) {

  // 创建一个Worker
  const worker = new Worker(workerUrl, { type: 'module' })

  // 向Worker发送一个值。
  worker.postMessage(pos)

  // 等待Worker处理发送的值并接收计算出的值。
  const result = await runWorker(worker);

  // 终止Worker。
  worker.terminate();

  return result
}

// 一个等待函数,等待来自Worker的消息
function runWorker(worker: Worker): Promise<Point[]> {
  return new Promise(resolve => {
    worker.onmessage = (e: MessageEvent<Point[]>) => {
      resolve(e.data)
    }
  })
}

CalculateRidgeWorker.ts:

addEventListener('message', async (e: MessageEvent<Pos>) => {
  let pos = e.data;
  let points = await getRidgePoints_Init(pos)
  postMessage(points)
})

// 如果我绕过Web Worker,在主线程上执行这个函数,代码就会成功构建。
async function getRidgePoints_Init(pos_m: Pos) {

  const DSM_Base = new URL(import.meta.url)
  const DSM_25M = new URL('FO_DSM_2017_FOTM_25M_DEFLATE_UInt16.tif', DSM_Base.origin);
  const DSM_5M = new URL('FO_DSM_2017_FOTM_5M_DEFLATE_UInt16.tif', DSM_Base.origin);

  // 加载25M分辨率地图。
  let image_25M = await fetch(url)
    .then(response  => response.arrayBuffer())
    .then(tiff      => fromArrayBuffer(tiff)) // 如果我在Web Worker中注释掉这两行,代码就能成功构建。
    .then(result    => result.getImage())     // 如果我在Web Worker中注释掉这两行,代码就能成功构建。

  ... 根据这个文件进行很多计算 ...
  
  return result
}

我的当前vite.config.ts文件:

import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
import path from 'path';

// https://vitejs.dev/config/
export default defineConfig({
  base: "/solar-analysis-faroe-island/",
  plugins: [svelte()],

  build: {
    rollupOptions: {
      output: {
        format: "esm",
        inlineDynamicImports: true,
      }
    }
  },

  resolve: {
    alias: {
      src: path.resolve('src/'),
    }
  },
})
英文:

I am using a Web Worker to do calculation on a GeoTiff file. I call the function getRidgePoints from CalculateRidge.ts, and this function creates a worker, posts the message to the worker, and then awaits a result from the worker, and finally, terminates the worker after the result is gotten and returns the result. The worker is being wrapped in a "await"-function (i have heard about Comlink, but i found this solution and it works great).

The worker has an addEventListener that executes the function CreateRidge_Init that will do the calculations. This function loads a GeoTiff file, reads it and does calculation based on values read from this file.

My problem is:

This code wont build. I get the following error when trying to build the code:

Error [RollupError]: Invalid value &quot;iife&quot; for option &quot;output.format&quot; - UMD and IIFE output formats are not supported for code-splitting builds.
    at error (file:///C:/Users/ono/Documents/Programmering/solar-analysis-faroe-island/node_modules/rollup/dist/es/shared/node-entry.js:2125:30)
    at validateOptionsForMultiChunkOutput (file:///C:/Users/ono/Documents/Programmering/solar-analysis-faroe-island/node_modules/rollup/dist/es/shared/node-entry.js:17493:16)
    at Bundle.generate (file:///C:/Users/ono/Documents/Programmering/solar-analysis-faroe-island/node_modules/rollup/dist/es/shared/node-entry.js:17384:17)
    at async file:///C:/Users/ono/Documents/Programmering/solar-analysis-faroe-island/node_modules/rollup/dist/es/shared/node-entry.js:25683:27
    at async catchUnfinishedHookActions (file:///C:/Users/ono/Documents/Programmering/solar-analysis-faroe-island/node_modules/rollup/dist/es/shared/node-entry.js:24770:20)
    at async serialBundleWorkerEntry (file:///C:/Users/ono/Documents/Programmering/solar-analysis-faroe-island/node_modules/vite/dist/node/chunks/dep-d305c21f.js:22316:61) {
  code: &#39;PLUGIN_ERROR&#39;,
  url: &#39;https://rollupjs.org/configuration-options/#output-format&#39;,
  pluginCode: &#39;INVALID_OPTION&#39;,
  plugin: &#39;vite:worker&#39;,
  hook: &#39;transform&#39;,
  id: &#39;C:/Users/ono/Documents/Programmering/solar-analysis-faroe-island/src/lib/Functions/CalculateRidgeWorker.ts?worker&amp;url&#39;,
  watchFiles: [
    ... basicly all the files used in this project ...
]

I have tested different things, and i notice that it is the combination of using both GeoTiff.js (fromArrayBuffer() and .getImage()) and a Web Worker that causes the error:

  • If i bypass the Web Worker and execute CreateRidge_Init on the main thread, the build works.
  • If i do not use fromArrayBuffer() and .getImage() in the Web Worker, the build works.

I have tried to play around with the build.rollupOptions settings, but with no error change in the build. I want to add, that the code works perfectly fine in development.

CalculateRidge.ts:

import workerUrl from &quot;src/lib/Functions/CalculateRidgeWorker?worker&amp;url&quot;;
import type { Pos, Point } from &quot;../Stores&quot;;

// The function calling the worker.
export async function getRidgePoints(pos: Pos) {

  // Create a worker
  const worker = new Worker(workerUrl, { type: &#39;module&#39; })

  // Send a value to the worker.
  worker.postMessage(pos)

  // Wait for the worker to process the sent value and recieve the calculated value.
  const result = await runWorker(worker);

  // Terminate the worker.
  worker.terminate();

  return result
}

// An await function that will wait for a message from the worker
function runWorker(worker: Worker): Promise&lt;Point[]&gt; {
  return new Promise(resolve =&gt; {
    worker.onmessage = (e:MessageEvent&lt;Point[]&gt;) =&gt; {
      resolve(e.data)
    }
  })
}

CalculateRidgeWorker.ts:

addEventListener(&#39;message&#39;, async (e:MessageEvent&lt;Pos&gt;) =&gt; {
  let pos = e.data;
  let points = await getRidgePoints_Init(pos)
  postMessage(points)
})

// If i bypass the web worker, and execute this function on
// the main thread, the code does build succesfully.
async function getRidgePoints_Init(pos_m: Pos) {

  const DSM_Base = new URL(import.meta.url)
  const DSM_25M = new URL(&#39;FO_DSM_2017_FOTM_25M_DEFLATE_UInt16.tif&#39;, DSM_Base.origin);
  const DSM_5M = new URL(&#39;FO_DSM_2017_FOTM_5M_DEFLATE_UInt16.tif&#39;, DSM_Base.origin);

  // Load the 25M resolution map.
  let image_25M = await fetch(url)
    .then(response  =&gt; response.arrayBuffer())
    .then(tiff      =&gt; fromArrayBuffer(tiff)) // If i comment out these two lines when using a
    .then(result    =&gt; result.getImage())     // web worker, the code does build succesfully.

  ... Does alot of calculations based on this file ...

  return result
}

My current vite.config.ts file:

import { defineConfig } from &#39;vite&#39;
import { svelte } from &#39;@sveltejs/vite-plugin-svelte&#39;
import path from &#39;path&#39;;

// https://vitejs.dev/config/
export default defineConfig({
  base: &quot;/solar-analysis-faroe-island/&quot;,
  plugins: [svelte()],

  build: {
    rollupOptions: {
      output: {
        format: &quot;esm&quot;,
        inlineDynamicImports: true,
      }
    }
  },

  resolve: {
    alias: {
      src: path.resolve(&#39;src/&#39;),
    }
  },
})

答案1

得分: 0

I tried to change the output format in the rollup options, but I was supposed to change the format for the worker itself (I did not know there was a .worker option). This vite.config.js file solved the error, and now the project is successfully building and working:

import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
import path, { resolve } from 'path';

// https://vitejs.dev/config/
export default defineConfig({
  base: "/solar-analysis-faroe-island/",
  plugins: [svelte()],

  worker: {
    format: "es"
  },

  resolve: {
    alias: {
      src: path.resolve('src/'),
    }
  },
})
英文:

I tried to change the output format in the rollup options, but i was supposed to change the format for the worker itself (i did not know there was a .worker option). This vite.config.js file solved the error, and now the project is succesfully building and working:

import { defineConfig } from &#39;vite&#39;
import { svelte } from &#39;@sveltejs/vite-plugin-svelte&#39;
import path, { resolve } from &#39;path&#39;;

// https://vitejs.dev/config/
export default defineConfig({
  base: &quot;/solar-analysis-faroe-island/&quot;,
  plugins: [svelte()],

  worker: {
    format: &quot;es&quot;
  },

  resolve: {
    alias: {
      src: path.resolve(&#39;src/&#39;),
    }
  },

})

huangapple
  • 本文由 发表于 2023年4月19日 14:44:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76051452.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定