【问题标题】:Symfony assetic sass filter via node-sass?Symfony资产sass过滤器通过node-sass?
【发布时间】:2015-07-27 17:13:03
【问题描述】:

我在让资产 sass 过滤器与 node-sass 一起使用而不是 ruby​​ 替代品时遇到了一些困难。我的config.yml 文件中有以下配置:

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),这也会使事情变得混乱。

有人知道如何用node 代替ruby 来设置sass 过滤器吗?

【问题讨论】:

    标签: ruby node.js symfony sass


    【解决方案1】:

    我想与可能也遇到此问题的任何人分享我对此问题的解决方案。

    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>
    

    现在应该可以正常工作了。

    【讨论】:

    • 干得好。这应该放在资产存储库中,我也主要通过没有 ruby​​ 的节点来管理资产。
    • 我会检查他们是否还没有在最新版本中修复这个问题,并在我有时间的时候进行 PR。 :)
    • 好的,谢谢-我花了几个小时弄乱加载路径(ruby sass)与加载导入(node-sass)......最终意识到sass过滤器的目的是与红宝石一起使用:)
    • 我制作了一个 node-sass 过滤器 github.com/kriswallsmith/assetic/pull/767,它的工作原理与您的非常相似。它似乎工作正常。
    • 希望@gremo 的 PR 尽快合并!
    猜你喜欢
    • 2015-05-05
    • 2021-05-13
    • 2020-10-11
    • 1970-01-01
    • 2011-09-03
    • 1970-01-01
    • 2016-01-13
    • 2015-02-10
    • 2020-06-09
    相关资源
    最近更新 更多