In Custom PHP Land, it can be complicated to load all server-side and client-side dependencies, libraries, and assets for a web application. However, all dependencies can be declared in a single composer.json in the vhost root.
An Example
{
"name": "my-org/my-lovely-web-app",
"description": "My Lovely Web App",
"license": "proprietary",
"repositories": [
{
"type": "composer",
"url": "https://my.org.edu/packages/"
},
{
"type": "git",
"url": "https://github.com/twbs/bootstrap.git"
},
{
"type": "git",
"url": "https://github.com/FortAwesome/Font-Awesome.git"
},
{
"type": "package",
"package": {
"name" : "jquery/jquery",
"version": "3.4.1",
"dist": {
"url": "https://code.jquery.com/jquery-3.4.1.min.js",
"type": "file"
}
}
},
],
"require": {
"twig/twig": "3.*",
"my-org/custom-package": "1.*",
"fortawesome/font-awesome": "5.15.1",
"jquery/jquery": "3.4.1",
"twbs/bootstrap": "v4.4.1"
},
"scripts": {
"post-autoload-dump": [
"rm -rf app/vendor",
"mkdir app/vendor",
"mv vendor/fortawesome app/vendor/fortawesome",
"mv vendor/jquery app/vendor/jquery",
"mv vendor/twbs app/vendor/twbs",
"rm -rf app/vendor/twbs/bootstrap/build app/vendor/twbs/bootstrap/js app/vendor/twbs/bootstrap/nuget app/vendor/twbs/bootstrap/scss app/vendor/twbs/bootstrap/site app/vendor/twbs/bootstrap/*.*"
]
}
}
This example assumes the web application has a vhost root (/) and a web root (/app). Server-side dependencies will be saved to /vendor by default.
Client-side dependencies need to be moved to the web root. This can be done by using Composer scripts. The above example saves all dependencies to /vendor; makes a new app/vendor directory; moves the javascript and css libraries to app/vendor; and removes some build files and other junk from one library. The resulting directory structure looks like this:
- composer.json
- composer.lock
- vendor
- my-org
- twig
- app
- vendor
- fortawesome
- jquery
- twbs
Why use server-side composer.json to declare all dependencies?
- All the dependencies for an app can be found in one single manifest file. It's like a table of contents of all the libraries your app needs.
- All dependencies can be fetched in a single build, instead of one build for PHP dependencies and one buld for JS dependencies.
- GitHub dependency graph and Dependabot alerts refers to composer.json for dependency review and security vulnerabilities.
- You don't have to rely on a CDN for availability and security. If the CDN assets are not available and ‘composer update’ fails, your dependencies don’t disappear.
- You don't have to allow any external domains in Content-Security-Policy headers, because all external resources are now local.