Skip to content

Commit

Permalink
add support for dynamic import()
Browse files Browse the repository at this point in the history
must be hidden from closure to prevent it trying to rewrite
  • Loading branch information
thheller committed Jun 17, 2020
1 parent fced62b commit 4ab18eb
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/dev/demo/esm/a.cljs
@@ -1,5 +1,6 @@
(ns demo.esm.a
(:require ["https://cdn.pika.dev/preact@^10.0.0" :as x]))
(:require
["https://cdn.pika.dev/preact@^10.0.0" :as x]))

(def foo "demo.esm.a/foo")

Expand Down
19 changes: 17 additions & 2 deletions src/main/shadow/build/targets/esm.clj
Expand Up @@ -145,6 +145,12 @@
:entries entries
:default default?)
(cond->
;; closure will try to rewrite dynamic import() calls
;; but its just a regular function so we alias and extern it
;; so closure doesn't rename it.
default?
(update :module-externs conj "shadow_esm_import")

;; REPL client - only for watch (via worker-info), not compile
;; this needs to be in base module
(and default? build-worker?)
Expand Down Expand Up @@ -321,6 +327,9 @@
"globalThis.goog = goog;\n"
"globalThis.shadow$provide = {};"


"globalThis.shadow_esm_import = function(x) { return import(x.startsWith(\"./\") ? \".\" + x : x); }\n"

"let $CLJS = globalThis.$CLJS = globalThis;"
(slurp (io/resource "shadow/boot/esm.js"))

Expand Down Expand Up @@ -352,7 +361,7 @@
polyfill-js
"const $jscomp = {};\n")))

(defn setup-imports [{::build/keys [mode] :as state}]
(defn setup-imports [state]
(update state :build-modules
(fn [modules]
(->> modules
Expand All @@ -374,7 +383,13 @@

(-> mod
(update :module-externs set/union externs)
(update :prepend str-prepend (str imports "\n"))))))
(update :prepend str-prepend (str imports "\n"))
(cond->
;; only create shadow_esm_import if shadow.esm was required anywhere
;; needs to be created in all modules since it must be module local
(get-in state [:sym->id 'shadow.esm])
(update :prepend str "const shadow_esm_import = function(x) { return import(x) };\n"))
))))
(vec)))))

;; in dev all imports must happen in the prepend
Expand Down
18 changes: 18 additions & 0 deletions src/main/shadow/esm.cljs
@@ -0,0 +1,18 @@
(ns shadow.esm)

;; workaround until we can tell the closure-compiler to not rewrite
;; a dynamic import(). we just want to keep it as is to import "foreign"
;; code dynamically at runtime.
;; FIXME: can't use import as name apparantly?
;;
;; (ns foo (:require [shadow.esm :refer (import)]))
;; (defn init []
;; (js/console.log (import "./b.js")))
;; ------------------------- ^------------------------------------------------------
;; Error in phase :compilation
;; Arguments to import must be quoted. Offending spec: ./b.js at line 10 demo / esm/a.cljs
;; --------------------------------------------------------------------------------
(defn dynamic-import
"dynamic import(path) where path is relative to the :output-dir of the build"
[what]
(js/shadow_esm_import what))

0 comments on commit 4ab18eb

Please sign in to comment.