关于在 ClojureScript 当中引入依赖 document 对象的包(笔记)

一般前端代码崔主要是为了在浏览器环境运行,
在有服务端渲染的需求的时候, 也会兼容一下代码的加载,
比如同一个 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 版本就支持了, 所以就搞定了.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值