我想在一个使用 CoffeeScript 和 Grunt 的非常大的单页应用程序中实现 RequireJS。我们为不同的模块(服务、Backbone 等)提供了单独的文件。
实现 RequireJS 非常简单——我的主要问题是应用程序的大小和 CoffeeScript 的空白敏感性。我们需要能够在实现 RJS 的同时不断开发新功能。我们不能这样做的原因是我们必须将所有文件包装在定义调用中,并重新标记文件。当您尝试重新设置此代码的基础时,会因制表符而出现大量合并冲突。没有人有时间解决所有这些问题,因为在 RJS 之前可能已经引入了新功能和错误修复。
我研究了一些可能的解决方案:
停止开发并重新标记所有内容。这很糟糕,因为在文件被标记并且代码实际上与 RJS 一起工作之前,开发会停止。
使用 CommonJS 模式,并使用 RJS CommonJS 转换器 pre-RJS 优化。看起来很hacky。
- 使用 CoffeeScript
backtick
功能将 CoffeeScript 类包装在标准 JavaScript 模块模式中。接下来将依赖项传递给 CoffeeScript 类的“模块”包装器,然后在文件中的 RJS 调用中初始化“模块”。
编辑:感谢有关垂直结构的提示并介绍我以这种方式传递函数参数(无逗号)。我们的项目在结构上非常相似(不幸的是,目前除了 grunt-contrib-coffee 进行 linting),我还在构建一个自定义监视任务来编译单个文件(与 glob 模式相比)。
考虑这个非常基本的例子:
view.coffee
:
class View
template: Helper.template
constructor: (@options) ->
render: (meters) ->
$('body').html @template @options
正常的过程是使用 RJS 执行以下操作:
define [
'jQuery'
'Helper'
], (
$
Helper
) ->
class View
template: Helper.template 'base_view'
constructor: (@options) ->
render: (meters) ->
$('body').html @template @options
注意整个类是如何被重新标记的。如果我们的任何一位开发人员出现并修改了View
该类,而我正在尝试并行实现 require ,Git 会讨厌这一点。
反引号的想法行不通,我无法解决那里的全球问题:
`var exports = function($, Helper) {
class View
template: Helper.template
constructor: (@options) ->
render: (meters) ->
$('body').html @template @options
return View }(jQuery, Helper)`
define [
'jQuery'
'Helper'
], (
$
Helper
) ->
return exports($, Helper)
我认为我最好的选择是将所有应用程序功能合并在一起,然后暂停片刻以重新标记每个文件必要的两个空格,所有这些都在一次提交中完成。只要文件的其余部分遵循该模式,CoffeeScript 似乎并不关心缩进从哪里开始(第 0 列与第 2 列)。我们应该能够以这种方式在 RJS 中滑动并逐步实现它,从而防止无法解决的合并冲突。