向Twig文件注入Webpack代码块

9

我正在使用php/twig/webpack工具创建一个传统网站(不是单页应用)。几乎每个网站都有自己的入口脚本。还有vendorcommon js文件。

如何在我的twig文件中注入带有哈希值的入口块(以处理浏览器缓存)?这些文件存储在templates文件夹中,并且应该留在那里(不进入public文件夹,因为它们被PHP使用)。如何向twig文件注入脚本标记?

这是我的twig通用布局文件:

{% block html %}
<!DOCTYPE html>
<html lang="pl">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <base href="/">
        <title>
            {% block title %}{% endblock %}
        </title>
        <link href="css/style.css" rel="stylesheet">
        <script src="js/vendor.js"></script>
        <script src="js/common.js"></script>
    </head>
    <body>
        {% block body %}
        {% endblock %}

        {% block scripts %}
        {% endblock %}
    </body>
</html>
{% endblock %}

例如联系页面可以使用Twig:
{% extends "layout/bootstrap.twig" %}

{% block scripts %}
    <script src="js/entry-contact.js"></script>
{% endblock %}

{% block body %}
    <h1>Contact form</h1>
{% endblock %}
1个回答

10

提取

正如在Webpack文档中所述,文件哈希可以从编译统计数据中提取。

module.exports = {
  /*...*/
  plugins: [
    function() {
      this.plugin("done", function(stats) {
        require("fs").writeFileSync(
          "stats.json", 
          JSON.stringify(stats.toJson())
        );
      });
    }
  ]
};

但是使用其中一个插件更容易:webpack-manifest-pluginassets-webpack-plugin。例如,WebpackManifestPlugin 会创建一个简单的JSON文件manifest.json,其中将捆绑映射到实际文件名:

{
  "main.js": "main.155567618f4367cd1cb8.js",
  "vendor.js": "vendor.c2330c22cd2decb5da5a.js"
}

现在您需要阅读并更改模板中的路径。

注入

例如,我们可以创建一个简单的Twig扩展

use Twig_Extension;
use Twig_SimpleFilter;

class WebpackAssetsExtension extends Twig_Extension
{
    private $manifest;

    public function __construct()
    {
        // ONLY FOR EXAMPLE! Code is intentionally simplified.
        // In real world you should not parse this JSON in production.
        // Do it at the container building step (in bundle extensions, 
        // compiler passes, etc) or at the cache warming.

        $jsonContents   = file_get_contents('manifest.json');
        $this->manifest = json_decode($jsonContents, true);
    }

    public function getFilters()
    {
        return [
            new Twig_SimpleFilter('webpack_asset', function (string $name): string {
                return $this->manifest[$name];
            }),
        ];
    }
}

并在您的模板中应用此过滤器:

<script src="{{ 'vendor.js'|webpack_asset }}"></script>

它确实有效 - 非常感谢。有一个问题 - 在Twig v2中使用new Twig_Filter()。再次感谢。 - piernik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接