profiles.clj 中的 :provided 是什么意思?

What does :provided mean in profiles.clj?

Luminus 现在正在创建一个 profiles.clj 内容如下:

{:provided {:env {;;when set the application start the nREPL server on load
                  :nrepl-port "7001"
                  :database-url "jdbc:mysql://localhost:3306/mysqlkorma_dev?user=db_user_name_here&password=db_user_password_here"}}}

:provided 在这里做什么?在 environ 的文档中,它似乎指向有两个条目,一个用于开发,一个用于测试 https://github.com/weavejester/environ.

The :provided profile is used to specify dependencies that should be available during jar creation, but not propagated to other code that depends on your project. These are dependencies that the project assumes will be provided by whatever environment the jar is used in, but are needed during the development of the project. This is often used for frameworks like Hadoop that provide their own copies of certain libraries.

-- Reference

TL;DR提供的配置文件用于profiles.clj作为 dev 配置文件的替代方案,因为如果在那里使用 dev 它将 覆盖整个 dev project.clj.

中指定的配置文件

:provided 最常见的用途是指定在 jar 创建期间应该可用的依赖项,但将由 运行time 环境提供。但是我觉得这里是用来防止profiles.clj中配置的:env(不打算提交到你的源代码库中)被覆盖在 project.clj 中配置的 :env

Luminus 会在 profiles.clj 中使用 :dev 配置文件而不是 :provided,如果不是因为他们已经将内容放入 project.clj:dev 配置文件的 :env 条目中,这将被 [=98 中的内容覆盖=].

参见 this example repo。如果你立即运行它,没有任何变化(在profiles.clj中使用:provided)输出将是:

› lein run
Hello, world
Db config: some:db://localhost

如果在 profiles.clj 中将 :provided 更改为 :dev,则输出更改为:

› lein run
Hello, nil
Db config: some:db://localhost

它们没有合并,但是 profiles.clj 中的 :env 覆盖了 [= 中的 :env 108=]


编辑:我刚刚发现如果在[=中使用:dev,不仅:env条目会被覆盖98=]。整个 :dev 配置文件将被覆盖。这在 profiles documentation:

中有解释

Remember that if a profile with the same name is specified in multiple locations, only the profile with the highest "priority" is picked – no merging is done. The "priority" is – from highest to lowest – profiles.clj, project.clj, user-wide profiles, and finally system-wide profiles.

所以在 profiles.clj 中使用 :provided 是围绕 leiningen 配置文件的合并策略 hack

它至少有一个缺点:如果您需要在 project.clj 中定义一个 :provided 配置文件,以指定将在 运行时间环境它将被profiles.clj.

中定义的环境覆盖

正如@nberger 所说,provided 用于指定类路径中应该可用的依赖项,但将由运行时提供。

一个特殊情况是库,如果包含在您的项目中,则在创建 uberjar 时会弄乱它们的签名。

BouncyCastle的情况就是这样。

所以你的 project.clj 可能看起来像:

:profiles {:dev {:dependencies [[org.bouncycastle/bcprov-jdk15on "1.50"]]}
           :provided {:dependencies [[org.bouncycastle/bcprov-jdk15on "1.50"]]}}

在这种情况下,您说对于开发,您可以使用 maven 存储库中的库,但在运行时,它必须由环境提供。

所以原始 jar 文件原样,必须存在于类路径中:

java -cp bcprov-jdk15on-151.jar:your-standalone.jar clojure.main