Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(0 , import_jspdf_autotable.default) is not a function #1044

Closed
psarno opened this issue Mar 13, 2024 · 10 comments
Closed

(0 , import_jspdf_autotable.default) is not a function #1044

psarno opened this issue Mar 13, 2024 · 10 comments

Comments

@psarno
Copy link

psarno commented Mar 13, 2024

We are experiencing an issue after a deployment today of our Angular 17 project that we did not catch in testing, and we have not been able to reproduce yet locally. I'm trying to determine exactly what is going on.

In the Angular project, we import and use jdfPDF-AutoTable as follows:

    import autoTable, { RowInput } from 'jspdf-autotable';
    
    const doc = new jsPDF('l', 'pt');
     ...
    autoTable(doc, {
      columns: columns.map((col) => ({
        title: col.header,
        dataKey: col.key ?? col.field,
      })),
      body: data as unknown as RowInput[],
      theme: 'striped',
    });

With today's production build, at runtime this now fails with:

(0 , import_jspdf_autotable.default) is not a function

In checking the source that this is transpiling to, I see:

var import_jspdf_autotable = __toESM(require_jspdf_plugin_autotable(), 1);

(0, import_jspdf_autotable.default)(doc, {
      columns: columns.map((col) => ({
        title: col.header,
        dataKey: col.key ?? col.field
      })),
      body: data,
      theme: "striped"
    });

I don't understand why this is suddenly failing for us. I verified that the Angular code has not changed in months, and we do weekly releases. This was working last week. Our package.json and lock files have not changed either, and we run npm ci so this shouldn't be a version issue:

"jspdf": "^2.5.1",
"jspdf-autotable": "^3.5.23",

Does anyone have any insight into what is going on here, and possible a fix or a workaround to get this working again?

@Alijavedofficial
Copy link

Ensure that both jspdf and jspdf-autotable are up to date. Even though your package.json and lock files haven't changed, it's possible that an update was applied to one of these packages without updating the version numbers in your package.json. You can check for updates by running npm outdated and then updating the packages as necessary.

@psarno
Copy link
Author

psarno commented Mar 13, 2024

Ensure that both jspdf and jspdf-autotable are up to date.

I bumped jspdf-autotable to 3.8.2, ran npm i to verify, rebuilt the project for production and deployed it. Same error at runtime.

"jspdf": "^2.5.1",
"jspdf-autotable": "^3.8.2",

What I really am not understanding yet is exactly what changed here. I know the code using this hasn't changed, and I know the versions haven't changed, which at this point I think leaves only the builder? Running this Angular via ng serve locally in both development and production mode has everything working fine on localhost, which also doesn't make much sense.

So I'm unclear on whose issue this even is. For now, the only workaround I can think of is to determine what is wrong with the code that is being transpiled and what (if anything) can be done to work around it.

@Alijavedofficial
Copy link

The issue might be related to changes in how jspdf-autotable exports its functionality. If the library has changed its export mechanism between versions, your import statement might need to be updated to match the new export format.

@Alijavedofficial
Copy link

The problem could also stem from how the Angular build process transpiles the code. Angular uses TypeScript and a set of tools (like Babel or esbuild) to transpile TypeScript code to JavaScript. If there's a mismatch in how these tools interpret the library's exports, it could lead to the error you're seeing.

@mmghv
Copy link
Collaborator

mmghv commented Mar 13, 2024

There's a problem with v3 in angular 17 which causes the plugin to work with serve but not with build due to inconsistency between vite and esbuild, but only when using dynamic imports angular/angular-cli#26888

You shouldn't see this problem with static imports though, try to console.log(autoTable) and see what you get in a production build.

@psarno
Copy link
Author

psarno commented Mar 13, 2024

Yes, I posted the transpiled code in the original post. It's from esbuild.

This clearly has something to do with CommonJS vs. ESM due to that __toESM(() call that's in there. It's possible it's a problem with esbuild but I will have to try the suggestions/workaround there also. The __toESM() call is being emitted with the second parameter set to 1, which indicates isNodeMode, which is wrong in this case. Might be a problem with our Angular config as well.

I'm not sure exactly why this is only a problem with jspdf-autotable. Everything else on a large site is working fine, it's just this one bit of code that is suddenly failing. But I'll report back if this is irrelevant to this library.

I also noticed there is a v4 in the works with changes probably relevant.

@mmghv
Copy link
Collaborator

mmghv commented Mar 13, 2024

Yes, v4 should solve all problems regarding the module system, but I tested with angular 17 and I don't see this problem in a production build, I don't see __toESM() in the output though so it might be a config thing (I'm not an angular dev), I'm interested in reproducing this to test it against v4.

@psarno
Copy link
Author

psarno commented Mar 13, 2024

This has been fixed by removing type: "module" from our package.json, which now results in esbuild emitting working JS in this scenario.

@psarno psarno closed this as completed Mar 13, 2024
@mmghv
Copy link
Collaborator

mmghv commented Mar 13, 2024

Great, was able to reproduce it with type: "module", turned out to be the same problem with the dynamic imports which is caused by esbuild default-interop so in ng build the the default export is available at autoTable.default() while in ng serve it's available at autoTable().

Confirmed that this is solved in v4 where we moved away from the default export and properly exported the EMS version of the library.

@mgohin
Copy link

mgohin commented Dec 10, 2024

If it can help anyone, regarding @mmghv solution, I made a simple function :

// get-autotable.ts
import autoTable from 'jspdf-autotable';

// until its fixed in V4 https://github.com/simonbengtsson/jsPDF-AutoTable/issues/1044
export function getAutoTable() {
  return (typeof autoTable === 'function' ? autoTable : (autoTable as any).default) as (d: jsPDFDocument, options: UserOptions) => void;
}
// other-file.ts
import { getAutoTable } from './get-autotable';

getAutoTable()(jsPdfFile, ...)

Question if someone comes around, is there a type for the autoTable function, did not find it, so I repeated the signature ... as (d: jsPDFDocument, options: UserOptions) => void;.
I found a type export type autoTable = (options: UserOptions) => void; but it does not match the signature.

I use "jspdf-autotable": "^3.8.4"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants