Skip to main content

Setting up Laminas MVC to use the manifest

By now, you should have been able to generate bundles of JS files in the public/dist folder of your application with a scriplist.php manifest.

Your application directory structure should look like this:

.
+--browser
| +--build
| +--src
+--config
| +--autoload
| global.php
| local.php
| application.config.php
+--data
+--module
| +--Application
| | +--config
| | +--src
| | +--view
| +--AnotherModule
+--public
| +--assets
| | <your asset files>
| +--css
| | <your css files>
| index.js
| application.index.js
| npm.bootstrap.js
| npm.jquery.js
| npm.popper.js.js
| scriptlist.php
+--vendor
composer.json
composer.lock
package.json

How do you use the manifest in your Laminas MVC application?

This is where laminas-webpack comes into play to automate the loading of Webpack bundles that consumes the manifest file.

Using the laminas-webpack module

laminas-webpack provides two main pieces: a route listener and a view helper plugin.

The listener attaches to MvcEvent::EVENT_DISPATCH ("dispatch") event of the AbstractControllerclass. When it fires, it will look at the matched route to determine an entry point that the view template associated with the route should use.

The laminas-webpack module requires a configuration file in the config/autoload folder called webpack.global.php (the name of the file is irrelevant) which contains the following:

<?php
return [
/**
* webpack configuration
*/
'webpack' => [
/**
*
*/
'dist_path' => 'dist/',

/**
* Default entry point or key (see routes below)
*/
'default_entry_point' => 'main',

/**
* Entry point map file generated by Webpack
* Change this according to your webpack configuration
* A webpack plugin is available to generate the script list
*/
'entrypoint_map_file' => __DIR__ . '/../../public/dist/scriptlist.php',


/**
* Associative array of routes to match.
* Each entry can either be:
* a) 'key' only : this route will map to the default entry point set by 'default_entry_point'
* b) 'key' => 'value': this route map to the entry point set by 'value'
*
* The 'key' can be a wildcard. For example: 'items*' will match all routes starting with 'items' such as 'item/add'
*
*/
'routes' => [
'home' => 'application.index',
'mymoduleroute',
],
],
];

Using this configuration file, the home route (assuming this is the route for indexAction in the Application controller) will match the application.index entry point.

The mymoduleroute route does not have an associated entry point and will default to the main entry point as defined by default_entry_point.

The listener then uses the entry points map file set by entrypoint_map_file to create an array of scripts files to be loaded for the route. This array is stored in the scriptlist view variable of the layout template for the controller.

A alternate listener will come in the future to match view templates to entry points instead of using route matching. If someone wants to contribute to this listener, I welcome it.

Using the webpackScriptLoader view helper plugin

The laminas-webpack also provides a view helper plugin that adds the script tags to the <head> section of the page. It depends on the HeadScript helper to append the tags.

The layout template needs to call the plugin to add all the scripts:

<html>
<head>
<!-- other head tags -->
<?php
$this->webpackScriptLoader();
echo $this->headscript();
?>
</head>
<body>
<!-- your rendering -->
</body>
</html>

If a route has no associated entry point, then $this->webpackScriptLoader() does nothing.

Further work

I hope you found this guide useful.

It's work in progress and if you have questions, found an error or think of additional feature, let me know by creating an issue.