NodeJS + CoffeeScript,根据要求渲染 CoffeeScript 编译的 js

Posted

技术标签:

【中文标题】NodeJS + CoffeeScript,根据要求渲染 CoffeeScript 编译的 js【英文标题】:NodeJS + CoffeeScript, render coffeescript compiled js on request 【发布时间】:2011-07-08 22:20:46 【问题描述】:

我想做的是将以下内容添加到我已经在运行咖啡脚本编写的服务器

app.get '/test.js', (req, res) ->
    render coffee somecoffeefile.coffee

NodeJS、Express 和 Coffeescript 可以实现类似的功能吗?

谢谢!

何塞

【问题讨论】:

【参考方案1】:

coffee-middleware 完全符合我的要求 - 最少的设置,没有生成的文件,而且没有马虎。 当它收到somescript.js 的请求时,它会检查是否有somescript.coffee。如果有,它会编译并发送过来。

安装它:

npm install coffee-middleware

要使用,只需添加

app.use require('coffee-middleware') src: "#__dirname/your/web/root"

在您用于提供静态文件之前。

在“公共”目录中提供文件的简单示例,在发送之前遵守咖啡脚本,并进行彩色日志记录:

app = require('express')()

app.use require('morgan') 'dev'
app.use require('coffee-middleware') src: "#__dirname/views"
app.use require('serve-static') "#__dirname/views"
app.listen 80

使用上面的代码:

mkdir coffeeServer
cd coffeeServer
npm install morgan coffee-middleware serve-static
npm install coffee-script -g

echo 'app = require("express")()
app.use require("morgan") "dev"
app.use require("coffee-middleware") src: "#__dirname/views"
app.use require("serve-static") "#__dirname/views"
app.listen 80' > server.coffee

coffee -c server.coffee
mkdir views
cd views
echo 'console.log "Hello world!"' > script.coffee
cd ..
node server.js

您可以将整个文件复制到终端中,它将设置并运行服务器。

测试:

curl XXX.XXX.XXX.XXX/script.js

最后一点应该吐出来

(function() 
  console.log("Hello world!");

).call(this);

//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NyaXB0LmpzIiwic291cmNlcyI6WyJzY3JpcHQuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQUEsRUFBQSxPQUFPLENBQUMsR0FBUixDQUFZLGNBQVosQ0FBQSxDQUFBO0FBQUEifQ==NHS0076

祝你好运!

【讨论】:

【参考方案2】:

您可以使用Coffee4Clients 将咖啡资产通过您的快递服务器即时渲染到 javascript

更新:Coffee4Clients 已被取消,取而代之的是 DocPad,它会预编译您的资产。

【讨论】:

【参考方案3】:

对于我们这些使用最新版本的 Connect 和 Express 的人,我刚刚发布了一个新模块 npm install connect-coffee-script,它可以即时编译咖啡脚本文件。提供了文档和示例以及introduction article。

这是自述文件中的一个示例:

    var coffeescript = require('connect-coffee-script');
    var connect = require('connect');

    var app = connect();

    app.use(coffeescript(
        src: __dirname,
        dest: __dirname + '/public',
        bare: true
    ));

    app.use(connect.static(__dirname + '/public'));

    app.listen(3000)

【讨论】:

作为对老师的回复,所有这些中间件将只编译一次 Coffee 文件,当发生修改时。唯一的成本是获取文件的修改时间,在生产模式下,可以简单地注释像 connect-coffee-script 这样的插件,因为 js 文件已经在磁盘上生成。 我真的很困惑 - 如何将它与 express 一起使用?【参考方案4】:

我认为您应该只编译一次 COFFEE 文件,尤其是在生产模式下

如果您想将咖啡与 Express 3 一起使用,或与任何 Web 框架一起使用,请查看此 repo ExpressOnSteroids 您可以使用此解决方案,或使用此项目中的 Cakefile 创建自己的解决方案

【讨论】:

【参考方案5】:

如果你想使用一个很棒的现有插件,我会推荐Trevor Burnham's Connect-Assets。它有助于编译、缩小和连接 .js 和 .coffee 文件,并优化文件的服务方式(使用文件的 md5-hash 失效的远期过期标头)。插件写得很好。

【讨论】:

+1 因为是列表中唯一推荐系统资产管理系统的人。 Connect-assets 有了新家:github.com/adunkman/connect-assets【参考方案6】:

好消息:Connect(以及扩展 Connect 的 Express)已经作为插件提供!它没有很好的记录;事实上,在我被告知这样的东西已经存在之前,我自己也写过类似的东西 (connect-coffee)。

以下是使用 Express 进行设置的方法:

# Notice the following code is coffescript
# You must add the parens for the app.use method to use in js
coffeeDir = __dirname + '/coffee'
publicDir = __dirname + '/public'
app.use express.compiler(src: coffeeDir, dest: publicDir, enable: ['coffeescript'])
app.use express.static(publicDir)

