10

我正在工作中开始一个项目,并且想知道最好使用的构建工具是什么。

整个事情都是用 CoffeeScript 编写的,客户端使用 AngularJS,服务器使用 NodeJS。

该应用程序有几个组件:

  • iPad 应用程序
  • iPhone 应用程序(与 ipad 不同的功能)
  • 应用程序的 CMS
  • 一个 NodeJS 服务器

所有这些之间有大量的共享代码,同样都是用 CoffeeScript 编写的。

我想要一个构建工具,我可以在其中列出哪个应用程序使用了哪些代码(其中大部分是共享的),并且它将每个应用程序的 javascript 文件构建到一个单独的文件夹中。

例如,我会设置一个名为“/compiled/ipad/”的文件夹,其中包含 index.html,以及 js、css、img 等文件夹。我会列出我想要放入 /compiled/ipad/js 的已编译咖啡文件(其中一些来自 /src/shared/*.coffee,一些来自 /src/ipad/*.coffee 等)以及我想将哪些文件放入 /compiled/ipad/css。我也希望它能够轻松地连接我想要的文件。

它还会将我的测试从 /src/test/ipad 编译成 /compiled/test/ipad/*.js。

我所有的客户端单元测试都是使用testacular编写的,我还不确定我会用什么来编写服务器端单元测试。

什么构建工具/配置是这里最好的方法?生成文件?像咕噜一样的东西?老实说,我对整个构建场景都很陌生。

编辑:决定使用 Browserify。您可以在此处找到我的解决方案以使其与 Angular 一起使用:https ://groups.google.com/forum/#!topic/angular/ytoVaikOcCs

4

3 回答 3

4

就我个人而言,我认为在 javascript 或 coffeescript 中编写服务器端代码的驱动力也延伸到了您的构建工具链:所以也坚持在那里使用 javascript/coffeescript。这将允许您从构建工具轻松地自动化您的服务器/客户端任务 - 我怀疑使用 make 之类的另一个工具是否有意义(您只是在 node.js 命令调用周围编写包装器)。建议,按结构化排序:

  • node.js:只需在 javascript 中滚动构建脚本,然后使用 node.js 调用它们。我想类似于 shell 脚本。我不推荐这条路线。
  • jake or cake:我来自 java 世界,所以这些让我想起蚂蚁也就不足为奇了。我更喜欢coffeescript,因此更喜欢蛋糕。
  • grunt:我以前没有听说过这个,所以我不能给出太多建议。它让我想起了 maven,当然……我只能说……构建工具倾向于强制执行的结构越多,它的灵活性就越低。它是一种权衡。只要您以“构建工具”的方式进行操作,就可以节省大量时间。但是,如果您遇到特定于应用程序的问题,则要解决它可能是一件非常痛苦的事情。

当然,您可以使用其他一些您已经熟悉的其他语言的构建工具:rake、maven、ant、gradle 等。

于 2012-05-21T17:43:21.823 回答
4

我根据需要使用节点模块在 Cakefile 中完成了几乎所有完全相同的事情。

使用每个文件的路径设置一些作为数组的全局变量,将这些文件连接到您指定的编译目录中的一个文件中,然后将该文件编译为 js。

对于样式,显然与没有编译的连接相同。

fs = require 'fs'
path = require 'path'
{spawn, exec} = require 'child_process'
parser = require('uglify-js').parser
uglify = require('uglify-js').uglify
cleanCss = require 'clean-css'

coffees = 
 [
  "/src/shared/file1.coffee"
  "/src/shared/file2.coffee"
  "/src/ipad/file1.coffee"
 ]

tests = 
  [
   "/src/ipad/tests.coffee"
  ]

styles = 
 [
  "/src/ipad/styles1.css"
  "/src/shared/styles2.css"
 ]

concatenate = (destinationFile, files, type) ->
  newContents = new Array
  remaining = files.length
  for file, index in files then do (file, index) ->
      fs.readFile file, 'utf8', (err, fileContents) ->
          throw err if err
          newContents[index] = fileContents
          if --remaining is 0
              fs.writeFile destinationFile, newContents.join '\n\n', 'utf8', (err) ->
                throw err if err
              if type is 'styles'
                 minifyCss fileName
              else
                 compileCoffee fileName


 compileCoffee = (file) ->
    exec "coffee -c #{file}", (err) ->
       throw err if err
       # delete coffee file leaving only js
       fs.unlink 'path/specifying/compiled_coffee', (err) -> 
          throw err if err
          minifyJs file

 minifyJs = (file) ->
  fs.readFile f, 'utf8', (err, contents) ->
      ast = parser.parse contents
      ast = uglify.ast_mangle ast 
      ast = uglify.ast_squeeze ast
      minified = uglify.gen_code ast

      writeMinified file, minified

writeMinified = (file, contents) ->
   fs.writeFile file, contents, 'utf8', (err) -> throw err if err  


minifyCss = (file) ->
    fs.readFile file, 'utf8', (err, contents) ->
    throw err if err
    minimized = cleanCss.process contents
    clean = minimized.replace 'app/assets', ''

    fs.writeFile file, clean, 'utf8', (err) ->
        throw err if err


task 'compile_coffees', 'concat, compile, and minify coffees', ->
  concatenate '/compiled/ipad/code.coffee', coffees, 'coffee'

task 'concat_styles', 'concat and minify styles', ->
  concatenate '/compiled/ipad/css/styles.css', styles, 'styles'

task 'compile_tests', 'concat, compile, and minify test', ->
  concatenate '/compiled/ipad/tests.coffee', tests, 'tests'

现在这大致是我认为你所要求的。

肯定会更漂亮,尤其是有一个单独的函数来编写缩小的内容,但它确实有效。

也不是完美的样式,因为我在使用 Sass 并且在它达到缩小功能之前还有其他功能,但我想你明白了。

于 2012-05-21T18:27:25.327 回答
3

我会将所有共享代码放入 Node.js 模块并创建一个类似于以下内容的项目:

Project
|~apps/
| |~cms/
| | `-app.js
| |~ipad/
| | `-app.js
| |~iphone/
| | `-app.js
| `~node/
|   `-app.js
|~libs/
| |-module.js
| `-module2.js
|~specs/
| |~cms/
| | `-app.js
| |~ipad/
| | `-app.js
| |~iphone/
| | `-app.js
| `~node/
|   `-app.js
| `~libs/
|   |-module.js
|   `-module2.js
`-Makefile

然后我会使用 Browserify 之类的东西(还有其他的)在需要的地方制作客户端应用程序。这样,您实际上就拥有真正的应用程序导入模块,而不是在其中说出您需要什么的构建文件。

于 2012-05-21T17:58:48.293 回答