2015-05-15 34 views
6

我有一些困難讓資產sass過濾器與node-sass,而不是ruby的替代方案。我在我的config.yml文件如下配置:Symfony資產sass過濾器通過節點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)%" 

雖然這觸發正確的node-sass命令,我不知道配置是否正確。如果我刪除ruby: null它試圖運行C:\Program Files...\path\to\ruby.exe %%USERPROFILE%%\\AppData\\Roaming\\npm\\node-sass這是完全錯誤的。但擁有ruby: null也不能解決問題,因爲它設置了錯誤的參數(即--load-path而不是--include-path),並且也會造成混亂。

有誰知道如何設置sass篩選器node而不是ruby

回答

5

我想分享我的解決方案,以解決這個問題,任何人誰也可能會遇到它。

看起來BaseSassFilter只適用於ruby版本。所以我決定創建我自己的過濾器。這裏是我的課:

<?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) 
    { 
    } 
} 

然後,在你config.yml您添加以下內容:

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

app/config/filters/nodesass.xml你添加下面的XML:

<?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> 

這應該得到的東西工作現在。

+0

好的工作。這應該在資產庫中,我也主要通過沒有ruby的節點來管理資產。 – gremo

+0

我會檢查他們是否已經在最新版本中解決了這個問題,並且在這種情況下我有一些時間來做PR。 :) – tftd

+0

好的,無論如何,謝謝 - 我花了幾個小時搞定load-path(ruby sass)vs load-imports(node-sass)......終於意識到sass過濾器是用來與ruby :) – gremo