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

如何在不同ClojureScript项目中使用通用依赖与自定义Reagent组件?

Handling Shared Dependencies & Reusing ClojureScript Reagent Components

Great question! Manually copying compiled files works for a quick test, but as you've noticed, shared dependencies can lead to bloated bundles or subtle version conflicts. Let's break down how to fix this and adopt a cleaner, scalable workflow for reusing your Reagent component across projects.

First: Fixing Duplicate Dependencies

Right now, when you compile your component project and copy the output, you're probably bundling shared libraries like Reagent or React along with your component. This means if the host project also uses those tools, you'll end up with duplicate copies in the final bundle—wasting space and potentially causing bugs from mismatched versions.

The Solution: Mark Shared Dependencies as "Provided"

Instead of bundling common libraries into your component's output, tell your build tool that these dependencies will be supplied by the host project. Here's how to do it with popular tools:

For Shadow-CLJS (Recommended)

In your component project's shadow-cljs.edn, mark shared dependencies with :scope "provided":

{:dependencies [
  [reagent "1.2.0" :scope "provided"]
  ;; Add other shared libs here (e.g., react, react-dom)
 ]
 :builds {:my-component-library
          {:target :library
           :output-dir "dist"
           :exports {:slider-view my.reagent.component/slider-view}}}}

When you compile with shadow-cljs compile my-component-library, the output won't include Reagent or other provided dependencies—those will come directly from the host project.

For Leiningen/Figwheel-Main

In your project.clj, use the :provided profile to exclude shared dependencies from your component's bundle:

(defproject my-reagent-component "0.1.0"
  :dependencies [[org.clojure/clojurescript "1.11.60"]]
  :profiles {:provided {:dependencies [[reagent "1.2.0"]]}}
  :cljsbuild {:builds [{:id "library"
                        :source-paths ["src"]
                        :compiler {:output-to "dist/my-component.js"
                                   :optimizations :advanced
                                   :output-wrapper true}}]})

Second: Stop Manually Copying Files—Use Proper Library Distribution

Manual file copying is error-prone and hard to maintain. Instead, turn your component into a reusable Clojure library that other projects can depend on directly:

Option 1: Publish to Clojars (Standard Approach)

This is the best way to share your component with other teams or the community:

  1. Set up your component project with a project.clj or deps.edn (following the provided dependency setup above).
  2. Use lein deploy (Leiningen) or clojure -X:deps deploy (deps.edn) to publish your library to Clojars.
  3. In the host project, add your component as a dependency:
    ;; deps.edn example
    {:deps {my-reagent-component {:mvn/version "0.1.0"}}}
    
    Your build tool will automatically fetch the component and resolve dependencies without duplication.

Option 2: Local Development (For Testing)

If you're still iterating on the component, link it locally instead of publishing:

  • For deps.edn: Add a local path dependency:
    {:deps {my-reagent-component {:local/root "../path-to-your-component-project"}}}
    
  • For Leiningen: Use :checkout-deps to link the local project directly.

Bonus: Ditch JS Interop for Native CLJS Imports

Instead of calling your component via JS interop:

(.slider-view (.-views js/swipe) (clj->js [[:p "1"] [:p "2"] [:p "3"]]))

You can import it as a native ClojureScript namespace once it's a proper library:

(ns host-project.core
  (:require [my.reagent.component :as slider]))

;; Use the component naturally, like any other Reagent component
[slider/slider-view [[:p "1"] [:p "2"] [:p "3"]]]

This is cleaner, more idiomatic, and avoids JS interop friction.

Third: Best Practices for Shared Dependencies Across Projects

To avoid version conflicts and keep things consistent:

  • Lock Dependency Versions: Use a shared dependency file (e.g., a company-wide deps.edn or Leiningen profile) that defines versions for common libraries (Reagent, React, etc.). All projects reference this file to ensure everyone uses the same versions.
  • Use Dependency Overrides: If a host project needs a different version of a shared dependency, use your build tool's override feature. For deps.edn:
    {:override-deps {reagent "1.2.0"}}
    
    For Leiningen, use :exclusions and re-declare the dependency with your desired version.
  • Test Compatibility: Make sure your component library works with a range of dependency versions (e.g., Reagent 1.1.x to 1.2.x) to reduce friction for host projects.

内容的提问来源于stack exchange,提问作者Verbery

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:21:43