Skip to content

Instantly share code, notes, and snippets.

@borkdude
Last active May 4, 2023 03:42
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save borkdude/7e548f06fbefeb210f3fcf14eef019e0 to your computer and use it in GitHub Desktop.
Save borkdude/7e548f06fbefeb210f3fcf14eef019e0 to your computer and use it in GitHub Desktop.
Shadow CLJS require ES Module in script

This shows how to require ES modules in a node script which is itself compiled as an ES module by shadow. I made this to verify if nbb's way of requiring ES modules aligns with other tools that accomplish the same using the CLJS compiler.

Build with npx shadow-cljs compile script. Run with node out/script.js. It will print something like:

#js {:columns 202, :rows 45}
[Function: Spinner]
{
"dependencies": {
"ink-spinner": "^4.0.2",
"react": "^16.14.0",
"shadow-cljs": "^2.15.6",
"term-size": "^3.0.0",
"ws": "^8.2.1"
},
"type": "module"
}
{:source-paths ["src"]
:builds
{:script
{:target :esm
:output-dir "out"
:js-options {:keep-as-import #{"term-size" "ink-spinner"}}
:modules {:script {:init-fn hello.world/main}}}}}
;; place this file in src/hello/world.cljs
(ns hello.world
(:require ["ink-spinner$default.default" :as is] ;; the double default is weird, but it's the only way that worked for me
["term-size$default" :as term-size]))
(defn main []
(prn (term-size))
(.log js/console is))
@thheller
Copy link

thheller commented Sep 1, 2021

The "ink-spinner$default.default" can be explained by the package being written in typescript but only published as commonjs.

https://unpkg.com/browse/ink-spinner@4.0.2/build/index.js

In the early days of commonjs <-> esm interop webpack and others did some "smart" detection as to seemingly make interop easier. See the __esModule marker which was used to make commonjs look like ESM as in it allowed import { thing } from "actually-commonjs". node never did such tricks and only allows import thing from "actually-commonjs". So only one default import which is the object exported by the package, which again only has the default property.

@FreeAgent
Copy link

To get this sample working, I ran:
yarn add ink

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment