Injecting webpack chunks to twig files Injecting webpack chunks to twig files symfony symfony

Injecting webpack chunks to twig files


Extraction

As said in the Webpack documentation, file hashes can be extracted from compilation stats.

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

But it's easier to use one of the plug-ins: webpack-manifest-plugin or assets-webpack-plugin. For example, the WebpackManifestPlugin creates a simple JSON file manifest.json with bundles mapping to actual file names:

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

Now you need to read it and change the paths in the templates.

Injection

For example, we can create a simple Twig extension:

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];            }),        ];    }}

And apply this filter in your template:

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