mholt / PapaParse

Fast and powerful CSV (delimited text) parser that gracefully handles large files and malformed input
http://PapaParse.com
MIT License
12.44k stars 1.14k forks source link

Error in dynamic import in web component #1008

Open dman777 opened 1 year ago

dman777 commented 1 year ago

I am trying a dynamic import in chrome. I have

      const { default: Papa } = await import('papaparse');
      const csv = Papa.parse(data);

but I get the error Uncaught (in promise) TypeError: Cannot set properties of undefined (setting 'Papa') which traces to the module code

(function(root, factory)
{
    /* globals define */
    if (typeof define === 'function' && define.amd)
    {
        // AMD. Register as an anonymous module.
        define([], factory);
    }
    else if (typeof module === 'object' && typeof exports !== 'undefined')
    {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like environments that support module.exports,
        // like Node.
        module.exports = factory();
    }
    else
    {
        // Browser globals (root is window)
        root.Papa = factory();
    }
    // in strict mode we cannot access arguments.callee, so we need a named reference to
    // stringify the factory method for the blob worker
    // eslint-disable-next-line func-name
}(this, function moduleFactory()

This is being used in the lit element library, which is a web component library using shadow dom. Am I doing anything wrong in the above to cause this error?

dman777 commented 1 year ago

This happens also with a normal import in the browser. This is being done with no typescript or transpiling.... just native ES in browser

troptropcontent commented 1 year ago

Hello,

I am pretty new with javascript

I am working with a rails 7 app, and trying to make this work,

In my script i have :

import Papa from "https://unpkg.com/papaparse@latest/papaparse.min.js";

But in my browser console i have the following error :

SyntaxError: The requested module 'papaparse' does not provide an export named 'default'

Is this the same issue ? 🤔

Any idea of how to make this work ? 🤔

j0sh commented 11 months ago

Getting the same - I wonder if it is because of missing esm support? Eg https://github.com/mholt/PapaParse/issues/939 / https://github.com/mholt/PapaParse/pull/875 (note the workarounds suggested in the #939 don't seem to help with dynamic imports as far as I can tell)

j0sh commented 11 months ago

Here is what worked for me; the relevant parts were taken from https://github.com/mholt/PapaParse/pull/978 (via nix-shell which I use to set up my development environment)

    if ! [ -f papaparse.js ]; then
      curl -Lo papaparse-v5.4.0.zip "https://github.com/mholt/PapaParse/archive/refs/tags/5.4.0.zip"
      unzip papaparse-v5.4.0.zip
      pushd PapaParse-5.4.0
      echo "export default globalThis.Papa;" >> papaparse.js
      sed -i "s/function(root,/function(root=window,/" papaparse.js
      esbuild --minify papaparse.js > ../papaparse.js
      popd
    fi

Now this is working in my project, a Chrome extension:

async function loadPapaParse(){
  const src = chrome.runtime.getURL('papaparse.js');
  const { default:Papa } = await import(src);
  return Papa;
}
TuringTux commented 11 months ago

@j0sh Thanks for the helpful workaround! For future reference, I needed to install esbuild using:

npm install --save-exact --save-dev esbuild

This assumes you already have Node.js pre-installed. I also needed to prefix npx before the esbuild call, i.e. like this:

...
npx esbuild --minify papaparse.js > ../papaparse.js
...

In my client-side JavaScript code, I then needed to write (replacing "/location/of/papaparse.js" with the location of the just-generated file):

import { default as Papa } from "/location/of/papaparse.js"
markg85 commented 3 weeks ago

I was having this issue too. The comment from @TuringTux didn't work for me in a browser context. I had to use this command:

npx esbuild --format=esm --minify papaparse.js > papaparse.min.mjs

And then import as:

import Papa from "/location/of/papaparse.min.mjs"

It does give a parse warning at the npx esbuild time but it works so.. that's good enough for me :)