Условная компиляция в CoffeeScript/UglifyJS

Использование Coffeescript Мне нужно пройти через сборку script в любом случае, чтобы обновить мои .js файлы, и у меня есть два из них: один для отладки и один для производства (один использует Uglify для минимизации файлов, не). Поэтому я думал, что было бы удобно иметь некоторую условную компиляцию, а код, который входит только в сборку отладки.

Какой самый простой способ достичь этого, идеально управляемый простым переключателем командной строки, который я могу дать либо кофе, либо uglify?

Ответ 1

Если вы все равно пишете конструкцию script, вы можете добавить к ней шаг препроцессора. Поскольку CoffeeScript использует # для обозначения комментариев, препроцессор C кажется хорошим выбором. Вы можете указать код отладки с помощью #ifdef s:

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

будет работать нормально, потому что препроцессор не смотрит строки, если их первый символ не является #.

Ответ 2

Мне кажется, что вы говорите, что у вас есть два сценария сборки? Для string.js, я просто использую Cakefile для достижения того, что вы думаете, что хотите. По сути, если исходный файл изменяется, он создает обычный JS файл, а затем угнетенный файл.

Вот соответствующая часть 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()

Ответ 3

Альтернативой препроцессору C будет макрос M4 (Вступление Википедии). Я не использовал его сам, поэтому я не могу его пересмотреть, и я знаю, что это должно быть немного больно, но это решит вашу проблему. Кроме того, он, как и препроцессор 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
#...