Условная компиляция в 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
#...