在 nextjs 上使用打字稿时网络工作者无法正确加载
web worker not loading properly when using typescript on nextjs
我正在为我的项目使用 next js,它使用 Webpack 5 进行捆绑。
根据这个 webworkers 我可以使用以下语法来加载我的网络工作者:
new Worker(new URL('./worker.js', import.meta.url));
但是当我使用以下内容时:
new Worker(new URL('./worker.ts', import.meta.url));
它作为媒体类型文件加载到浏览器上,而不是解析 typescript 的导入和导出。关于如何在下一个 js 上解决这个问题有什么建议吗?
我的 tsconfig:
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"baseUrl": ".",
"paths": {
"@/*": ["./*"]
}
},
"exclude": ["node_modules", ".next", "out"],
"include": [
"next-env.d.ts",
"global.d.ts",
"**/*.ts",
"**/*.tsx",
"**/*.mdx",
"**/*.js",
"workers/**/*.ts"
]
}
不确定这是否能准确回答您的问题,但这是我用于 Typescript only web worker 体验的一个选项。我认为它非常简洁并且支持一个很好的基于对象的编码模型,所以也许它满足您的要求?
依赖关系
运行 这些命令:
npm install comlink --save
npm install worker-loader --save-dev
定义网络工作者
将此添加到 typings.d.ts
文件:
declare module 'worker-loader!*' {
class WebpackWorker extends Worker {
constructor();
}
export default WebpackWorker;
}
创建网络工作者
import {expose} from 'comlink';
export class MyWebWorker {
private readonly name: string;
public constructor(name: string) {
this.name = name;
}
public async getData(input: string) : Promise<any> {
return {
message: `Hello from web worker, ${name}, ${input}`;
};
}
}
expose(MyWebWorker);
使用网络工作者
import {wrap, Remote} from 'comlink';
import Worker from 'worker-loader!./mywebworker';
import {MyWebWorker} from './mywebworker';
export class MyConsumingClass {
public async callWebWorker(): Promise<void> {
{
const RemoteChannel = wrap<typeof MyWebWorker>(new Worker());
const webWorker: Remote<MyWebWorker> = await new RemoteChannel("some name");
const data = await webWorker.getData("some input");
console.log(data.message);
}
}
WEBPACK 行为
上面的typings.d.ts文件和worker-loader插件意味着webpack 5会输出一个名为mywebworker.bundle.worker.js
的文件,注意这是小写的。在实际的 webpack 文件中不需要对 worker-loader 的引用,尽管在我的设置中我使用了这种输出格式,这可能会影响 web worker bundle 的名称:
output: {
path: path.resolve(__dirname, '../dist'),
filename: '[name].bundle.js'
}
我正在为我的项目使用 next js,它使用 Webpack 5 进行捆绑。 根据这个 webworkers 我可以使用以下语法来加载我的网络工作者:
new Worker(new URL('./worker.js', import.meta.url));
但是当我使用以下内容时:
new Worker(new URL('./worker.ts', import.meta.url));
它作为媒体类型文件加载到浏览器上,而不是解析 typescript 的导入和导出。关于如何在下一个 js 上解决这个问题有什么建议吗?
我的 tsconfig:
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"baseUrl": ".",
"paths": {
"@/*": ["./*"]
}
},
"exclude": ["node_modules", ".next", "out"],
"include": [
"next-env.d.ts",
"global.d.ts",
"**/*.ts",
"**/*.tsx",
"**/*.mdx",
"**/*.js",
"workers/**/*.ts"
]
}
不确定这是否能准确回答您的问题,但这是我用于 Typescript only web worker 体验的一个选项。我认为它非常简洁并且支持一个很好的基于对象的编码模型,所以也许它满足您的要求?
依赖关系
运行 这些命令:
npm install comlink --save
npm install worker-loader --save-dev
定义网络工作者
将此添加到 typings.d.ts
文件:
declare module 'worker-loader!*' {
class WebpackWorker extends Worker {
constructor();
}
export default WebpackWorker;
}
创建网络工作者
import {expose} from 'comlink';
export class MyWebWorker {
private readonly name: string;
public constructor(name: string) {
this.name = name;
}
public async getData(input: string) : Promise<any> {
return {
message: `Hello from web worker, ${name}, ${input}`;
};
}
}
expose(MyWebWorker);
使用网络工作者
import {wrap, Remote} from 'comlink';
import Worker from 'worker-loader!./mywebworker';
import {MyWebWorker} from './mywebworker';
export class MyConsumingClass {
public async callWebWorker(): Promise<void> {
{
const RemoteChannel = wrap<typeof MyWebWorker>(new Worker());
const webWorker: Remote<MyWebWorker> = await new RemoteChannel("some name");
const data = await webWorker.getData("some input");
console.log(data.message);
}
}
WEBPACK 行为
上面的typings.d.ts文件和worker-loader插件意味着webpack 5会输出一个名为mywebworker.bundle.worker.js
的文件,注意这是小写的。在实际的 webpack 文件中不需要对 worker-loader 的引用,尽管在我的设置中我使用了这种输出格式,这可能会影响 web worker bundle 的名称:
output: {
path: path.resolve(__dirname, '../dist'),
filename: '[name].bundle.js'
}