2015-05-15 17 views
6

Ich habe einige Schwierigkeiten, einen assetic sass Filter zu bekommen, um mit node-sass anstelle der Rubinalternative zu arbeiten. Ich habe die folgende Konfiguration in meiner config.yml Datei:Symfony assetic sass filter über node-sass?

assetic: 
    debug:   "%kernel.debug%" 

    use_controller: false 
    bundles:  [ ] 

    write-to:  "%kernel.root_dir%/../web/assets" 
    read_from:  "%kernel.root_dir%/../web/assets" 

    node:  "%%PROGRAMFILES%%\nodejs\\node.exe" 
    node_paths: ["%%USERPROFILE%%\\AppData\\Roaming\\npm\\node_modules"] 
    sass:  "%%USERPROFILE%%\\AppData\\Roaming\\npm\\node-sass" 
    ruby: null 

    filters: 
     cssrewrite: ~ 
     scss: 
      output-style: compressed 
      apply_to: "\.(scss|sass|css)%" 

Obwohl dies die richtige node-sass Befehl löst, ich bin nicht sicher, ob die Konfiguration korrekt ist. Wenn ich ruby: null entferne, versucht es, C:\Program Files...\path\to\ruby.exe %%USERPROFILE%%\\AppData\\Roaming\\npm\\node-sass zu laufen, das total falsch ist. Aber ruby: null zu lösen, löst das Problem auch nicht, weil es die falschen Argumente setzt (d. H. --load-path anstelle von --include-path) und das vermasselt auch die Dinge.

Weiß jemand, wie man den sass Filter mit node anstelle von ruby einstellt?

Antwort

5

Ich möchte meine Lösung für dieses Problem für jeden da draußen teilen, der es auch erfahren könnte.

Es scheint, dass die BaseSassFilter nur für die Arbeit mit der Ruby-Version geeignet ist. Also habe ich beschlossen, einen eigenen Filter zu erstellen. Hier ist meine Klasse:

<?php 

namespace App\YourBundle\Assetic\Filter; 

use Assetic\Asset\AssetInterface; 
use Assetic\Exception\FilterException; 
use Assetic\Filter\Sass\BaseSassFilter; 
use Assetic\Filter\Sass\SassFilter; 

/** 
* This class is based on Assetic\Filter\Sass\SassFilter and is slightly modified to work with node-sass instead of Ruby. 
*/ 

class NodeSassFilter extends BaseSassFilter 
{ 

    const STYLE_NESTED  = 'nested'; 
    const STYLE_EXPANDED = 'expanded'; 
    const STYLE_COMPACT = 'compact'; 
    const STYLE_COMPRESSED = 'compressed'; 

    private $sassPath; 
    private $scss; 
    private $style; 
    private $quiet; 
    private $cacheLocation; 

    public function __construct($sassPath = '/usr/bin/node-sass') 
    { 
     $this->sassPath = $sassPath; 
     $this->cacheLocation = realpath(sys_get_temp_dir()); 
    } 

    public function setScss($scss) 
    { 
     $this->scss = $scss; 
    } 

    public function setStyle($style) 
    { 
     $this->style = $style; 
    } 

    public function setQuiet($quiet) 
    { 
     $this->quiet = $quiet; 
    } 

    public function filterLoad(AssetInterface $asset) 
    { 
     $sassProcessArgs = array($this->sassPath); 

     $pb = $this->createProcessBuilder($sassProcessArgs); 

     if ($dir = $asset->getSourceDirectory()) { 
      $pb->add('--include-path')->add($dir); 
     } 

     if ($this->style) { 
      $pb->add('--output-style')->add($this->style); 
     } 

     if ($this->quiet) { 
      $pb->add('--quiet'); 
     } 

     // input 
     $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_sass')); 
     file_put_contents($input, $asset->getContent()); 

     $proc = $pb->getProcess(); 
     $code = $proc->run(); 
     unlink($input); 

     if (0 !== $code) { 
      throw FilterException::fromProcess($proc)->setInput($asset->getContent()); 
     } 

     $asset->setContent($proc->getOutput()); 
    } 

    public function filterDump(AssetInterface $asset) 
    { 
    } 
} 

Dann in Ihrem config.yml Sie fügen Sie folgendes:

assetic: 
    filters: 
     nodesass: 
      bin: "%sass.bin%" 
      resource: '%kernel.root_dir%/config/filters/nodesass.xml' 
      style: compressed 
      apply_to: "\.scss%" 

In app/config/filters/nodesass.xml Sie das folgende XML hinzu:

<?xml version="1.0" ?> 
<container xmlns="http://symfony.com/schema/dic/services" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> 

    <parameters> 
     <parameter key="assetic.filter.nodesass.class">App\YourBundle\Assetic\Filter\NodeSassFilter</parameter> 
     <parameter key="assetic.filter.nodesass.bin">%assetic.sass.bin%</parameter> 
     <parameter key="assetic.filter.nodesass.timeout">240</parameter> 
     <parameter key="assetic.filter.nodesass.style">null</parameter> 
     <parameter key="assetic.filter.nodesass.load_paths" type="collection" /> 
    </parameters> 

    <services> 
     <service id="assetic.filter.nodesass" class="%assetic.filter.nodesass.class%"> 
      <tag name="assetic.filter" alias="nodesass" /> 
      <argument>%assetic.filter.nodesass.bin%</argument> 
      <call method="setTimeout"><argument>%assetic.filter.nodesass.timeout%</argument></call> 
      <call method="setStyle"><argument>%assetic.filter.nodesass.style%</argument></call> 
      <call method="setLoadPaths"><argument>%assetic.filter.nodesass.load_paths%</argument></call> 
     </service> 
    </services> 

</container> 

Dies sollte die Dinge arbeiten für jetzt.

+0

Gute Arbeit. Dies sollte in das Assessment-Repository gehen, ich verwalte Assets auch hauptsächlich über Knoten ohne Ruby. – gremo

+0

Ich werde überprüfen, ob sie das nicht bereits in den neuesten Versionen behoben haben und eine PR machen, wenn ich in diesem Fall etwas Zeit habe. :) – tftd

+0

OK, trotzdem danke - ich habe ein paar Stunden damit verbracht, mit load-path (ruby sass) gegen load-imports (node-sass) zu spielen ... um endlich zu erkennen, dass die sass filter mit ruby ​​verwendet werden sollen :) – gremo

Verwandte Themen