Create a repository for your extension from this template.
(rename the header after initialization and change the text of the paragraph)
(remove this section after initialization)
Run:
php init.php
It will ask to enter an extension name and some other information. After the initialization, the script will prompt you to run npm install.
After initialization, placeholders in the readme file will be replaced with values specific to your extension. Use the changed readme as the documentation.
After initialization, you can remove init.php file from your repository. Commit the changes and proceed to configuration & building.
Create config.json file in the root directory. You can copy config-default.json and rename it to config.json.
When reading, this config will be merged with config-default.json. You can override default parameters in the created config.
Parameters:
- espocrm.repository – from what repository to fetch EspoCRM;
- espocrm.branch – what branch to fetch (
stableis set by default); you can specify version number instead (e.g.9.1.0); - database - credentials of the dev database;
- install.siteUrl – site url of the dev instance;
- install.defaultOwner – a webserver owner (important to be set right);
- install.defaultGroup – a webserver group (important to be set right).
You can override EspoCRM config. Create config.php in the root directory of the repository. This file will be applied after EspoCRM installation (when building).
Example:
<?php
return [
'useCacheInDeveloperMode' => true,
];After building, EspoCRM instance with installed extension will be available at site directory. You will be able to access it with credentials:
- Username: admin
- Password: 1
- You need to have node, npm, composer installed.
- Run
npm install(ornpm ciif you are not building the extension from scratch). - Create a database. Note that without the created database instance building will fail. The database name is set in the config file. You can change it.
It will download EspoCRM (from the repository specified in the config), then build and install it. Then it will install the extension.
Command:
npm run all
Note: It will remove a previously installed EspoCRM instance, but keep the database intact.
Note: If an error occurred, check site/data/logs/ for details. It's often a database is not created.
You need to run this command every time you make changes in src directory, and you want to try these changes on Espo instance.
Command:
npm run sync
To avoid running this command manually, use a file watcher in your IDE. The configuration for PhpStorm is included in this repository. See below about the file watcher.
AfterInstall.php will be applied for EspoCRM instance.
Command:
node build --after-install
Command:
npm run extension
The package will be created in build directory.
Note: The version number is taken from package.json.
If your extension requires other extensions, there is a way to install them automatically while building the instance.
Necessary steps:
-
Add the current EspoCRM version to the
config.php:<?php return [ 'version' => '9.3.0', ];
-
Create the
extensionsdirectory in the root directory of your repository. -
Put needed extensions (e.g.
my-extension-1.0.0.zip) in this directory.
Extensions will be installed automatically after running the command node build --all or node build --install.
- Do development in
srcdir. - Run
npm run sync. - Test changes in EspoCRM instance at
sitedir.
You can block out new entity types right in Espo (using Entity Manager) and then copy generated custom files (site/custom dir) to the repository (src dir) using copy-custom.js script.
- Create entity types, fields, layouts, relationships in Espo (it should be available in
sitedir after building). - Run
node copy-custom.js. It will copy all files fromsite/customtosrc/files/custom/Espo/Modules/{@name}and apply needed modifications to files. - Remove files from
site/custom. - Run
npm run sync. It will copy files from the repository to Espo build (site/custom//Espo/Modules/{@name}dir). - Clear cache in Espo.
- Test in Espo.
- Commit changes.
You can remove copy-custom.js from the repository if you don't plan to use it future.
If your extension requires additional libraries, they can be installed by composer:
- Create a file
src/files/custom/Espo/Modules/{@name}/composer.jsonwith your dependencies. You can change dir to this directory and add composer dependencies using composer require. - Once you run
node build --allornode build --composer-install, composer dependencies will be automatically installed. - Create a file
src/files/custom/Espo/Modules/{@name}/Resources/autoload.json.
Note: The extension build will contain only the vendor directory without the composer.json file.
The autoload.json file defines paths for namespaces:
{
"psr-4": {
"LibraryNamespace\\": "custom/Espo/Modules/{@name}/vendor/<vendor-name>/<library-name>/path/to/src"
}
}This definition is needed because in EspoCRM extensions are not installed via composer, they are included in runtime.
For static analysis, add to phpstan.neon:
excludePaths:
- src/files/custom/Espo/Modules/{@name}/vendor
scanDirectories:
- site/custom/Espo/Modules/{@name}/vendor
The version number is stored in package.json and package-lock.json.
Bumping version:
npm version patch
npm version minor
npm version major
To prepare an Espo instance for tests, run:
npm run prepare-test
It downloads the Espo package, unzips it in the site directory, and then runs composer install. To be used for unit tests and static analysis in CI environment as it takes less time than the full installation (with database).
You need to install composer dev dependencies in the root first:
composer install
This root composer serves only for unit tests static analysis.
Command to run unit tests:
vendor/bin/phpunit
or with a path:
vendor/bin/phpunit tests/unit/Espo/Modules/{@name}
or:
npm run unit-tests
Unit tests should be placed in tests/unit/Espo/Modules/{@name} directory and be in tests\unit\Espo\Modules\{@name}
namespace.
You need to install composer dev dependencies in the root first:
composer install
Command to run static analysis:
vendor/bin/phpstan
or:
npm run sa
PHPStan scans sources in the src and site directories as it's configured in phpstan.neon.
Integrations tests are run from the site directory.
You need to build a test instance first:
-
npm run sync -
(cd site; grunt test)You need to create a config file
tests/integration/config.php:<?php return [ 'database' => [ 'driver' => 'pdo_mysql', 'host' => 'localhost', 'charset' => 'utf8mb4', 'dbname' => 'TEST_DB_NAME', 'user' => 'YOUR_DB_USER', 'password' => 'YOUR_DB_PASSWORD', ], ];
Command to run integration tests:
(npm run sync; cd site; vendor/bin/phpunit tests/integration/Espo/Modules/{@name})
or:
npm run integration-tests
Note that integration tests needs the full Espo installation.
Integration tests should be placed in tests/integration/Espo/Modules/{@name} directory
and be in tests\integration\Espo\Modules\{@name} namespace.
You need to set the following paths to be ignored in your IDE:
buildsite/buildsite/custom/site/client/custom/site/tests/unit/Espo/Modules/{@name}site/tests/integration/Espo/Modules/{@name}
Note: The File Watcher configuration for PhpStorm is included in this repository (no need to configure).
You can set up a file watcher in the IDE to automatically copy and transpile files upon saving.
File watcher parameters for PhpStorm:
- Program:
node - Arguments:
build --copy-file --file=$FilePathRelativeToProjectRoot$ - Working Directory:
$ProjectFileDir$
The initialization script asks whether you want to use ES6 modules. It's recommended to choose "YES".
If you have chosen No and want to switch to ES6 later, then:
- Set bundled to true in
extension.json. - Set bundled and jsTranspiled to true in
src/files/custom/Espo/Modules/{@name}/Resources/module.json. - Add
src/files/custom/Espo/Modules/{@name}/Resources/metadata/app/client.json{ "scriptList": [ "__APPEND__", "client/custom/modules/{@nameHyphen}/lib/init.js" ] }
Install rollup.
In extension.json, add a command that will bundle the needed library into an AMD module. Example:
{
"scripts": [
"npx rollup node_modules/some-lib/build/esm/index.mjs --format amd --file build/assets/lib/some-lib.js --amd.id some-lib"
]
}Add the library module path to src/files/custom/Espo/Modules/{@name}/Resources/metadata/app/jsLibs.json
{
"some-lib": {
"path": "client/custom/modules/{@nameHyphen}/lib/some-lib.js"
}
}When you build, the library module will be automatically included in the needed location.
Note that you may also need to create rollup.config.js to set some additional Rollup parameters that are not supported via CLI usage.
Update the version number of espo-extension-tools in package.json to the latest one.
Run:
npm update espo-extension-tools
npm update espo-frontend-build-tools
Or just update everything:
npm update
(change this section after initialization)
Change the license in LICENSE file. The current license is intended for scripts of this repository. It's not supposed to be used for code of your extension.