How to bundle browser only code(in Node.js) in shadow-cljs?

I’m importing https://github.com/alertifyjs/alertify.js in my project, meanwhile I also use the code for page rendering in Node.js , while threw an error during page rendering, because alertify.js is using document, which is not in Node.js :

w"),t.classList.add("hide"),t.addEventListener("transitionend",o),setTimeout(o,e)}};if("undefined"!=typeof module&&module&&module.exports){module.exports=function(){return new t};var n=new t;for(var i in n)module.exports[i]=n[i]}else"function"==typeof define&&define.amd?define(function(){return new t}):window.alertify=new t}();
                                                    ^
ReferenceError: document is not defined
    at new t (/Users/chen/repo/memkits/copycat/node_modules/alertify.js/dist/js/alertify.js:1:53)
    at /Users/chen/repo/memkits/copycat/node_modules/alertify.js/dist/js/alertify.js:1:11133
    at Object.<anonymous> (/Users/chen/repo/memkits/copycat/node_modules/alertify.js/dist/js/alertify.js:1:11274)
    at Module._compile (internal/modules/cjs/loader.js:654:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
    at Module.load (internal/modules/cjs/loader.js:566:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
    at Function.Module._load (internal/modules/cjs/loader.js:498:3)
    at Module.require (internal/modules/cjs/loader.js:598:17)
    at require (internal/modules/cjs/helpers.js:11:18)
}
cp entry/manifest.json dist/
{:exit 0, :out , :err }

What does shadow-cljs suggest I do in this case?

For now I’m trying to replace that module with an empty file:

:js-options {:resolve {"alertify.js" {:target :file
                                      :file "entry/alert-ssr.js"}}}

I think there’s a problem… :js-options does not redirect the module alertify.js in my build. My code https://github.com/Memkits/copycat/pull/1/commits/dc9c5fd2eac1d85312044f9a9bc646afebf28576

What’s worse, when I tried to misspell :resolve intentionally as :resolv, shadow-cljs does not find that it’s incorrect.

Using Reader Conditionals is currently the most reliable solution as it was introduced to fix exactly this problem.

I still need to figure out how to do :resolve properly for node. It can work in your situation but it would fail for transitive dependencies.

;; this works
(ns my.app
  (:require ["alertify.js" :as alert]))

;; this doesn't
(ns my.app
  (:require ["something-that-requires-alertify.js-internally" :as x]))

Same problem with reader conditionals though so it should be fine.

I just released shadow-cljs@2.3.22 which enables the use of :resolve for :js-provider :require.

Documented the limitations here.

1 Like

Thanks for the update. Will try tonight.

It works~

Made me curious, shadow-cljs does not throw warnings when my file is actually providing a wrong alertify object. So it’s not checking when I do that…

What do you mean? JS exports are never checked or validated. Warnings are only generated for CLJS code.

1 Like

That makes sense! …

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.