Setting up Laminas MVC to use Webpack
This is not a guide on setting up a Webpack environment. I got inspired by this excellent answer on Stackoverflow by Loilo. Further investigations led me to the Webpack plugin castiron/webpack-php-manifest.
This is not a guide on setting up a Laminas MVC application either. The Laminas MVC Skeleton is a good place to start and this is what I used for my own application.
Setting up your Laminas application
So here's a typical Laminas MVC directory structure:
.
+--config
| +--autoload
| application.config.php
+--data
+--module
| +--Application
| | +--config
| | +--src
| | +--view
| +--AnotherModule
+--public
| +--js
| +--css
+--vendor
composer.json
composer.lock
So where's the best place to hold all your JS sources? That's up to you. I personally
decided to have all my JS sources in a browser
subfolder of the root directory.
Then I followed the guidelines provided by Loilo in his Stackoverflow answer
and created src
and build
folders under browser
like this:
.
+--browser
| +--build
| +--src
+--config
| +--autoload
| application.config.php
+--data
+--module
| +--Application
| | +--config
| | +--src
| | +--view
| +--AnotherModule
+--public
| +--js
| +--css
+--vendor
composer.json
composer.lock
I also decided that the root folder would also be where the node
modules would be located.
It could have been anywhere but it allows you to use all kinds of node
tools and automation
in the project. So once you initialize your node
environment, you end up with this:
.
+--browser
| +--build
| +--src
+--config
| +--autoload
| application.config.php
+--data
+--module
| +--Application
| | +--config
| | +--src
| | +--view
| +--AnotherModule
+--node_modules
+--public
| +--js
| +--css
+--vendor
composer.json
composer.lock
package.json
Setting up your JS files
How you want to set up your JS source files is up to you.
I personally wanted to have some level of structure and organization in source files that
matches the structure of my application's pages. Since each page rendered by the application
is its own frontend JS app, my src
folder matches the module/controller-action/view
structure.
In addition, you can share common JS modules using a lib
folder within the src
folder.
For example, if you have a module called mymodule
with a controller called mycontroller
and the following actions index
, edit
, detail
with corresponding view templates, then you
can use a structure like this:
.
+--browser
| +--build
| +--src
| +--lib
| | common-code.js
| +--mymodule
| +--mycontroller
| index.js
| details.js
| edit.js
+--...
The important concept here is that index.js
, details.js
and edit.js
are entry points
for the JS scripts that the corresponding view template will need to load.
This means that index.js
will
need to require or import all the libraries and modules that it needs to rendered the frontend
part of the page such that Webpack can create a bundle of scripts for the view.
As example, if you need Bootstrap in your page, then index.js
could look like:
/**
* This imports Bootstrap JS and its css
*/
import 'bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
/*
you own code go here
*/
Webpack will include Bootstrap's dependencies Jquery
and popper.js
in the bundle.
Sharing entry points
Obviously, if you follow strictly my proposed structure, you would end up with as many JS files as you have pages in your application.
To avoid this, I usually have a common entry point for all pages that use the same bundle like
the Bootstrap
bundle above. This is useful when the only thing your page needs is Bootstrap
.
Using the bundles in Laminas MVC
Laminas Skeleton application expects the public
folder to hold all Internet-facing assets.
Therefore, all the bundles generated by Webpack from the src
files should go somewhere under the public
folder.
I personally use a public/dist
folder to hold the generated bundles.
Depending on how you set up Webpack, there will be many bundles generated in your public/dist
folder. You will need
to make sure that your Laminas view template loads all the scripts of an entry point's bundle which
can very quickly become complex unless you automate the development process.
More on this in the next page of this guide.