资产包括子目录中的所有文件

Assetic to include all files within sub directories

刚开始在我的 Symfony2 项目中使用 assectic,它工作得很好,但看不到一个很好的简单方法来将所有 javascript 文件包含在一个包中。

我的 AppBundle 的结构是

AppBundle
  - Controller
  - Resources
    - views
    - public
      - js
        - Model
          - User.js
        - View
          - Dashboard.js
        - Bundle.js
        - Router.js

我目前的编译代码是

{% javascripts '@AppBundle/Resources/public/js/*' %}
    <script src="{{ asset_url }}"></script>
{% endjavascripts %}

哪个转储出来

<script src="/js/d356fea_part_1_Bundle_1.js"></script>
<script src="/js/d356fea_part_1_Router_2.js"></script>

那么如何才能将所有 javascript 文件包含在子文件夹中?

还有可以更改part_1的名字吗?很想在开发过程中说 AppBundle

经过大量研究并使用 Assetic 无法进行游戏。由于这个原因,我不得不从项目中删除 Assetic,而且它更新文件的速度太慢,这给前端开发人员带来了问题。

这不是一个正确的答案,但由于这是我在短时间内能找到的唯一解决方案,所以我最终一起破解了一个解决方案。

我们现在有一个 JSON 配置文件,如下所示:

{
  "lib": {
    "cwd": {
      "vendor": "app/Resources/vendor"
    },
    "files": [
      "%vendor%/jquery/dist/jquery.min.js",
      "%vendor%/underscore/underscore-min.js",
      "%vendor%/backbone/backbone-min.js"    
    ]
  },
  "app": {
    "cwd": {
      "app": "app/Resources/public/js",
      "AppBundle": "src/AppBundle/Resources/public/js"
    },
    "files": [
      "%app%/*.js",
      "%AppBundle%/*.js"
    ]
  }
}

然后使用 grunt-contrib-symlink 将这些目录符号链接到 web 目录。

    symlink: {
        expanded: {
            files: function () {
                var symlinks = [];

                Object.keys(js).forEach(function (key) {
                    var file = js[key];

                    Object.keys(file.cwd).forEach(function (name) {
                        symlinks.push({
                            src: [file.cwd[name]],
                            dest: 'web/js/' + name
                        });
                    });
                });

                return symlinks;
            }()
        }
    },

然后我们有一个简单的 twig 函数,它将把它分开并找到所有文件名以将它们分别包含在开发环境中。

class AssetService
{
    protected $rootDir;

    public function __construct($rootDir)
    {
        $this->rootDir = $rootDir;;
    }

    public function getJavascriptFiles($ref)
    {
        $output = [];
        $data = json_decode(file_get_contents(realpath($this->rootDir . '/Resources/config/include.json')), true);
        $paths = [];

        foreach ($data[$ref]['cwd'] as $key => $path) {
            $paths['%' . $key . '%'] = $this->rootDir . '/../' . $path;
        }

        foreach ($data[$ref]['files'] as $file) {
            $output = array_merge($output, str_replace(
                $paths,
                array_keys($data[$ref]['cwd']),
                $this->globRecursive(str_replace(array_keys($paths), $paths, $file), GLOB_NOCHECK)
            ));
        }

        return $output;
    }

    protected function globRecursive($pattern, $flags = 0)
    {
        $files = glob($pattern, $flags);
        foreach (glob(dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
            $files = array_merge($files, $this->globRecursive($dir . '/' . basename($pattern)));
        }
        return $files;
    }
}

然后在开发中我们得到如下所示的输出:

<script src="/js/vendor/jquery/dist/jquery.min.js"></script>
<script src="/js/vendor/underscore/underscore-min.js"></script>
<script src="/js/vendor/backbone/backbone-min.js"></script>
<script src="/js/AppBundle/Bundle.js"></script>
<script src="/js/AppBundle/Router.js"></script>
<script src="/js/AppBundle/Collection/Products.js"></script>
<script src="/js/ProjectsBundle/Model/Project.js"></script>
<script src="/js/AppBundle/View/Product/Index.js"></script>

并且在使用相同的逻辑使用 Grunt 对文件进行丑化之后,在生产中我们有:

<script src="/js/lib.js"></script>
<script src="/js/app.js"></script>

有点 hacky,但它是即时更新并使 PHP 生产环境完全不知道前端资产。