Angular项目加载自有Webpack库的Web Worker报404问题求助
Angular加载Webpack库的Web Worker报404问题解决
问题描述
我在Angular应用中使用自行开发的Webpack库,构建库时执行npm run build && npm pack,dist目录正确生成两个文件:
- lib.js:库核心代码
- 408.lib.js:Worker代码
通过npm i ../lib/lib-1.0.0.tgz将库导入Angular应用后,库与Worker文件已存在于应用的node_modules/lib文件夹中,但调用库的Worker时出现404错误,原因是Angular未暴露该库的Worker文件。
解决步骤
1. 调整Webpack库的构建配置,固定Worker文件名
修改库的webpack.config.js,添加Worker文件的处理规则,避免哈希命名导致路径无法预测:
const Path = require('path'); module.exports = { entry: './src/index.js', output: { path: Path.resolve(__dirname, 'dist'), filename: 'lib.js', globalObject: 'this', library: { name: 'webpackNumbers', type: 'umd' } }, module: { rules: [ { test: /worker\.js$/, type: 'asset/resource', generator: { filename: 'worker.js' // 固定输出为worker.js,方便后续引用 } } ] } };
2. 库的package.json声明Worker文件为公开资源
在库的package.json中添加files字段,确保Worker文件被包含到npm包中:
{ "name": "lib", "version": "1.0.0", "description": "", "private": true, "main": "dist/lib.js", "files": [ "dist/lib.js", "dist/worker.js" ], "scripts": { "build": "webpack --mode production" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "webpack": "^5.91.0", "webpack-cli": "^5.1.4" } }
3. 配置Angular,将库的Worker文件加入资源列表
修改Angular项目的angular.json,在build的assets中添加Worker文件的复制规则,让Angular构建时将其复制到可访问的目录:
{ "projects": { "app": { "architect": { "build": { "options": { "assets": [ "src/favicon.ico", "src/assets", { "glob": "worker.js", "input": "./node_modules/lib/dist", "output": "./assets/lib" } ] } } } } } }
4. 更新库中Worker的创建路径
修改库的src/index.js,调整Worker的加载路径,指向Angular输出的资源位置:
// 指向Angular复制后的Worker文件路径 const worker = new Worker(new URL('/assets/lib/worker.js', window.location.origin)); export function testWorker() { worker.postMessage({ question: 'The Answer to the Ultimate Question of Life, The Universe, and Everything.', }); worker.onmessage = ({ data: { answer } }) => { console.log(answer); }; }
原始相关代码
库的原始webpack.config.js
const Path = require('path'); module.exports = { entry: './src/index.js', output: { path: Path.resolve(__dirname, 'dist'), filename: 'lib.js', globalObject: 'this', library: { name: 'webpackNumbers', type: 'umd' }, } };
库的原始package.json
{ "name": "lib", "version": "1.0.0", "description": "", "private": true, "main": "dist/lib.js", "scripts": { "build": "webpack --mode production" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "webpack": "^5.91.0", "webpack-cli": "^5.1.4" } }
库的原始src/index.js
const worker = new Worker(new URL('./worker.js', import.meta.url)); export function testWorker() { worker.postMessage({ question: 'The Answer to the Ultimate Question of Life, The Universe, and Everything.', }); worker.onmessage = ({ data: { answer } }) => { console.log(answer); }; }
库的原始src/worker.js
self.onmessage = ({ data: { question } }) => { self.postMessage({ answer: 42, }); };
Angular应用的原始app.component.ts
import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; import * as lib from 'lib'; @Component({ selector: 'app-root', standalone: true, imports: [RouterOutlet], templateUrl: './app.component.html', styleUrl: './app.component.css' }) export class AppComponent { title = 'app'; constructor() { lib.testWorker(); } }
内容的提问来源于stack exchange,提问作者Tim Autin
相关产品推荐
相关产品推荐

