You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular项目导入pdf-lib出现404 Not Found错误求助

解决Angular中外部JS文件导入pdf-lib的404错误

问题现象

Angular项目中外部JS文件已被成功加载,多数功能正常,但使用pdf-lib模块时出现404错误:

GET http://localhost:4200/node_modules/pdf-lib/dist/pdf-lib.min.js net::ERR_ABORTED 404 (Not Found)

相关代码

出错的外部JS文件(organizer.js)

import * as PDFDocument from '/node_modules/pdf-lib/dist/pdf-lib.min.js';
document.getElementById("download-pdf-lib").addEventListener("click", async function () {
  if (!uploadedPdfData) {
    alert("Please upload a PDF first.");
    return;
  }

  const pdfBytes = await fetch(uploadedPdfData).then((res) => res.arrayBuffer()); // Fetch the PDF and convert to array buffer
  const pdfDoc = await PDFDocument.load(pdfBytes);  // Load the PDF document

  // Function to adjust y-coordinate
  const adjustYCoordinate = (y, pageHeight) => pageHeight - y;

  // Loop through each interaction and add it to the corresponding page
  interactionData.forEach(async (interaction) => {
    const page = pdfDoc.getPages()[interaction.page - 1]; // Get the page (zero-indexed)
    const { height } = page.getSize(); // Get the page height
    const adjustedY = adjustYCoordinate(interaction.y, height); // Adjust the y-coordinate
    // const text = `User ${interaction.user} clicked at (${interaction.x}, ${adjustedY})`;
    console.log(`User ${interaction.user} clicked at (${interaction.x}, ${adjustedY}) on Page Number: ${interaction.page}, Order ${interaction.order}`);

    // Append keywords for each interaction
    keywords.push(`User:${interaction.user}`);
    keywords.push(`Page: ${interaction.page}`);
    keywords.push(`X-axis: ${interaction.x}`);
    keywords.push(`Y-axis: ${interaction.y}`);
    keywords.push(`Order: ${interaction.order}`);
  });
  pdfDoc.setKeywords(keywords); // Set the keywords in the PDF document
  const modifiedPdfBytes = await pdfDoc.save(); // Save the modified PDF
  const blob = new Blob([modifiedPdfBytes], {
    type: "application/pdf",
  }); // Create a blob from the modified PDF
  const url = URL.createObjectURL(blob); // Create a URL for the blob
  const a = document.createElement("a"); // Create an anchor element
  a.href = url;
  a.download = "annotated_pdf.pdf"; // Set the download attribute
  a.click(); // Trigger the download
});

加载外部JS的Angular组件(organizer.component.ts)

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-organizer',
  templateUrl: './organizer.component.html',
  styleUrls: ['./organizer.component.css']
})
export class OrganizerComponent implements OnInit{
  ngOnInit(){
    this.loadScript('assets/organizerjs/organizer.js');
  }
  loadScript(src:string){
    const script=document.createElement('script');
    script.src=src;
    script.type='module'
    document.body.appendChild(script);
  }
}

Angular.json资产配置

"assets": [
              "src/favicon.ico",
              "src/assets",
              {
                "glob": "**/*",
                "input": "./node_modules/pdf-lib/dist/",
                "output": "/node_modules/pdf-lib/dist/"
              }
            ],

pdf-lib版本

"pdf-lib": "^1.5.0",

解决方案

1. 修正Angular资产配置路径

将angular.json中pdf-lib的input路径调整为node_modules/pdf-lib/dist/(去掉开头的./),确保路径相对于项目根目录:

"assets": [
              "src/favicon.ico",
              "src/assets",
              {
                "glob": "**/*",
                "input": "node_modules/pdf-lib/dist/",
                "output": "/node_modules/pdf-lib/dist/"
              }
            ],

修改后重启Angular开发服务,确认资源被正确复制到输出目录。

2. 调整外部JS的导入路径

如果资产配置生效,可保持原有导入路径;若仍有问题,可尝试使用相对路径(假设外部JS在assets/organizerjs/下):

import * as PDFDocument from '../node_modules/pdf-lib/dist/pdf-lib.min.js';

3. 推荐方案:通过Angular组件传递pdf-lib对象

更符合Angular模块规范的做法是在组件中导入pdf-lib,挂载到window对象供外部JS使用:

  • 修改organizer.component.ts:
import { Component, OnInit } from '@angular/core';
import * as PDFDocument from 'pdf-lib';

@Component({
  selector: 'app-organizer',
  templateUrl: './organizer.component.html',
  styleUrls: ['./organizer.component.css']
})
export class OrganizerComponent implements OnInit{
  ngOnInit(){
    // 将PDFDocument挂载到window,让外部JS可访问
    (window as any).PDFDocument = PDFDocument;
    this.loadScript('assets/organizerjs/organizer.js');
  }
  loadScript(src:string){
    const script=document.createElement('script');
    script.src=src;
    script.type='module'
    document.body.appendChild(script);
  }
}
  • 修改organizer.js,去掉import语句,直接使用window.PDFDocument:
document.getElementById("download-pdf-lib").addEventListener("click", async function () {
  if (!uploadedPdfData) {
    alert("Please upload a PDF first.");
    return;
  }

  const pdfBytes = await fetch(uploadedPdfData).then((res) => res.arrayBuffer());
  // 使用window.PDFDocument替代原有导入的对象
  const pdfDoc = await window.PDFDocument.load(pdfBytes);

  // 剩余代码保持不变...
});

4. 确认依赖安装完整

执行以下命令重新安装pdf-lib,确保node_modules中存在完整的dist文件:

npm install pdf-lib@^1.5.0

内容的提问来源于stack exchange,提问作者Syed Shaheer Ali Zaidi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 03:26:08