Вот что я ищу:Есть ли способ сообщить компилятору Google Closure о том, что * NOT * не встроил мои локальные функции?
- Я хочу использовать замечательные свойства SIMPLE режима минификации при отключении только одна особенности (отключить локальную функцию инлайн).
- UPDATE: Ответ НЕТ, это не возможно, учитывая мои настройки. Но для меня есть обходное решение, когда я использую Grails.
- Как пояснил @Chad ниже: «Это нарушает основные предположения компилятора». Дополнительную информацию см. В моем UPDATE3 ниже.
В ФОРМЕ ВОПРОС:
- Я использую
CompilationLevel.SIMPLE_OPTIMIZATIONS
, который делает все, что нужно, за исключением того, что это встраивание мои локальные функции. - Есть ли способ обойти это? Например, есть ли параметр, который я могу разместить в своих JS-файлах, чтобы сообщить Google Closure не включать мои локальные функции?
Было бы здорово иметь некоторые директивы в верхней части моего файла JavaScript, таких как:
// This is a JS comment...
// google.closure.compiler = [inlineLocalFunctions: false]
Я занимаюсь разработкой приложения Grails и используя Grails asset-pipeline плагин, который использует Google Closure Compiler (в дальнейшем, компилятор). Плагин поддерживает различные уровни минимизации, которые поддерживает компилятор через конфигурацию Grails grails.assets.minifyOptions. Это позволяет использовать «ПРОСТО», «РАСШИРЕННЫЙ», «WHITESPACE_ONLY».
AssetCompiler.groovy (актив-конвейерный плагин) вызывает ClosureCompilerProcessor.process()
Это в конечном итоге присваивает SIMPLE_OPTIMIZATIONS
на объект в CompilerOptions. И при этом CompilerOptions.inlineLocalFunctions = true
как побочный продукт (это жестко закодированное поведение в компиляторе). Если бы я использовал WHITESPACE_ONLY
, результат был бы inlineLocalFunctions=false
.
Таким образом, используя настройку «ПРОСТОЙ» в Asset Pipeline, локальные функции вставляются, что вызывает у меня проблемы. Пример: ExtJS ext-all-debug.js, который использует множество локальных функций.
SO post Is it possible to make Google Closure compiler *not* inline certain functions? оказывает некоторую помощь. Я могу использовать его трюк window['dontBlowMeAway'] = dontBlowMeAway
, чтобы мои функции не вставлялись. Однако у меня много функций, и я не собираюсь вручную делать это для каждого; и я не хочу писать сценарий, чтобы сделать это для меня. Создание JS-модели и попытка идентифицировать локальные функции не звучат безопасно, весело и быстро.
Предыдущий SO сообщение направляет читателю https://developers.google.com/closure/compiler/docs/api-tutorial3#removal, где объясняется трюк window['bla']
, и он работает.
Wow спасибо, что прочитали этот длинный.
Помощь? :-)
Update1:
Хорошо. Приложив все усилия для написания этого вопроса, у меня может получиться трюк, который мог бы сработать. Grails использует Groovy. Groovy упрощает процедуру перехвата вызова метода, используя свой MetaClass API.
Я собираюсь попробовать перехватить вызов:
com.google.javascript.jscomp.Compiler.compile(
List<T1> externs, List<T2> inputs, CompilerOptions options)
Мой перехватывать метод будет выглядеть так:
options.inlineLocalFunctions=false
// Then delegate call to the real compile() method
Пора кровать, так что я должен попробовать это позже. Тем не менее, было бы неплохо решить эту проблему без взлома.
UPDATE2: Отклик в аналогичной должности (Is it possible to make Google Closure compiler *not* inline certain functions?) не решает мою проблему из-за большого количества функций, мне нужно встраиваемыми. Я уже объяснил это.
Возьмите файл ExtJS, который я привел выше, в качестве примера того, почему приведенный выше similar SO post не разрешает мою проблему. Посмотрите на необработанный код для ext-all-debug.js. Найдите функцию byAttribute(). Затем продолжайте искать строку «byAttribute», и вы увидите, что она является частью строк, которые определяются. Я не знаком с этим кодом, но я предполагаю, что эти строковые значения byAttribute
позже передаются на выполнение функции JS's eval(). Компилятор не изменяет эти значения byAttribute
, когда это часть строки. После того, как function byAttribute
встроен, попытки вызова функции больше невозможны.
Update3: Я пытался две стратегии, чтобы решить эту проблему, и оба оказались безуспешными. Однако я успешно реализовал обходной путь. Мои неудачные попытки:
- Использование перехвата метода Groovy (Протокол метаобъектов, aka MOP) для перехвата
com.google.javascript.jscomp.Compiler.compile()
. - Закройте заглушку-compiler.jar (сделайте мою собственную копию) и измените
com.google.javascript.jscomp.applySafeCompilationOptions()
, установивoptions.setInlineFunctions(Reach.NONE);
вместо LOCAL.
метод перехват не работает, потому что Compiler.compile()
является классом Java, который вызывается с помощью Groovy класса, помеченного как @CompileStatic
. Это означает, что ССМ Groovy не используется, когда process()
называет Compiler.compile()
Google. Даже ClosureCompilerProcessor.translateMinifyOptions()
(код Groovy) нельзя перехватить, потому что класс @CompileStatic
. Единственный метод, который можно перехватить, - ClosureCompilerProcessor.process()
.
Викинг Google-compiler.jar был моим последним уродливым курортом. Но так же, как @Chad сказал ниже, просто вставка options.setInlineFunctions(Reach.NONE)
в нужное место не воскресила мои встроенные имена функций JS. Я попытался переключить другие параметры, такие как setRemoveDeadCode=false
безрезультатно. Я понял, что сказал Чад. Я бы закончил переворачивать настройки и, возможно, уничтожил работу миниатюры.
Мое решение: Я предварительно скомпилировал ext-all-debug.js с помощью UglifyJS и добавил их в свой проект. Я мог бы назвать файлы ext-all-debug.min.js
, чтобы сделать это более чисто, но я этого не сделал. Ниже приведены настройки, которые я установил в своем Grails Config.groovy:
grails.assets.minifyOptions = [
optimizationLevel: 'SIMPLE' // WHITESPACE_ONLY, SIMPLE or ADVANCED
]
grails.assets.minifyOptions.excludes = [
'**ext-all-debug.js',
'**ext-theme-neptune.js'
]
Выполнено. Задача решена.
Ключевые слова: преуменьшать, минификация, уродовать, UglifyJS, UglifyJS2
Можете ли вы объяснить ** почему ** локальная функция встраивания вызывает проблемы? Существует несколько методов предотвращения этого, но мне нужно знать основные причины, чтобы предложить его. –
Возможный дубликат [Возможно ли сделать компилятор Google Closure \ * not \ * встроенными определенные функции?] (Http://stackoverflow.com/questions/4297685/is-it-possible-to-make-google-closure- compiler-not-inline-certain-functions) –
Спасибо @ChadKillingsworth. Я добавил «UPDATE2» к моему вопросу как ответ на ваш вопрос. В самом деле, я просил вас прокомментировать «возможный дубликат», если вы прочтете мой первоначальный вопрос, который вы, вероятно, сделали в любом случае. Мир брата. –