问题 CoffeeScript / UglifyJS中的条件编译


使用Coffeescript我需要经历一个构建脚本来更新我的.js文件,我有两个,一个用于调试,一个用于生产(一个使用Uglify来最小化文件,一个不使用)。因此我认为使用一些条件编译也很方便,代码只能进入调试版本。

实现这一目标的最简单方法是什么?理想情况下,我可以通过简单的命令行开关来控制咖啡或uglify?


9499
2018-03-14 02:41


起源



答案:


如果您正在编写构建脚本,则可以向其添加预处理器步骤。自CoffeeScript使用 # 为了表示评论,C预处理器似乎是一个不错的选择。您可以使用表示调试代码 #ifdefS:

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

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

编辑:这个很难,因为这意味着任何没有缩进的CoffeeScript注释都会破坏预处理步骤。不确定这对你有多大问题。例如,

code...
#comment about the code

会破坏构建,但是

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

将正常工作,因为除非第一个字符是a,否则预处理器不会查看行 #


7
2018-03-14 14:31



我喜欢这个想法,尽管你必须小心不要包含像#if blah,#error blah或其他任何与预处理程序指令冲突的注释。 - obmarg
@obmarg好点。我会记下来的。编辑:任何未缩进的注释都将成为问题,因为预处理器会阻塞;缩进的注释将按预期被忽略。 - Aaron Dufour
+1。那会有用。我不需要缩进预处理器注释。但是你知道在node.js上运行的类似cpp的工具(不想为此安装额外的东西,除了通过npm,这很容易)? - Thilo
我不知道,快速搜索没有发现任何东西。您是否期望在没有C编译器的系统上?假设我们在谈论UNIX,它们在我的经验中相当罕见。另外,我可能还不清楚。没有前面的空格的正常注释将会生成 cpp 呛。 - Aaron Dufour
嗯......不知道为什么我没碰到那个。看起来是个不错的选择。我不确定它对CoffeeScript的效果如何,因为它需要(和输出) // 注释,CoffeeScript将其解释为空正则表达式。 - Aaron Dufour


答案:


如果您正在编写构建脚本,则可以向其添加预处理器步骤。自CoffeeScript使用 # 为了表示评论,C预处理器似乎是一个不错的选择。您可以使用表示调试代码 #ifdefS:

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

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

编辑:这个很难,因为这意味着任何没有缩进的CoffeeScript注释都会破坏预处理步骤。不确定这对你有多大问题。例如,

code...
#comment about the code

会破坏构建,但是

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

将正常工作,因为除非第一个字符是a,否则预处理器不会查看行 #


7
2018-03-14 14:31



我喜欢这个想法,尽管你必须小心不要包含像#if blah,#error blah或其他任何与预处理程序指令冲突的注释。 - obmarg
@obmarg好点。我会记下来的。编辑:任何未缩进的注释都将成为问题,因为预处理器会阻塞;缩进的注释将按预期被忽略。 - Aaron Dufour
+1。那会有用。我不需要缩进预处理器注释。但是你知道在node.js上运行的类似cpp的工具(不想为此安装额外的东西,除了通过npm,这很容易)? - Thilo
我不知道,快速搜索没有发现任何东西。您是否期望在没有C编译器的系统上?假设我们在谈论UNIX,它们在我的经验中相当罕见。另外,我可能还不清楚。没有前面的空格的正常注释将会生成 cpp 呛。 - Aaron Dufour
嗯......不知道为什么我没碰到那个。看起来是个不错的选择。我不确定它对CoffeeScript的效果如何,因为它需要(和输出) // 注释,CoffeeScript将其解释为空正则表达式。 - Aaron Dufour


听起来像你说你有两个构建脚本?对于 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()

2
2018-03-14 02:58



是的,那部分工作正常。但我也希望uglified文件的内容与另一个文件略有不同。想想#ifdef'DEBUG'。相同的源文件,但外部交换机会影响要删除的内容。 - Thilo


C预处理器的替代方案是 M4  宏处理器(维基百科介绍)。我自己没有使用它,所以我无法复习它,我知道它应该有点痛苦,但它会解决你的问题。它也像C预处理器一样,可以运行在每个操作系统上。


1
2018-03-15 08:29





我用 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
#...

0
2017-07-02 18:45