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.