使用Vite构建时TypeScript编写的Web Worker未被编译为JavaScript
我在TypeScript中这样使用Web Worker:
const url = new URL("src/lib/Functions/CalculateRidge.ts", import.meta.url); const worker = new Worker(url, { type: 'module' })
开发环境下代码运行正常,Worker能从指定URL加载并正确执行函数返回结果。但执行构建后,除Worker文件外,其他所有文件都被转换为.js格式。部署到Github Pages后,执行上述代码时URL请求成功,但出现以下错误:
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "video/mp2t". Strict MIME type checking is enforced for module scripts per HTML spec.
我认为错误源于TypeScript文件(.ts扩展名)无法被执行或读取,核心问题是Web Worker的TypeScript文件未被编译转换为JavaScript。
构建后的dist目录结构如下:
我使用vite build构建项目,npx gh-pages -d dist部署到Github Pages。相关配置文件如下:
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()], resolve: { alias: { src: path.resolve('src/'), } }, })
tsconfig.node.json
{ "compilerOptions": { "composite": true, "module": "ESNext", "moduleResolution": "Node" }, "include": ["vite.config.ts"] }
tsconfig.json
{ "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { "baseUrl": ".", "target": "ESNext", "useDefineForClassFields": true, "module": "ESNext", "resolveJsonModule": true, "paths": { "src/*": [ "src/*" ] }, /** * Typecheck JS in `.svelte` and `.js` files by default. * Disable checkJs if you'd like to use dynamic types in JS. * Note that setting allowJs false does not prevent the use * of JS in `.svelte` files. */ "allowJs": true, "checkJs": true, "isolatedModules": true }, "include": ["src/*.ts","src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], "references": [{ "path": "./tsconfig.node.json" }] }
svelte.config.js
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' export default { // Consult https://svelte.dev/docs#compile-time-svelte-preprocess // for more information about preprocessors preprocess: vitePreprocess(), }
问题核心是Vite默认不会把你通过new URL引入的.ts文件纳入构建流程,导致打包后仍保留原扩展名;而Github Pages服务器对.ts文件返回的MIME类型不符合浏览器对模块脚本的要求,最终触发报错。
方法一:用Vite官方推荐的Worker引入方式(优先选择)
将Worker文件通过带后缀的import引入,让Vite自动处理编译、打包:
import WorkerUrl from 'src/lib/Functions/CalculateRidge?worker&module' const worker = new Worker(WorkerUrl, { type: 'module' })
?worker&module后缀会告知Vite这是一个模块类型的Web Worker,工具会自动将其编译为.js文件,并处理内部依赖。
方法二:配置Vite强制处理.ts资源
如果不想修改代码逻辑,可在vite.config.ts中添加assetsInclude配置,让Vite把.ts文件当作静态资源处理并编译:
export default defineConfig({ // ...原有配置 assetsInclude: ['**/*.ts'], })
这种方式不如方法一可靠,Vite可能无法正确处理Worker内部的TypeScript语法和依赖,仅作为备选方案。
验证修复
修改后重新执行vite build,检查dist目录下是否生成了对应的Worker.js文件,再重新部署到Github Pages即可解决MIME类型错误。
内容的提问来源于stack exchange,提问作者Ólavur Nón

