2016-12-22 16 views
3

Сжатие связанных JavaScript и CSS файлов не имеет большого значения при использовании Assetic в моем проекте Symfony 2.8. Но как насчет скриптов, которые непосредственно встроены в страницу с помощью тега script. Эти сценарии никоим образом не изменены.Minify/Uglify встроенный JavaScript в Symfony/Twig response

Возможно ли сжать/изменить/убрать эти скрипты?

Конечно, я мог бы просто переместить эти скрипты в файлы разделов и, таким образом, применить к ним фильтры Assetic. Но в некоторых случаях просто удобно иметь скрипты непосредственно в шаблоне HTML/Twig.

Итак, существует ли существующее решение для фильтрации этих сценариев, не перемещая их?

+0

В большинстве случаев вы можете передать 99% кода в отдельные файлы, включив их в аксессуар в шаблоне ветки, оставляя только небольшую часть javascript как встроенный скрипт. Я использую этот подход в основном для динамических параметров конфигурации, инициализации данных JSON и т. Д. –

+1

Несомненно, это абсолютно правильно. Однако в моем проекте я бы оценил, что 5-10% кода используется в HTML/Twig. Но это не имеет значения, если его 1%, 5% или 50%. В некоторых случаях встроенный код упрощается. Таким образом, вопрос заключается в том, как минимизировать/убрать этот код, не переходя в отдельные файлы **? –

ответ

2

Поскольку я не нашел решение для этого, я, наконец, удалось создать свой собственный: Добавить специальный тег для моего (существующего) расширение Twig применять Assetics uglifyJS2 фильтр для встроенных скриптов:

Шаг 1: Создание Twig TokenParser и Node

class UglifyTokenParser extends Twig_TokenParser { 
    private $enabled;  

    public function __construct($enabled = true) { 
     $this->enabled = (bool) $enabled; 
    } 


    public function parse(Twig_Token $token) { 
     $lineNumber = $token->getLine(); 

     $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 
     $body = $this->parser->subparse(function (Twig_Token $token) { 
      return $token->test('enduglify'); 
     }, true); 

     $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 
     if ($this->enabled) { 
      $node = new UglifyNode($body, $lineNumber, $this->getTag()); 
      return $node; 
     } 

     return $body; 
    }  


    public function getTag() { 
     return 'uglify'; 
    } 
} 

class UglifyNode extends \Twig_Node { 
    public function __construct(Twig_Node $body, $lineNumber, $tag = 'uglify') { 
     parent::__construct(array('body' => $body), array(), $lineNumber, $tag); 
    } 

    public function compile(Twig_Compiler $compiler) {  
     $compiler 
      ->addDebugInfo($this) 
      ->write("ob_start();\n")     
      ->subcompile($this->getNode('body')) 
      ->write("echo \$context['_uglifier']->uglify(trim(ob_get_clean()));\n"); 
    } 
} 

Шаг 2: Добавьте Uglifier класс, который используется в Node передать содержимое в Assetic UglifyJS2Filter

class Uglifier { 
    private $filter; 
    private $asset; 
    private $enabled; 

    public function __construct(FilterInterface $filter, $endabled) { 
     $this->filter = $filter; 
     $this->asset = new UglifierAsset(array($this->filter)); 
     $this->enabled = $endabled; 
    } 

    public function uglify($content) { 
     if ($this->enabled) { 
      $this->asset->loadContent($content); 
      $uglified = $this->asset->dump();  
      return $uglified; 
     } else { 
      return $content; 
     } 
    } 
} 


class UglifierAsset extends BaseAsset { 
    public function __construct($filters = array()) { 
     parent::__construct($filters); 
    } 

    private $theContent; 
    public function loadContent($content) { 
     $this->theContent = $content; 
     $this->load(); 
    } 

    public function load(FilterInterface $additionalFilter = null) { 
     $this->doLoad($this->theContent); 
    } 

    public function getLastModified() { 
     return 0; 
    } 
} 

Шаг 3: Создать Uglifier в sService, передать его Twig Extension и реализовать пользовательский тег в расширении

app.twig_extension: 
    class: AppBundle\Twig\AppExtension 
    public: false 
    arguments: [ "@app.twig_extension.uglifier" ] 
    tags: 
     - { name: twig.extension } 


app.twig_extension.uglifier: 
    class: AppBundle\Twig\uglify\Uglifier 
    arguments: [ "@assetic.filter.uglifyjs2", "%twig_extension.unglifier.enabled%" ] 


class AppExtension extends \Twig_Extension implements \Twig_Extension_GlobalsInterface { 
    private $uglifier; 
    public function __construct(Uglifier $uglifier) { 
     $this->uglifier = $uglifier; 
    } 

    public function getGlobals() {  
     return array(
      '_uglifier' => $this->uglifier, 
     ); 
    } 

    public function getTokenParsers() { 
     return array(new UglifyTokenParser()); 
    } 
} 

Шаг 4: Wrap встроенные скрипты с новой `{ % uglify%} тег

{# before #} 
<script type="text/javascript"> 
    // some JS 
</script> 

{# after #} 
<script type="text/javascript"> 
    {% uglify %} 
     // some JS 
    {% enduglify %} 
</script> 

DONE

 Смежные вопросы

  • Нет связанных вопросов^_^