question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

CJS -> ESM interoperability for imports inside external modules loaded from CDN

See original GitHub issue

What version of Next.js are you using?

12.0.7

What version of Node.js are you using?

12.22.6 and above

What browser are you using?

Chrome

What operating system are you using?

macOS

How are you deploying your application?

next start

Describe the Bug

If a CDN esm module uses Head from next/head breaks next dev

Here is a esm module using next/head https://jscdn.teleporthq.io/new-project-68d4/globals.js@0888a7f951f31cc0e33ee614e97d5b6e398ed19c

And it is imported inside https://jscdn.teleporthq.io/new-project-68d4/card.js@edb67533c00984de863a24b4433f30bab9eae03e

Now, if we try to import and use the component. It breaks the render.

import styles from '../styles/Home.module.css'
import Component from 'https://jscdn.teleporthq.io/new-project-68d4/card.js@edb67533c00984de863a24b4433f30bab9eae03e'

const App = () => {

  return (
    <div className={styles.container}>
     <Component />
    </div>
  )
}

export default App

Screenshot 2021-12-07 at 8 08 54 PM

Expected Behavior

Component to load the module and render it without breaking

To Reproduce

Here is a online repl which does the same to reproduce the bug https://replit.com/@JayaKrishnaNamb/nextjs-http#pages/index.js

GitHub repo to reproduce in local https://github.com/teleporthq/nextjs-http

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:2
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
mattcarlottacommented, Dec 8, 2021

And i am not sure if nextjs controls the module-resolution of it’s own. Or just delates to the node one. Because, the same example with styled-components is resolving the same irrespective of imported from the code directly or via CDN module. Here is a example https://codesandbox.io/s/new-project1-forked-z64zx?file=/src/teleporthq/pages/home.js

I believe styled-components works because it does something similar to what I mentioned above in Option C, where the default property is interpolated within the package itself:

styled-components.cjs.js

...
return e && "object" == typeof e && "default" in e ? e.default : e
...

styled-components.js

...
var r="default" in e ? e.default : e
...

next/dist/shared/lib/head.js (doesn’t interpolate default like above)

// returns/builds the obj instead of returning just the default property
function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}

// returns/builds the obj instead of returning just the default property
function _interopRequireWildcard(obj) {
    if (obj && obj.__esModule) {
        return obj;
    } else {
        var newObj = {
        };
        if (obj != null) {
            for(var key in obj){
                if (Object.prototype.hasOwnProperty.call(obj, key)) {
                    var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {
                    };
                    if (desc.get || desc.set) {
                        Object.defineProperty(newObj, key, desc);
                    } else {
                        newObj[key] = obj[key];
                    }
                }
            }
        }
        newObj.default = obj;
        return newObj;
    }
}

On a separate note it appears that imports have some node module resolution. The reason I say some is because you can’t use require within a CDN asset (it’s undefined).

1reaction
JayaKrishnaNamburucommented, Dec 9, 2021

And i am not sure if nextjs controls the module-resolution of it’s own. Or just delegates to the node one. Because, the same example with styled-components is resolving the same irrespective of imported from the code directly or via CDN module. Here is a example https://codesandbox.io/s/new-project1-forked-z64zx?file=/src/teleporthq/pages/home.js

Read more comments on GitHub >

github_iconTop Results From Across the Web

What the heck are CJS, AMD, UMD, and ESM in Javascript?
The loading and parsing for ESM modules is indeed asynchronous, but the execution of the code in them is synchronous and serialized based...
Read more >
Dynamically Import ESM Modules From A CDN - ITNEXT
The URL of the library on the CDN can then be used to dynamically import, await import(cdn) , the functions we are interested...
Read more >
CommonJS (cjs) and Modules (esm): Import compatibility
You can import CommonJS (cjs) into ESM modules, and vice versa (esm into cjs). But one way is easier than the other.
Read more >
ECMAScript modules in browsers - JakeArchibald.com
"Bare" import specifiers aren't currently supported · nomodule for backwards compatibility · Defer by default · Inline scripts are also deferred.
Read more >
ECMAScript modules | Node.js v19.3.0 Documentation
For better compatibility with existing usage in the JS ecosystem, Node.js in ... In most cases, the ES module import can be used...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found