Hey,
I would like to share my feedback on this promising tool to manage multiple PHP project in the same repository.
Here is what I want to achieve
- Setup a monorepo of multiple PHP/Symfony/API-platform projects & some shared lib or shared components (api-1, api-2, api-3, ... shared-lib)
- Easily manage my dependencies (sync between all my projects)
- Easily use shared components/libs into API projects
I look at
Walk-through my exploration with this tool
Scaffolding
- root (backend)
- composer.json
- composer.lock
- .gitignore
- vendor
- api-1
- api-2
- shared-lib
Migration Multiple API projects to Monorepo
First, I had to change symfony/flex
for symfony/symfony
. Symfony Flex will install all recipe at the monorepo root which is really annoying.
Create the root composer.json
{
"name": "plop/backend",
"require": {
"beberlei/composer-monorepo-plugin": "~0.13",
"php": "^7.1.3",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/api-pack": "^1.2",
"auth0/jwt-auth-bundle": "^3.0",
"doctrine/doctrine-migrations-bundle": "^2.0",
"league/flysystem-aws-s3-v3": "^1.0",
"oneup/flysystem-bundle": "^3.1",
"ramsey/uuid-doctrine": "^1.5",
"sensio/framework-extra-bundle": "^5.4",
"sentry/sentry-symfony": "^3.1",
"stof/doctrine-extensions-bundle": "^1.3",
"symfony-bundles/redis-bundle": "^2.2",
"symfony/console": "4.3.*",
"symfony/form": "4.3.*",
"symfony/framework-bundle": "4.3.*",
"symfony/http-client": "4.3.*",
"symfony/workflow": "4.3.*",
"symfony/yaml": "4.3.*",
"symfony/symfony": "4.3.*"
},
"require-dev": {
"behat/behat": "^3.5",
"behat/mink": "dev-master",
"behat/mink-browserkit-driver": "dev-master",
"behat/mink-extension": "dev-master",
"behat/symfony2-extension": "^2.1",
"behatch/contexts": "^3.0",
"doctrine/doctrine-fixtures-bundle": "^3.2",
"friendsofphp/php-cs-fixer": "^2.15",
"hautelook/alice-bundle": "^2.5",
"phpstan/phpstan": "^0.11.15",
"phpstan/phpstan-symfony": "^0.11.6",
"symfony/debug-pack": "^1.0",
"symfony/dotenv": "^4.3"
}
}
And configure monorepo.json
into api-*
folders
{
"deps": [
"vendor/api-platform/api-pack",
"vendor/auth0/jwt-auth-bundle",
"vendor/doctrine/doctrine-migrations-bundle",
"vendor/league/flysystem-aws-s3-v3",
"vendor/oneup/flysystem-bundle",
"vendor/ramsey/uuid-doctrine",
"vendor/sensio/framework-extra-bundle",
"vendor/sentry/sentry-symfony",
"vendor/stof/doctrine-extensions-bundle",
"vendor/symfony-bundles/redis-bundle",
"vendor/symfony/console",
"vendor/symfony/dotenv",
"vendor/symfony/form",
"vendor/symfony/framework-bundle",
"vendor/symfony/http-client",
"vendor/symfony/workflow",
"vendor/symfony/yaml",
"vendor/symfony/symfony"
],
"deps-dev": [
"vendor/behat/behat",
"vendor/behat/mink",
"vendor/behat/mink-browserkit-driver",
"vendor/behat/mink-extension",
"vendor/behat/symfony2-extension",
"vendor/behatch/contexts",
"vendor/doctrine/doctrine-fixtures-bundle",
"vendor/friendsofphp/php-cs-fixer",
"vendor/hautelook/alice-bundle",
"vendor/phpstan/phpstan",
"vendor/phpstan/phpstan-symfony",
"vendor/symfony/debug-pack"
],
"autoload": {
"psr-4": {
"App\\": "src/",
"Fixtures\\": "fixtures/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
}
}
}
Composer install 🚀
run composer install
, it detects & generates the subpackage autoload 🎉
Trying APIs
Directly through REST client, everything seems to work 👌
I can resolve asset, when I search in autoloader, there is no asset Class loaded. Even if I try to add in monorepo.json : "vendor/symfony/asset"
, it is not resolved. I tried to install it, reference it, ... It is required by api-platform/api-pack
.
Some tests failed. Seems there is some problem with autoload providers for faker in Fixtures, error are not clear on this.
Add to that, I have this when I run any console command:
PHP Warning: Class 'Nette\DI\Config\Adapter' not found in /var/www/vendor/nette/di/src/compatibility.php on line 10
PHP Stack trace:
PHP 1. {main}() /var/www/vendor/behat/behat/bin/behat:0
PHP 2. require() /var/www/vendor/behat/behat/bin/behat:15
PHP 3. require_once() /var/www/api/vendor/autoload.php:5
PHP 4. composerRequireOnce8cfb30f5c45c15f7ff26872515d65e35() /var/www/api/vendor/composer/autoload_real.php:56
PHP 5. require_once() /var/www/api/vendor/composer/autoload_real.php:61
PHP 6. class_alias() /var/www/vendor/nette/di/src/compatibility.php:10
PHP Warning: Class 'Nette\DI\Definitions\Statement' not found in /var/www/vendor/nette/di/src/compatibility.php on line 11
PHP Stack trace:
PHP 1. {main}() /var/www/vendor/behat/behat/bin/behat:0
PHP 2. require() /var/www/vendor/behat/behat/bin/behat:15
PHP 3. require_once() /var/www/api/vendor/autoload.php:5
PHP 4. composerRequireOnce8cfb30f5c45c15f7ff26872515d65e35() /var/www/api/vendor/composer/autoload_real.php:56
PHP 5. require_once() /var/www/api/vendor/composer/autoload_real.php:61
PHP 6. class_alias() /var/www/vendor/nette/di/src/compatibility.php:11
PHP Warning: Class 'Nette\DI\Definitions\ServiceDefinition' not found in /var/www/vendor/nette/di/src/compatibility.php on line 12
PHP Stack trace:
PHP 1. {main}() /var/www/vendor/behat/behat/bin/behat:0
PHP 2. require() /var/www/vendor/behat/behat/bin/behat:15
PHP 3. require_once() /var/www/api/vendor/autoload.php:5
PHP 4. composerRequireOnce8cfb30f5c45c15f7ff26872515d65e35() /var/www/api/vendor/composer/autoload_real.php:56
PHP 5. require_once() /var/www/api/vendor/composer/autoload_real.php:61
PHP 6. class_alias() /var/www/vendor/nette/di/src/compatibility.php:12
Same problem with Nette\DI\Config\Adapter
, seems it has not been included into the autoloader.
$ vendor/bin/phpstan analyse -c phpstan.neon src/ --level=7 --memory-limit=512M
PHP Warning: Class 'Nette\DI\Config\Adapter' not found in /var/www/vendor/nette/di/src/compatibility.php on line 10
PHP Stack trace:
PHP 1. {main}() /var/www/vendor/phpstan/phpstan/bin/phpstan:0
PHP 2. require_once() /var/www/vendor/phpstan/phpstan/bin/phpstan:14
PHP 3. require_once() /var/www/api/vendor/autoload.php:5
PHP 4. composerRequireOnce8cfb30f5c45c15f7ff26872515d65e35() /var/www/api/vendor/composer/autoload_real.php:56
PHP 5. require_once() /var/www/api/vendor/composer/autoload_real.php:61
PHP 6. class_alias() /var/www/vendor/nette/di/src/compatibility.php:10
PHP Warning: Class 'Nette\DI\Definitions\Statement' not found in /var/www/vendor/nette/di/src/compatibility.php on line 11
PHP Stack trace:
PHP 1. {main}() /var/www/vendor/phpstan/phpstan/bin/phpstan:0
PHP 2. require_once() /var/www/vendor/phpstan/phpstan/bin/phpstan:14
PHP 3. require_once() /var/www/api/vendor/autoload.php:5
PHP 4. composerRequireOnce8cfb30f5c45c15f7ff26872515d65e35() /var/www/api/vendor/composer/autoload_real.php:56
PHP 5. require_once() /var/www/api/vendor/composer/autoload_real.php:61
PHP 6. class_alias() /var/www/vendor/nette/di/src/compatibility.php:11
PHP Warning: Class 'Nette\DI\Definitions\ServiceDefinition' not found in /var/www/vendor/nette/di/src/compatibility.php on line 12
PHP Stack trace:
PHP 1. {main}() /var/www/vendor/phpstan/phpstan/bin/phpstan:0
PHP 2. require_once() /var/www/vendor/phpstan/phpstan/bin/phpstan:14
PHP 3. require_once() /var/www/api/vendor/autoload.php:5
PHP 4. composerRequireOnce8cfb30f5c45c15f7ff26872515d65e35() /var/www/api/vendor/composer/autoload_real.php:56
PHP 5. require_once() /var/www/api/vendor/composer/autoload_real.php:61
PHP 6. class_alias() /var/www/vendor/nette/di/src/compatibility.php:12
PHP Fatal error: Cannot redeclare Zend\Diactoros\createUploadedFile() (previously declared in /var/www/vendor/zendframework/zend-diactoros/src/functions/create_uploaded_file.php:19) in /var/www/vendor/zendframework/zend-diactoros/src/functions/create_uploaded_file.php on line 39
PHP Stack trace:
PHP 1. {main}() /var/www/vendor/phpstan/phpstan/bin/phpstan:0
PHP 2. {closure:/var/www/vendor/phpstan/phpstan/bin/phpstan:17-36}() /var/www/vendor/phpstan/phpstan/bin/phpstan:38
PHP 3. require_once() /var/www/vendor/phpstan/phpstan/bin/phpstan:27
PHP 4. ComposerAutoloaderInit43c17f21039003d818a50fbd4ff86312::getLoader() /var/www/vendor/autoload.php:7
PHP 5. composerRequire43c17f21039003d818a50fbd4ff86312() /var/www/vendor/composer/autoload_real.php:56
Going further
I think this composer plugin works pretty well but I am stuck with weird cases I need to resolved.
Add to that, I build Docker image to ship my API, is there a command to hard copy dependencies of a specific project into it's vendor folder such as composer monorepo:package-vendor
(to avoid copy all root vendor folder into Docker image).
Let me know if you want another insight!
If you have any tips to fix some issues thanks in advance!