You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:57:52