Play에서 맞춤설정된 프로젝트에서 React.js 사용
15385 단어 PlayFrameworkScalaReact
완성형
하고 싶은 것은, 아래와 같은 형태의 프로젝트에서 sbt(activator)의 run 커멘드만으로 Scala와 JSX의 컴파일과 서버 기동을 할 수 있게 되는 것.
절차
reactjs 플러그인
먼저 sbt에서 JSX를 컴파일 할 수있는 플러그인을 사용합니다.
sbt-reactjs
plugins.sbt에 다음을 추가합니다.
plugins.sbtaddSbtPlugin("com.github.ddispaltro" % "sbt-reactjs" % "0.6.8")
이제 sbt에서 JSX를 컴파일 할 수 있습니다.
덧붙여서 디폴트에서는 node.js를 사용해 컴파일하려고 하는 것 같습니다만, 들어가 있지 않아도 js-engine 의 Trireme를 사용하므로 일단 신경쓰지 않아도 좋을 것 같습니다.
프로젝트 설정
조금 큰 제품이 되면 멀티 프로젝트 구성으로 하는 경우가 대부분이라고 생각합니다.
이번에는 Play의 표준 규약이 아니라 독자적인 패키지의 규칙으로 소스 코드를 배치하고 싶습니다.
build.sbtorganization := "my.company"
name := "PlayReact"
version := "1.0"
lazy val commonSettings = Seq(scalaVersion := "2.11.8")
lazy val web = (project in file("web"))
.settings(commonSettings: _*)
.enablePlugins(PlayScala)
.disablePlugins(PlayLayoutPlugin)
.settings(
sourceDirectories in (Compile, TwirlKeys.compileTemplates) := Seq((scalaSource in Compile).value / "my" / "company" / "system"),
sourceDirectories in (Test, TwirlKeys.compileTemplates) := Seq((scalaSource in Test).value / "my" / "company" / "system"),
sourceDirectory in Assets := (scalaSource in Compile).value / "my" / "company" / "system" / "assets",
sourceDirectory in TestAssets := (scalaSource in Test).value / "my" / "company" / "system" / "assets",
resourceDirectory in Assets := baseDirectory.value / "public",
ReactJsKeys.harmony := true,
ReactJsKeys.es6module := true,
ReactJsKeys.stripTypes := true
)
.dependsOn(common)
lazy val common = (project in file("common"))
.settings(commonSettings: _*)
결국 위와 같은 느낌으로 만들었습니다..disablePlugins(PlayLayoutPlugin)
에서 Play 표준 레이아웃을 해제합니다. (app아래에 소스 넣어야 하는 녀석)
또한 Twirl 템플릿의 배치 위치도 조정하고 있습니다.
.jsx
파일은 Assets 취급이므로 sourceDirectory in Assets
로 배치 위치를 조정합니다.
Play는 SbtWeb을 사용하므로 sbt-reactjs를 사용할 때 다시 플러그인을 활성화 할 필요가 없습니다.
JSX 컴파일 옵션은 ReactJsKeys
로 지정할 수 있습니다.
라우팅 설정
routesGET / my.company.system.controllers.Application.index
GET /api my.company.system.controllers.Application.api
GET /assets/*file controllers.Assets.at(path="/public", file)
FQCN에서 클래스명을 지정해야 하는 곳 이외는 특별히 바뀐 것은 없습니다.
컨트롤러와 JSX와 뷰
패키지 이외는 항상 그대로의 컨트롤러입니다.
Application.scalapackage my.company.system.controllers
import my.company.common.Resource
import play.api.libs.json.Json
import play.api.mvc._
class Application extends Controller {
def index = Action {
Ok(views.html.index("Your new application is ready."))
}
def api = Action {
Ok(Json.toJson(new Resource().data)) // Seq("hoge1", "hoge2", "hoge3")
}
}
JSX의 배치 장소는 build.sbt로 지정한 my.company.system.assets
패키지 아래의 javascript
패키지입니다.
코드 내용은 아무런 변형이 없는 JSX 파일입니다.
app.jsxconst DataList = React.createClass({
getInitialState: () => {
return {data: []};
},
componentDidMount: function() {
const self = this;
superagent
.get("/api")
.end(function(err, res){
self.setState({data: res.body});
});
},
render: function() {
const toListItem = x => <li>{x}</li>;
return (
<ul>
{this.state.data.map(toListItem)}
</ul>
);
}
});
ReactDOM.render(
<DataList />,
document.getElementById("main")
);
템플릿은 다음과 같습니다.
JSX로 컴파일 된 것은 @routes.Assets.at("javascripts/ファイル名.js")
로 패스를 얻을 수 있습니다.
index.scala.hml@(title: String)
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
<script src="//fb.me/react-with-addons-0.14.8.min.js"></script>
<script src="//fb.me/react-dom-0.14.8.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/superagent/1.2.0/superagent.min.js"></script>
</head>
<body>
Hello World!!
<div id="main"></div>
<script src="@routes.Assets.at("javascripts/app.js")"></script>
</body>
</html>
실행 결과
http://localhost:9000/ 방문하여 얻은 응답
Hello World!!
reactjs 플러그인
먼저 sbt에서 JSX를 컴파일 할 수있는 플러그인을 사용합니다.
sbt-reactjs
plugins.sbt에 다음을 추가합니다.
plugins.sbt
addSbtPlugin("com.github.ddispaltro" % "sbt-reactjs" % "0.6.8")
이제 sbt에서 JSX를 컴파일 할 수 있습니다.
덧붙여서 디폴트에서는 node.js를 사용해 컴파일하려고 하는 것 같습니다만, 들어가 있지 않아도 js-engine 의 Trireme를 사용하므로 일단 신경쓰지 않아도 좋을 것 같습니다.
프로젝트 설정
조금 큰 제품이 되면 멀티 프로젝트 구성으로 하는 경우가 대부분이라고 생각합니다.
이번에는 Play의 표준 규약이 아니라 독자적인 패키지의 규칙으로 소스 코드를 배치하고 싶습니다.
build.sbt
organization := "my.company"
name := "PlayReact"
version := "1.0"
lazy val commonSettings = Seq(scalaVersion := "2.11.8")
lazy val web = (project in file("web"))
.settings(commonSettings: _*)
.enablePlugins(PlayScala)
.disablePlugins(PlayLayoutPlugin)
.settings(
sourceDirectories in (Compile, TwirlKeys.compileTemplates) := Seq((scalaSource in Compile).value / "my" / "company" / "system"),
sourceDirectories in (Test, TwirlKeys.compileTemplates) := Seq((scalaSource in Test).value / "my" / "company" / "system"),
sourceDirectory in Assets := (scalaSource in Compile).value / "my" / "company" / "system" / "assets",
sourceDirectory in TestAssets := (scalaSource in Test).value / "my" / "company" / "system" / "assets",
resourceDirectory in Assets := baseDirectory.value / "public",
ReactJsKeys.harmony := true,
ReactJsKeys.es6module := true,
ReactJsKeys.stripTypes := true
)
.dependsOn(common)
lazy val common = (project in file("common"))
.settings(commonSettings: _*)
결국 위와 같은 느낌으로 만들었습니다.
.disablePlugins(PlayLayoutPlugin)
에서 Play 표준 레이아웃을 해제합니다. (app아래에 소스 넣어야 하는 녀석)또한 Twirl 템플릿의 배치 위치도 조정하고 있습니다.
.jsx
파일은 Assets 취급이므로 sourceDirectory in Assets
로 배치 위치를 조정합니다.Play는 SbtWeb을 사용하므로 sbt-reactjs를 사용할 때 다시 플러그인을 활성화 할 필요가 없습니다.
JSX 컴파일 옵션은
ReactJsKeys
로 지정할 수 있습니다.라우팅 설정
routes
GET / my.company.system.controllers.Application.index
GET /api my.company.system.controllers.Application.api
GET /assets/*file controllers.Assets.at(path="/public", file)
FQCN에서 클래스명을 지정해야 하는 곳 이외는 특별히 바뀐 것은 없습니다.
컨트롤러와 JSX와 뷰
패키지 이외는 항상 그대로의 컨트롤러입니다.
Application.scala
package my.company.system.controllers
import my.company.common.Resource
import play.api.libs.json.Json
import play.api.mvc._
class Application extends Controller {
def index = Action {
Ok(views.html.index("Your new application is ready."))
}
def api = Action {
Ok(Json.toJson(new Resource().data)) // Seq("hoge1", "hoge2", "hoge3")
}
}
JSX의 배치 장소는 build.sbt로 지정한
my.company.system.assets
패키지 아래의 javascript
패키지입니다.코드 내용은 아무런 변형이 없는 JSX 파일입니다.
app.jsx
const DataList = React.createClass({
getInitialState: () => {
return {data: []};
},
componentDidMount: function() {
const self = this;
superagent
.get("/api")
.end(function(err, res){
self.setState({data: res.body});
});
},
render: function() {
const toListItem = x => <li>{x}</li>;
return (
<ul>
{this.state.data.map(toListItem)}
</ul>
);
}
});
ReactDOM.render(
<DataList />,
document.getElementById("main")
);
템플릿은 다음과 같습니다.
JSX로 컴파일 된 것은
@routes.Assets.at("javascripts/ファイル名.js")
로 패스를 얻을 수 있습니다.index.scala.hml
@(title: String)
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
<script src="//fb.me/react-with-addons-0.14.8.min.js"></script>
<script src="//fb.me/react-dom-0.14.8.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/superagent/1.2.0/superagent.min.js"></script>
</head>
<body>
Hello World!!
<div id="main"></div>
<script src="@routes.Assets.at("javascripts/app.js")"></script>
</body>
</html>
실행 결과
http://localhost:9000/ 방문하여 얻은 응답
Hello World!!
끝
javascript 측은 더 여러 가지 생각이 있을 것 같습니다만, 일단 sbt만으로 Scala와 JSX의 컴파일을 할 수 있게 되었습니다.
실제로 해보면 sbt만으로 프런트 엔드와 백 엔드의 양쪽 모두가 컴파일 & 실행할 수 있어 매우 편합니다.
Reference
이 문제에 관하여(Play에서 맞춤설정된 프로젝트에서 React.js 사용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/maji_KY/items/b63846404fa7367750b0
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Play에서 맞춤설정된 프로젝트에서 React.js 사용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/maji_KY/items/b63846404fa7367750b0텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)