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:
import 'bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
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.