如何在Play 2.3.1模板中启用压缩的JavaScript文件?

14

我能够在我的Play Framework 2.3.1应用程序中加载sbt-uglify 1.0.3插件。加载未压缩的JavaScript文件非常简单,但似乎无法加载已压缩的版本。

在我的模板中,我使用类似于以下内容的 <script> 标签:

<script src="@routes.Assets.at("javascripts/app.js")"></script>
在开发模式下,加载的是非压缩的JavaScript版本,这很好。在生产模式下(使用activator start),我看到sbt-uglify会将压缩版本生成到target/web/uglify/build文件夹中,但由于我没有更改模板中上述<script>标签行,因此加载的是非压缩版本的JavaScript文件。
是否有一种方式可以对这些路由进行生产环境专用映射,以加载压缩版本?
1个回答

23

在Play 2.3.1中修复了Reverse Router should use minified assets in production automatically的问题,这正好符合您的要求。

根据Play 2.3.1更新日志

Assets反向路由的行为已经改变,如果存在文件的minified版本,它现在会返回一个URL。要禁用此行为,请在application.conf中设置assets.checkForMinified=true

注意,应该是set assets.checkForMinified=false,但无论如何...

以下内容仅在生产模式下工作,请使用activator start而不是run启动应用程序,或者使用生成的启动脚本(在stage之后)。

在具有@routes.Assets.versioned(而不是routes.Assets.at)的Play版本中,默认情况下应启用使用minified版本的资源文件的行为。

要求在conf/routes中正确声明路由:

GET  /assets/*file  controllers.Assets.versioned(path="/public", file: Asset)
起初我有些不明确的是pipelineStages中元素的顺序以及包括sbt-rjs的要求。
之后我在Play 2.3 迁移指南中的“RequireJS”部分中找到了关于顺序的说明:
“阶段的顺序很重要。您首先需要优化文件,生成它们的摘要,然后生成所有结果资产的gzip版本。”
我还在Play 2.3 迁移指南的“Closure Compiler”部分中发现了以下内容:
“UglifyJS 2目前通过RequireJS插件(下面描述)提供。未来的意图是为那些不使用RequireJS的情况也提供独立的UglifyJS 2插件。”
这一切始于对Play 2.3 sbt-web plugin Javascript minification的回答。
因此,下面的pipelineStages是有效的-注意顺序和rjs
pipelineStages := Seq(rjs, uglify, digest, gzip)

project/plugins.sbt 文件的使用如下:

resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"

addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.5")

addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.0.0")

addSbtPlugin("com.typesafe.sbt" % "sbt-uglify" % "1.0.3")

addSbtPlugin("com.typesafe.sbt" % "sbt-gzip" % "1.0.0")

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

不要忘记创建一个空的app/assets/javascripts/main.js文件,让sbt-rjs发挥作用。

作为测试,我使用activator new playApp play-scala创建了一个Play应用程序,并在构建和app/views/main.scala.html中应用了上述更改,最终如下所示(请注意@routes.Assets.versioned):

@(title: String)(content: Html)

<!DOCTYPE html>

<html>
    <head>
        <title>@title</title>
        <link rel="stylesheet" media="screen" href="@routes.Assets.versioned("stylesheets/main.css")">
        <link rel="shortcut icon" type="image/png" href="@routes.Assets.versioned("images/favicon.png")">
        <script src="@routes.Assets.versioned("javascripts/hello.js")" type="text/javascript"></script>
    </head>
    <body>
        @content
    </body>
</html>

执行activator start并调用curl http://localhost:9000会得到以下结果(为了易读性,格式由我稍作修改):

➜  play-uglify  curl http://localhost:9000

<!DOCTYPE html>

<html>
    <head>
        <title>Welcome to Play</title>
        <link rel="stylesheet" media="screen" href="/assets/stylesheets/d41d8cd98f00b204e9800998ecf8427e-main.css">
        <link rel="shortcut icon" type="image/png" href="/assets/images/84a01dc6c53f0d2a58a2f7ff9e17a294-favicon.png">
        <script src="/assets/javascripts/4302136334616ae0605d47a1932ee262-hello.min.js" type="text/javascript"></script>
    </head>
    <body>
        <h1>Your new application is ready.</h1>
    </body>
</html>

请注意4302136334616ae0605d47a1932ee262-hello.min.js和非JavaScript资源的摘要。


我也想使用uglify。但是,我不知道如何在Play中开始。如果您有示例,可以分享吗? - JMC
2
我按照你的描述,将uglify、digest和gzip添加到了项目和pipelineStages中。我还在视图中将'@routes.Assets.at'更改为'@routes.Assets.versioned'。使用'activator start'启动我的应用程序会生成压缩后的JavaScript文件,但浏览器仍然加载原始的非压缩版本。 - nyuwec
嗨@Jacek,我按照你提到的所有步骤进行了操作。但是当我执行activator start命令时,我遇到了以下错误。[info] Done packaging. java.util.regex.PatternSyntaxException: Unmatched closing ')' near index 47 ['"]?([^\s'"]*)['"]?\s*:\s*[\[]?.*['"].*/lib\(.*)['"] - Harmeet Singh Taara
这一切都运行良好(非常感谢!),但是存在一个小问题。Play默认提供缩小版本(这很好),但原始源代码也可以公开访问,位于/assets/javascripts/private-javascript-file.js.src.js。有没有办法删除这些文件,只保留缩小和.map文件? - icl7126
我不确定,建议您将此问题作为后续问题提出。我认为这个问题值得在SO上提问。加油! - Jacek Laskowski
所以我通过在build.sbt中禁用源映射生成,使用RjsKeys.generateSourceMaps := false成功地从最终构建中删除了原始未压缩的.js源文件。 - icl7126

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接