Figwheel环境变量配置:如何在CLJS代码中区分构建环境?
嘿,这个需求完全能搞定!Figwheel结合Leiningen(也就是你的project.clj)其实有专门的机制来处理这种不同构建/环境下的变量配置,下面我给你一步步拆解实现方法:
1. 在
project.clj中定义构建专属变量 核心是利用ClojureScript编译器的:closure-defines配置项——它允许你为不同构建环境指定常量,这些常量会在编译阶段直接替换到CLJS代码里,非常适合API端点、调试开关这类环境专属值。
举个具体的例子,假设你有dev(开发)和prod(生产)两个构建,在project.clj里可以这么配置:
(defproject my-app "0.1.0-SNAPSHOT" :dependencies [[org.clojure/clojure "1.11.1"] [org.clojure/clojurescript "1.11.60"] [com.bhauman/figwheel-main "0.2.18"]] :cljsbuild {:builds [{:id "dev" :source-paths ["src"] :figwheel {:open-urls ["http://localhost:3449/index.html"]} :compiler {:main my-app.core :output-to "target/public/js/app.js" :output-dir "target/public/js/out" ;; 开发环境专属常量 :closure-defines {my.app.config/API_ENDPOINT "http://localhost:3000/api" my.app.config/DEBUG true}}} {:id "prod" :source-paths ["src"] :compiler {:main my-app.core :output-to "target/public/js/app.js" :optimizations :advanced ;; 生产环境专属常量 :closure-defines {my.app.config/API_ENDPOINT "https://api.myapp.com/prod" my.app.config/DEBUG false}}}]})
2. 在CLJS代码中访问这些变量
首先你需要在CLJS代码里先声明这些常量(方便Closure编译器识别替换),比如新建一个src/my/app/config.cljs:
(ns my.app.config) ;; 先空声明变量,编译时会被project.clj里的值替换 (def API_ENDPOINT nil) (def DEBUG nil)
之后在其他业务代码里直接引用即可,比如src/my_app/core.cljs:
(ns my-app.core (:require [my.app.config :as config])) (println "当前使用的API端点:" config/API_ENDPOINT) ;; 开发环境下才打印调试日志 (when config/DEBUG (println "调试模式已开启,正在输出详细日志..."))
3. 进阶技巧:用系统环境变量动态配置
如果不想把敏感值(比如生产API密钥)硬写在project.clj里,还可以结合系统环境变量动态读取:
;; 在prod构建的:closure-defines里这样写 :closure-defines {my.app.config/API_ENDPOINT (or (System/getenv "PROD_API_ENDPOINT") "https://api.myapp.com/fallback")}
这样编译生产版本时,会优先读取系统环境变量PROD_API_ENDPOINT的值,没有的话就用默认的 fallback 值。
注意事项
- 确保CLJS里的变量是用
def声明的(不能是defn或其他形式),这样Closure编译器才能正确完成常量替换,尤其是在:advanced优化模式下,还会自动移除无用的调试代码。 - 如果你用的是Figwheel Main(新版Figwheel),也可以把
:closure-defines放在figwheel.edn的对应构建配置里,效果是一样的。
内容的提问来源于stack exchange,提问作者Dennis Hackethal
相关产品推荐
相关产品推荐

