Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The SitePoint post titled “Uncaught ReferenceError: Function is not defined” actually reports two different errors: an inline button handler cannot find generatePDF, and a browser module import cannot resolve the bare package name jspdf. Neither message, as quoted in the post, shows that JavaScript’s built-in Function constructor is missing. Fix the handler’s scope and the module’s package resolution separately.

What errors did the SitePoint post actually report?

The title uses the phrase “Function is not defined,” but the post’s specific console messages are Uncaught ReferenceError: generatePDF is not defined and Uncaught TypeError: Failed to resolve module specifier "jspdf". Relative references must start with either "/", "./", or "../". These indicate distinct problems: the button cannot access a function declared in a module, and the browser cannot locate an import written as a bare package name. They do not establish that the built-in Function constructor is unavailable.

The post concerns a Django page using jsPDF and jsPDF-AutoTable, but the errors described are browser-side JavaScript issues. Changing Python code would not, by itself, make a module-scoped function visible to an inline handler or tell the browser how to resolve jspdf.

Why an inline handler cannot see a module function

JavaScript modules have their own scope. A function declared inside a <script type="module"> script is not automatically placed on the page’s global object, so an HTML attribute such as onclick="generatePDF()" cannot necessarily look it up by name. MDN’s JavaScript modules guide describes module scope and how modules differ from classic scripts.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The original post also mentions an onload variant. The reported generatePDF is not defined message is consistent with a handler trying to find a name that remains inside module scope.

Recommended fix: attach the click handler inside the module

Give the button an ID, then select it and register the function from the same module where the function is declared. This keeps the function in module scope and avoids using an inline handler just to call it.

<button id="download-pdf">Download PDF</button>

<script type="module">
  import { jsPDF } from "YOUR_RESOLVED_JSPDF_IMPORT";
  import { autoTable } from "YOUR_RESOLVED_AUTOTABLE_IMPORT";

  function generatePDF() {
    const doc = new jsPDF();
    autoTable(doc, { html: "#your-table" });
    doc.save("table.pdf");
  }

  document
    .getElementById("download-pdf")
    .addEventListener("click", generatePDF);
</script>

The import strings above are deliberately not file paths: the correct values depend on how the project installs and serves its JavaScript. Keep the actual imports consistent with that setup.

Alternative: expose the function globally

If an inline handler must remain, explicitly attach the function to the global object after declaring it in the module:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
window.generatePDF = generatePDF;

Then an inline handler can call generatePDF(). This is a quick compatibility option, but it exposes the function globally and creates a name that other page scripts can collide with. The module-local listener avoids that extra global name. MDN’s functions guide covers functions and their use with event listeners.

Why the browser cannot resolve the bare import “jspdf”

A browser loading native JavaScript modules needs imports it can resolve to URLs. A specifier such as jspdf is a bare specifier, not a relative or absolute URL. Browsers need an import map that maps the name to a URL, or the project needs a build environment—such as a bundler—that resolves package names before serving the code. Without either, the browser reports that relative references must start with /, ./, or ../. See MDN’s section on bare module specifiers.

Choose the resolution method that matches the page’s delivery setup:

  • Bundled application: install the packages and use the project’s build process so package imports are resolved into browser-loadable output.
  • Native browser modules: use browser-resolvable module URLs, or define an import map that maps names such as jspdf to URLs.
  • Static-file or CDN setup: use the module files and paths actually available to the page. A package name alone does not tell the browser where those files are.

The jsPDF-AutoTable project README documents npm installation with npm install jspdf jspdf-autotable and includes usage examples. That supports a package-based workflow, but installing the packages does not by itself configure a browser to resolve bare imports. The original post does not establish its bundler, static-file layout, or package versions, so its exact import paths cannot be inferred.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Keep the two fixes separate

Console message What it points to What to check
generatePDF is not defined The inline handler cannot access the module-scoped function. Register the click listener inside the module, or explicitly expose the function on window if an inline handler is required.
Failed to resolve module specifier "jspdf" The browser has no configured way to map the bare package name to a module URL. Check the bundler or configure browser-resolvable URLs or an import map.

Changing the event handler does not resolve a missing package import, and changing the import path does not make a module-local function globally visible. Address the message that appears at each stage.

What the thread does not establish

The original post appeared on June 11, 2020, with replies and a closing comment on June 12, 2020. The poster later said PyCharm did not recognize a path to a file under node_modules and wondered whether Python was involved. The thread does not confirm a cause or resolution for that editor complaint, so it should not be treated as the explanation for either browser error. The forum reply’s example illustrates the listener approach, but does not establish the original project’s paths or prove that its code ran unchanged in the poster’s setup.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.