【问题标题】:How can sbt-web output be used with xsbt-web-plugin via a SBT project dependency?如何通过 SBT 项目依赖项将 sbt-web 输出与 xsbt-web-plugin 一起使用?
【发布时间】:2015-05-23 03:27:24
【问题描述】:

我正在尝试使用没有播放框架的 sbt-web 插件,而是使用 xsbt-web-plugin 构建一个 webapp。

我已经让 sbt-web 插件在处理资产管道时正常工作,并让它创建一个有效的 webjar 输出(通过 packageBin)以及标准的“web/public/main”输出(通过资产)。

另外,我一直在使用 xsbt-web-plugin 开发一个 webapp 并从 SBT 中提供该 webapp(通过 container:start)。 webapp 项目可以使用来自 mavenCentral 的 webjar 依赖项,并毫无问题地引用这些资源。

我无法弄清楚的是如何让 xsbt-web-plugin 将来自 sbt-web 管道的资产包含在 Web 应用程序中。看来我能做的最好的就是让它们进入 CLASSPATH。 (据我了解,这就是游戏所需要的全部,因为他们有一个“资产控制器”,可以从 CLASSPATH 中为这些资产提供服务,因此不需要将它们作为静态资产提供给 Web 应用程序)。

我创建了一个公开的 GitHub 存储库 (https://github.com/MartinSnyder/serving-sbt-web-output) 来展示我正在尝试做的事情。

我的 plugins.sbt 是:

resolvers += Resolver.typesafeRepo("releases")

addSbtPlugin("com.typesafe.sbt" % "sbt-web" % "1.1.1")

addSbtPlugin("com.typesafe.sbt" % "sbt-less" % "1.0.6")

addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "1.0.0")

我的 build.sbt 是:

name := "Example project serving sbt-web output from within SBT"

organization in ThisBuild := "com.martinsnyder"

version in ThisBuild := "0.0.1"

scalaVersion in ThisBuild := "2.11.6"

lazy val example_webjar =
  project
    .in(file("example_webjar"))
    .settings(libraryDependencies ++= Seq("org.webjars" % "requirejs" % "2.1.16"))
    .enablePlugins(SbtWeb)

lazy val example_webapp =
  project
    .in(file("example_webapp"))
    .dependsOn(example_webjar)
    .settings(libraryDependencies ++= Seq(
      "javax.servlet" % "servlet-api" % "2.5" % "provided",
      "org.eclipse.jetty" % "jetty-webapp" % "9.3.0.M2" % "container",
      "org.eclipse.jetty" % "jetty-plus"   % "9.3.0.M2" % "container",
      "commons-logging" % "commons-logging" % "1.2" % "container"
    ))
    .enablePlugins(SbtWeb)
    .settings(jetty(): _*)

webapp 中的 HTML 文件是:

<html>
    <head>
        <title>Example</title>
        <link rel="stylesheet" type="text/css" href="css/main.css">
        <link rel="stylesheet" type="text/css" href="lib/example_webjar/css/main.css">
        <link rel="stylesheet" type="text/css" href="webjar/example_webjar/0.0.1/css/main.css">
        <script src="webjars/requirejs/2.1.16/require.js"></script>
    </head>
    <body>
        <div class="red">Red</div>
        <div class="green">Green</div>
    </body>
</html>

就目前的情况而言,requirejs 已成功提供服务,因为它来自预构建的 webjar。这三个标签都是不同的,并且尝试引用来自 sbt-web 的资产输出失败。

我想要实现的最佳情况是让 sbt-web 插件输出(target/web/public/main/)包含在 xsbt-web-plugin webapp 输出(target/webapp/ )。我会满足于 xsbt-web-plugin 能够以 webjar 的形式访问项目依赖项。

【问题讨论】:

    标签: sbt xsbt-web-plugin sbt-web


    【解决方案1】:

    如果您tell xsbt-web-plugin 使用 sbt-web 的输出作为其 Web 应用程序资源目录,它应该可以帮助您。

    只需将webappSrc in webapp &lt;&lt;= WebKeys.assets in Assets 作为设置添加到您的example_webapp 项目中:

    lazy val example_webapp =
      project
        .in(file("example_webapp"))
        .dependsOn(example_webjar)
        .settings(libraryDependencies ++= Seq(
          "javax.servlet" % "servlet-api" % "2.5" % "provided",
          "org.eclipse.jetty" % "jetty-webapp" % "9.3.0.M2" % "container",
          "org.eclipse.jetty" % "jetty-plus"   % "9.3.0.M2" % "container",
          "commons-logging" % "commons-logging" % "1.2" % "container"
        ))
        .enablePlugins(SbtWeb)
        .settings(jetty(): _*)
        .settings(webappSrc in webapp <<= WebKeys.assets in Assets)
    

    【讨论】:

    • 注意:我实际上对 sbt-web 一无所知,所以让我知道还缺少什么,我会看看我是否可以修补我的答案。
    • 谢谢詹姆斯。这样做。我在那个方向上最接近的尝试是错过了“WebKeys”。对于阅读本文的其他人来说,这种方法的主要限制是只能有一个 webappSrc 文件夹,所以如果你有一个 web.xml,你需要将它塞进“资产”,即使它并不真正属于那里。跨度>
    • 作为参考,Martin 有opened an issue 用于改进 xsbt-web-plugin 对此的支持。
    【解决方案2】:

    issue 被解析之前,以下配置可能有用:

    // To sbt-web: Use 'src/main/webapp' for asset sources
    sourceDirectory in Assets := baseDirectory.value / "src" / "main" / "webapp"
    
    // To xsbt-web-plugin: Use sbt-web output instead of 'src/main/webapp'
    webappSrc in webapp <<= WebKeys.assets in Assets
    

    这将允许您将src/main/webapp 用于您的资产和普通配置文件(例如web.xml)。

    【讨论】:

      【解决方案3】:

      另一种选择是按照https://github.com/earldouglas/xsbt-web-plugin/issues/228 中的建议使用webappPostProcess。这将允许您保留现有的项目结构。

      以下示例会将 sbt-web 生成的所有内容复制到您的战争的“资产”目录中(并覆盖目标目录中的所有重复文件):

      webappPostProcess := {
        import Path._
      
        val assets = (Compile / WebKeys.assets).value
      
        webapp =>
          val tocopy = (assets ** ("*" -- HiddenFileFilter)).get()
          val pairs = tocopy pair rebase(assets, webapp / "assets")
          IO.copy(pairs, true, true, false)
      }
      

      【讨论】:

        猜你喜欢
        • 2014-06-13
        • 2014-12-17
        • 2018-03-20
        • 1970-01-01
        • 1970-01-01
        • 2017-08-22
        • 2017-02-26
        • 2017-08-19
        • 2019-04-11
        相关资源
        最近更新 更多