一般前端代码崔主要是为了在浏览器环境运行,
在有服务端渲染的需求的时候, 也会兼容一下代码的加载,
比如同一个 React 组件, 同样可以用于服务端渲染,
而其中涉及到浏览器 API 的代码, 可以选择不执行, 经典的:
if (typeof window != undefined) {
// do something
}
如果是 ClojureScript 当中遇到此类的代码, 也类似:
(if (exists? js/window)
(comment "do soemthing"))
问题
这一次是我引用了一个 https://alertifyjs.org/ 的模块,
这个 js 模块没有处理好. 对, 我是从 ClojureScript 引用了 js 模块,
然后, 在 shadow-cljs 打包完成运行的时候遇到了这样的问题,
ReferenceError: document is not defined
如果是 js, 我在 require("alertify.js")
的写法前面加 if
就好了.
虽然对于 import
语法不能用 if
, 但是打包工具一般都支持 CommonJS 的.
而在 ClojureScript 当中问题比较明显, 因为 ns
是个 Macro,
意味着代码在执行之前会被代码再进行处理, 我是不能随便加 if
的,
(ns app.main
(:require ["alertify.js" :as alertify]))
至少在我没搞清楚 ns
到底展开称为什么样的代码的情况下..
解决方案
于是我想到说用 shadow-cljs 对 js 模块做重定向的功能的做法,
我在打包 :node-script
这个执行脚本的时候, 不要使用 alertify.js
的代码了,
转而使用一个空的 js 文件, 这样就不会去访问 document
然后出错.
参考文档上的用法, 应该是这样写的:
:page {:target :node-script
:output-to "target/page.js"
:js-options {:resolve {"alertify.js" {:target :file
:file "entry/alert-ssr.js"}}}
:main app.page/main!
:devtools {:after-load app.page/main!}}}}
:js-options
是生效的地方, 我把模块指向了一个本地的文件.
不过实际使用遇到的问题, 问了作者, 他在 :node-script
这个环境没开这个选项,
https://clojureverse.org/t/ho...
然后升级到了 2.3.22
版本就支持了, 所以就搞定了.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。