Skip to content
This repository has been archived by the owner on May 22, 2024. It is now read-only.

Cannot use dynamic imports for ESM packages #869

Closed
pcattori opened this issue Dec 10, 2021 · 6 comments
Closed

Cannot use dynamic imports for ESM packages #869

pcattori opened this issue Dec 10, 2021 · 6 comments
Assignees

Comments

@pcattori
Copy link

- Do you want to request a feature or report a bug?
Bug

- What is the current behavior?
When deploying to Netlify, the deploy itself succeeds, but the deployed site throws errors whenever a dynamic import is encountered.

  • unspecified node_bundler: Error: Cannot find package 'unified' imported from /var/task/netlify/functions/server/build/index.js
  • node_bundler = "esbuild": Error: ENOENT: no such file or directory, open <path to my project>/.netlify/functions-serve/server/src/netlify/functions/languages/abap.tmLanguage.json
  • node_bundler = "esbuild" & external_node_modules = ["unified"]: Error: Must use import to load ES Module: <path to my project>/.netlify/functions-serve/server/src/node_modules/unified/index.js

Locally via netlify dev, things do work when neither node_bundler nor external_node_modules is specified, but does not work on Netlify remotely.

If node_bundler = "esbuild", then I get the ^above errors on routes relying on unified.

- If the current behavior is a bug, please provide the steps to reproduce.

  1. Create a new Remix app npx create-remix@latest
  2. Select "Netlify" as the deployment option
  3. Create a route that imports unified (or any other ESM-only package) dynamically
  4. Deploy to Netlify

I've noticed that locally, when esbuild is used, a .netlify directory is created and the transpiled code has replaced dynamic imports with require calls, causing Error: Must use import to load ES Module.

- What is the expected behavior?

esbuild keeps dynamic imports and does not replace them with require calls.

- Please mention your node.js, and operating system version.

MacOS 11.6.1
Node 14


I've tried debugging this on the Remix side of things, but right now I'm stuck trying to figure out how netlify dev's usage of esbuild is transpiling things such that dynamic imports are replaced by require calls.

@netlify-team-account-1
Copy link
Contributor

netlify-team-account-1 commented Dec 14, 2021

Hey @pcattori, thanks for letting us know of this issue! Looking into it :)

@netlify-team-account-1
Copy link
Contributor

I followed the steps you gave, but didn't set the external_node_modules flag.

This is the dynamic import I added to routes/index.tsx:

Screenshot 2021-12-14 at 14 13 12

Here's my site: https://zisi-869-repor.netlify.app.

I was able to verify this is working by looking at the Function's logs:

Screenshot 2021-12-14 at 14 13 49

You mention node_bundler="esbuild" results in Error: ENOENT: no such file or directory, open <path to my project>/.netlify/functions-serve/server/src/netlify/functions/languages/abap.tmLanguage.json, which makes me suspicious. What's that /languages/abap thing? I didn't find any reference to it in Unified.

Having a full reproduction repository would be helpful, so I know exactly what needs to happen to reproduce the error.

@pcattori
Copy link
Author

pcattori commented Dec 15, 2021

Trying to reproduce here: https://github.com/pcattori/remix-netlify-dynamic-imports .

So far I've just included a dead-simple unified processor:

export const loader = async (): Promise<LoaderData> => {
    const { unified} = await import('unified')
    const { default: remarkParse } = await import('remark-parse')
    const { default: remarkRehype } = await import('remark-rehype')
    const { default: rehypeStringify } = await import('rehype-stringify')

    const transpiler = await unified()
        .use(remarkParse)
        .use(remarkRehype)
        .use(rehypeStringify)

    const html = await transpiler.process('# Hello, Neptune!')
    return { html: String(html) }
}

That is working perfectly fine!

I also tried adding some 1st-party unified plugins (remark-gfm, remark-math, and rehype-katex) and everything works.
Github branch: https://github.com/pcattori/remix-netlify-dynamic-imports/tree/unified
Site for that branch: https://deploy-preview-2--jolly-fermi-8eb7bc.netlify.app/


I'm going to try to replicate my actual unified processor which uses a couple more unified plugins. I have a hunch that the errors could be caused by a 3rd-party plugin. (I think abap.tmLanguage.json might actually be coming from one of those other plugins too)

@pcattori
Copy link
Author

pcattori commented Dec 21, 2021

I was able to get things working by adding shiki to external_node_modules:

[functions]
  node_bundler = "esbuild"
  external_node_modules = ["shiki"]

shiki relys on a bunch of .json files for its (programming) language support as well as for its themes. abap.tmLanguage.json was one of the language files it needed.

The warnings about unified just threw me off.

@kubaracek
Copy link

I freaking love you guys! I did spend half a day trying to fix one of my imports.... Thank you!!!

@personable
Copy link

Thank you SO much @pcattori. Exact same issue with shiki.

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

No branches or pull requests

4 participants