symfony - Injecting webpack chunks to twig files -
i creating traditional website (not single page application) using php/twig/webpack tools. every site has own entry scripts. there vendor
, common
js files.
how can inject entry chunks with hash (to handle browser cache) in twig files? stored in templates
folder , should stay there (not go public
folder since used php). how can inject script tags twig files?
this twig general layout file:
{% 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 %}
and twig example contact page:
{% extends "layout/bootstrap.twig" %} {% block scripts %} <script src="js/entry-contact.js"></script> {% endblock %} {% block body %} <h1>contact form</h1> {% endblock %}
extraction
as said in webpack documentation, file hashes can extracted compilation stats.
module.exports = { /*...*/ plugins: [ function() { this.plugin("done", function(stats) { require("fs").writefilesync( "stats.json", json.stringify(stats.tojson()) ); }); } ] };
but it's easier use 1 of plug-ins: webpack-manifest-plugin or assets-webpack-plugin. example, webpackmanifestplugin
creates simple json file manifest.json
bundles mapping actual file names:
{ "main.js": "main.155567618f4367cd1cb8.js", "vendor.js": "vendor.c2330c22cd2decb5da5a.js" }
now need read , change paths in templates.
injection
for example, can create simple twig extension:
use twig_extension; use twig_simplefilter; class webpackassetsextension extends twig_extension { private $manifest; public function __construct() { // example! code intentionally simplified. // in real world should not parse json in production. // @ container building step (in bundle extensions, // compiler passes, etc) or @ 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]; }), ]; } }
and apply filter in template:
<script src="{{ 'vendor.js'|webpack_asset }}"></script>
Comments
Post a Comment