플레이 프레임워크 2.2.x:프로덕션에서 정적 자산 위치가 작동하지 않습니다.

StackOverflow https://stackoverflow.com//questions/22018817

문제

프로덕션 환경에서 컴파일된 자산 위치에 액세스하는 데 문제가 있습니다.

내 전략은 개발 중에는 "app/assets/ui"에 자산을 제공하고 프로덕션에서는 "public"에 자산을 제공하는 것이었습니다. 이는 아래 conf/routes 파일에 표시된 대로 수행됩니다.

#{if(play.Play.mode.isDev())}
  GET     /assets/*file    controllers.common.Assets.at(path="/app/assets/ui", file)
#{/}
#{else}
  GET     /assets/*file controllers.common.Assets.at(path="/public", file)
#{/}

"공개" 외부에서 자산 매핑을 정의했으므로 Build.scala에 다음 줄을 추가했습니다.

playAssetsDirectories <+= baseDirectory / "app/assets/ui"

예를 들어 내 스크립트는 아래와 같이 환경에 따라 조건부로 로드됩니다.

@if(play.Play.isDev()) {<script src="@routes.Assets.at("/app/assets/ui", "javascripts/application.js")"type="text/javascript"></script>} else {<script src="@.routes.Assets.at("/public", "javascripts/application.min.js")" type="text/javascript"></script>}

저는 프런트엔드 작업 흐름에 Grunt를 사용하고 있으며 애플리케이션이 빌드될 때 배포 파일을 애플리케이션의 공용 폴더에 복사합니다.다음을 사용하여 프로덕션에서 앱을 시작합니다. "sbt clean compile stage" 그런 다음 패키지된 앱을 실행합니다.

내 문제는 경로가 여전히 배포 "public" 폴더 대신 "app/assets/ui" 폴더를 참조하고 있는 것 같습니다.

이것을 디버깅하는 방법에 대한 팁이 있습니까?내 근무 배경은 프런트 엔드 개발자이므로 Play를 처음 접했습니다!그리고 스칼라.

도움이 되었습니까?

해결책

@estmatic이 언급했듯이 조건부 routes 평가되지 않습니다.

일반적으로 응용 프로그램 간의 차이점을 통합하는 것이 매우 유용합니다. Mode을 파일로 저장하려면 확장하는 것이 좋습니다. GlobalSettings (아직 그렇지 않은 경우) onLoadConfig 방법:

class Settings extends GlobalSettings {

  override def onLoadConfig(config: Configuration, path: File, classloader: ClassLoader, mode: Mode.Mode): Configuration = {

    val specificConfig:Config =  // ... Use the mode param to load appropriate file        

    super.onLoadConfig(specificConfig, path, classloader, mode)
  }
  ...
}

그런 다음 적절한 이름의 파일을 가질 수 있습니다(dev.conf 그리고 production.conf 떠오르는 것) 적절한 값을 포함하며 그 중 하나가 기본입니다. path 자산 컨트롤러가 사용할 수 있습니다.

EDIT는 이런 식으로 사용하는 것으로 나타났습니다. routes 어색합니다. 또 다른 접근 방식이 있습니다.

이 접근 방식은 환경별 구성 파일을 사용하지 않습니다. 즉, 프런트엔드 구성에서 무언가 변경된 경우(예:더 이상 제공되지 않습니다. /public) 이 코드를 변경하고 다시 배포해야 합니다.그러나 Play 2.x에는 꽤 잘 맞습니다.

package controllers

object EnvironmentSpecificAssets extends AssetsBuilder {

  val modeToAssetsPathMap = Map(
    Mode.Dev -> "/app/assets/ui",
    Mode.Prod -> "/public")

  lazy val modePath = modeToAssetsPathMap(Play.current.mode)

  /** New single-argument `at`, determines its path from the current app mode */
  def at(file:String): Action[AnyContent] = at(modePath, file)
}

코드는 설명이 매우 간단합니다. 유일한 "트릭"은 아마도 lazy val 즉, 현재 작동 모드를 평가하고 지도 조회를 한 번만 수행하면 됩니다.

이제 당신의 routes 파일은 다음과 같습니다:

GET   /assets/*file     controllers.EnvironmentSpecificAssets.at(file)

다른 팁

Playframework 2.x는 경로 파일에서 조건문을 지원하지 않습니다.1.x 버전에는 이 기능이 있었지만 제거되었습니다.

경로 파일에 있는 것은 단순히 동일한 URI 패턴을 가진 두 개의 경로입니다. /assets/file*.다른 줄은 파운드 문자로 시작하므로 주석으로 무시됩니다. #.패턴이 동일하기 때문에 첫 번째 경로는 모든 것을 잡는 것이고 두 번째 경로는 아무것도 하지 않는 것 같습니다.

정확히 당신이 하려는 일은 아니지만 경로 패턴을 약간 다르게 만들면 작동할 것이라고 생각합니다.

GET   /assets/dev/*file   controllers.common.Assets.at(path="/app/assets/ui", file)
GET   /assets/*file       controllers.common.Assets.at(path="/public", file)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top