使用Shim来修复require.js并不适用于使用CoffeeScript的play2

时间:2013-07-18 12:02:05

标签: coffeescript playframework-2.0 requirejs

我在Play 2.1.2项目上工作,使用Angular.js,CoffeeScript,require.js和bower来组织前端。 有了凉亭,我在/app/assets/javascripts/main.coffee文件中使用了垫片。 然后,我使用play clean stage部署并运行target/start

问题是:在stage阶段,Play不会使资源变得丑化。 在Build.scala

val main = play.Project(appName, appVersion, appDependencies).settings(
  requireJs += "main",
  requireJsShim += "main.js"
)

然后在阶段丑陋的css之后:

Tracing dependencies for: main
Error: Load timeout for modules: angular-bootstrap,angular
http://requirejs.org/docs/errors.html#timeout
In module tree:
    main
      jquery

Error: Load timeout for modules: angular-bootstrap,angular
http://requirejs.org/docs/errors.html#timeout
In module tree:
    main
      jquery

[info] RequireJS optimization finished.

所以没有任何事情被证实。在main.coffee

require.config
  paths:
    jquery: "lib/jquery/jquery"
    angular: "lib/angular/angular"
    ...
  shim:
    angular: {deps: ["jquery"], exports: "angular"}
    ...

define [
  "angular-bootstrap"
  "angular"
  ...
], ->
  app = angular.module "app"
  ...
  app

它在客户端完美运行,所有路径都是正确的等等。 requireJsShim += "main.js"看起来也是正确的:看起来在编译资产后会发生require.js优化,因此main.coffeemain不起作用。

任何想法问题的根源是什么?有没有人面对它?

3 个答案:

答案 0 :(得分:1)

我有一个使用垫片的example应用程序,我刚回答了一个与你非常相似的问题。简而言之,垫片会覆盖app.build.js文件。

答案 1 :(得分:1)

最终解决了我的问题的是创建自定义shim.coffee,其中包含require.config的一部分:

require.config
  paths:
    jquery: "lib/jquery/jquery"
    angular: "lib/angular/angular"
    ...

没有shim部分。

然后我必须在define子句中明确定义shimmed依赖项并使用requireJsShim += "shim.js" - 与我用于客户端配置的文件不同。

然后uglifying和require.js优化开始工作!

答案 2 :(得分:1)

我遇到了这个问题(几乎;我在我的项目中没有使用CoffeeScript),而且我认为这更容易解决。要重申这个问题:某些JavaScript资源 - 特别是那些在其垫片中没有export设置的资源 - 会产生上面所述的“模块加载超时”。更糟糕的是,问题似乎是短暂的。

从模块中分离RequireJS配置(例如pathsshim)似乎有所帮助,但编译仍然不可靠,并且使得在开发模式下工作更加复杂。

我发现将waitSeconds: 0添加到配置对象有助于可靠的构建。为什么在编译期间甚至可以超时访问本地资源超出我的范围。有关详细信息,请参阅RequireJS API waitSeconds documentation

以下是我的RequireJS模块的片段,位于public/javascripts(您的路径可能会有所不同)。

require({
  /* Fixes an unexplained bug where module loads would timeout
   * at compilation. */
  waitSeconds: 0,

  paths: {
    'angular': '../vendor/angular/angular',
    'angular-animate': '../vendor/angular/angular-animate',
    /* ... */

    'jquery': '../vendor/jquery/jquery'
  },

  shim: {
    'angular': {
      deps: [ 'jquery' ],
      exports: 'angular'
    },

    'angular-animate': ['angular'],
    /* ... */

    'jquery': {
      exports: 'jQuery'
    }
  },

  optimize: 'uglify2',
  uglify2: {
    warnings: false,
    /* Mangling defeats Angular injection by function argument names. */
    mangle: false
  }
})

define(['jquery', 'angular'], function($, angular) {
  /* Angular bootstrap. */
})