现在,当请求http://yourapp/foo.js 时,如果您的public 目录中不存在这样的文件,foo.coffee 将自动编译,并提供生成的foo.js。请注意,在static 之后设置static 很重要 compiler

更新:从 Connect 1.7 开始,compiler 中间件已被删除。部分是因为这个,部分是为了提供更像 Rails 3.1 的体验,我创建了一个名为connect-assets 的新中间件。用 npm 安装它,然后像这样设置它:

app.use require('connect-assets')(directory)

其中directory 是您的CoffeeScript 文件所在的文件夹(默认为assets)。很简单,对吧?试试看,让我知道你的想法。

【讨论】:

Trevor,我收到一个错误:TypeError: Cannot read property 'match' of undefined at Object.compiler [as handle] (/usr/local/lib/node/.npm/connect /0.5.10/package/lib/connect/middleware/compiler.js:58:19) 您需要定义coffeeDir,例如coffeeDir = __dirname + '/scripts' 如果您的 .coffee 文件位于 scripts 子目录中。请注意,目录路径不会添加到 URL。所以如果你在scripts/foo.coffee 有一个文件,你会请求http://localhost/foo.js 来获取编译后的JavaScript。 在较新版本的 connect 中,staticProvider() 现在称为 static()。此外,为了安全起见,如果您不希望人们能够获取您的原始 *.coffee 文件,则应在对 compiler() 的调用中同时设置 destsrc。它们不应该相同。 src 是您的原始 *.coffee 文件所在的位置,dest 是它们编译到的静态目录。 谢谢,阿米尔!我已编辑我的答案以纳入您的建议。 这对我不起作用。是否有禁用此功能的新更新?它没有抛出错误,只是没有找到 client.js(它应该寻找 client.coffee 并编译它)。【参考方案7】:

由于某种原因,编译器不再工作,所以我这样做了:

fs = require 'fs'
coffee = require 'coffee-script'

app.use express.static "#__dirname/static"

app.get '/:script.js', (req, res) ->
  res.header 'Content-Type', 'application/x-javascript'
  cs = fs.readFileSync "#__dirname/coffee/#req.params.script.coffee", "ascii"
  js = coffee.compile cs 
  res.send js

现在您可以编写 coffee/animal.coffee 并在您的 html 中编写标准脚本 src='/animal.js'。这隐藏了实现细节。咖啡脚本不可访问,因为“/coffee”目录未公开为静态路径。

注意事项:

    当然,这是一个 CoffeeScript 节点应用程序。我假设如果您将 CS 用于客户端脚本,那么您也将它用于您的服务器! “静态”行是可选的。我的观点是您可以愉快地将“js”文件保存在静态目录中,例如jquery.min.js 等库文件。 与大多数 Node/Express 示例一样,这对开发很有好处;但对于生产,您应该发送缓存标头,对其进行压缩,最好采用某种形式的反向代理,以避免每次都读取和编译文件。

【讨论】:

听起来您正在使用新版本的 Connect,它不再具有编译器中间件。请参阅我的更新答案。 我也从 CoffeeScript 推特帐户中得到了这个:“@mahemoff 是的,编译器中间件在最新的 Connect/Express 中消失了。正在寻找替代方案......”twitter.com/#!/CoffeeScript/status/107080947706503168 是的,我运行的是 CoffeeScript Twitter 帐户。 connect-assets 是我所指的替代方案。 :) 啊:)。您是否有计划支持生产配置?我为生产部署做了一些自定义编码,因为我想组合脚本(以及样式表)并在它们上运行压缩器。可以用标准方法在 Connect/Express 中做到这一点。 (很高兴分享我的代码,尽管它远非通用。) 这绝对是我最终想要支持的东西。事实上,文档说“在 2.0 中,connect-assets 还将提供一种连接和缩小这些文件以用于生产的方法(à la Sprockets)。”【参考方案8】:
CoffeeScript = require 'coffee-script'

app.get '/test.js', (req, res) ->
  render CoffeeScript.compile coffeeSourceCode

【讨论】:

在这种情况下,“coffeeSourceCode”是实际的源代码,而不是路径名。我添加了一个单独的答案来从文件编译。

以上是关于NodeJS + CoffeeScript,根据要求渲染 CoffeeScript 编译的 js的主要内容,如果未能解决你的问题,请参考以下文章

现在啊还不太清楚 nodejs和coffeescript 的关系

coffeescript初体验

如何将 JSON 转换为 CoffeeScript 并写入文件“.coffee”?

Angular遇上CoffeeScript - NgComponent封装

关于 CoffeeScript 变量范围的困惑

CoffeeScript 在更改和加载时动态选择表单字段