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

前端之家收集整理的这篇文章主要介绍了关于在 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 版本就支持了,所以就搞定了.

原文链接:https://www.f2er.com/javaschema/282217.html

猜你在找的设计模式相关文章