【问题标题】:Conditional compilation in CoffeeScript/UglifyJSCoffeeScript/UglifyJS 中的条件编译
【发布时间】:2012-03-30 12:19:24
【问题描述】:

使用 Coffeescript 我无论如何都需要通过构建脚本来更新我的 .js 文件,我有两个,一个用于调试,一个用于生产(一个使用 Uglify 来最小化文件,一个不使用) .所以我在想,也可以方便地进行一些条件编译,代码只进入调试版本。

实现这一点的最简单方法是什么,最好是通过一个简单的命令行开关来控制,我可以将它提供给咖啡或 uglify?

【问题讨论】:

    标签: build-process coffeescript conditional-compilation uglifyjs


    【解决方案1】:

    如果您正在编写构建脚本,您可以向其中添加预处理器步骤。由于 CoffeeScript 使用 # 来表示 cmets,因此 C 预处理器似乎是一个不错的选择。您可以使用#ifdefs 表示调试代码:

    some code...
    #ifdef DEBUG
    debug code...
    #endif
    

    然后,您可以使用cpp -E -Xpreprocessor -DDEBUG <filename> -o <outfile> 预处理调试版本并使用CoffeeScript 编译<outfile>。同样,使用cpp -E <filename> -o <outfile> 预处理生产版本。

    编辑:这很难,因为这意味着任何未缩进的 CoffeeScript cmets 都会破坏预处理步骤。不知道这对你有多大的问题。例如,

    code...
    #comment about the code
    

    会破坏构建,但是

    code...
      indented code...
      #indented comment
    

    会正常工作,因为预处理器不会查看行,除非它们的第一个字符是 #

    【讨论】:

    • 我喜欢这个想法,但您必须小心不要包含 #if blah、#error blah 之类的 cmets 或任何与预处理器指令冲突的内容。
    • @obmarg 好点。我会记下来的。编辑:任何未缩进的注释都会成为问题,因为预处理器会阻塞;缩进的 cmets 将按预期被忽略。
    • +1。那会奏效。我不需要缩进预处理器 cmets。但是你知道在 node.js 上运行的类似 cpp 的工具吗(不想为此安装任何额外的东西,除了通过 npm,这很容易)?
    • 我什么都不知道,快速搜索也没有找到任何东西。您是否希望在没有 C 编译器的系统上使用?假设我们谈论的是 UNIX,它们在我的经验中相当罕见。另外,我可能没有说清楚。前面没有空格的普通 cmets 将使 cpp 窒息。
    • 嗯...不知道为什么我没有遇到那个。看起来是个不错的赌注。我不确定它对 CoffeeScript 的效果如何,因为它需要(和输出)// cmets,CoffeeScript 将其解释为空的正则表达式。
    【解决方案2】:

    在我看来,您是在说您有两个构建脚本?对于string.js,我只是使用一个Cakefile 来实现你我认为你想要的。本质上,如果源文件发生变化,它会生成一个常规的 JS 文件,然后是一个 uglified 文件。

    这是Cakefile的相关部分:

     task 'watch', 'Watch src/ for changes', ->
        browserTestFile = path.join(process.cwd(), 'test_browser', 'string.test.js')
    
        coffee = spawn 'coffee', ['-w', '-c', '-o', 'lib', 'src']
        coffee.stderr.on 'data', (data) -> 'ERR: ' + process.stderr.write data.toString()
        coffee.stdout.on 'data', (data) ->
          d = data.toString()
          if d.indexOf('compiled') > 0
            #invoke 'test'
    
            fsw = fs.createWriteStream(browserTestFile, flags: 'w', encoding: 'utf8', mode: 0666)
            coffee_test = spawn 'coffee', ['-c', '-p', 'test/string.test.coffee']
            coffee_test.stdout.pipe(fsw, end: false)
    
            uglify = spawn 'uglifyjs', ['lib/string.js']
            uglify.stdout.pipe(fs.createWriteStream('lib/string.min.js'))
    
          else
            growl(d, title: 'Error', image: './resources/error.png')
    
          process.stdout.write data.toString()
    

    【讨论】:

    • 是的,那部分已经可以正常工作了。但我也希望 uglified 文件的内容与另一个文件略有不同。想想#ifdef 'DEBUG'。相同的源文件,但外部开关会影响删除的内容。
    【解决方案3】:

    C 预处理器的替代方案是 M4 宏处理器 (Wikipedia intro)。我自己没有使用过它,所以我无法查看它,我知道它应该有点痛苦,但它会解决你的问题。此外,它与 C 预处理器一样,可以在任何可以想象的操作系统上运行。

    【讨论】:

      【解决方案4】:

      我使用https://github.com/jsoverson/grunt-preprocess 处理这种事情。它完全符合我想要做的:

      detect_ennemy_collision: (ennemies) ->
      
      # @ifdef DEBUG 
          expect(ennemies).to.be.an 'array'
          expect(ennemies.length).to.be.ok
      
          for ennemy in ennemies
              (expect ennemy).to.be.an.instanceof Character
      
      # @endif
      #...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-14
        相关资源
        最近更新 更多