Pre-compilation
By default, Composer Asset Compiler loops installed Composer packages, and for each of them installs frontend dependencies and run a compiling script.
Doing that can can take several minutes per package. For a project with 20 or more packages to compile assets for, that is a lot.
To solve that problem, Composer Asset Compiler implements the so-called “pre-compilation”.
It works as follows:
- The packages’ assets are compiled separately and provided to a storage service supported by the plugin. At the time of writing, the plugin supports GitHub Artifacts, GitHub Release Binary, and “generic” archive URLs.
- When the Composer plugin finds a package to process, instead of immediately processing it, it checks if the package supports pre-compilation, and if so, it tries to download the pre-compiled assets.
- If pre-compiled assets are found, they are downloaded and used; if they are not found, the plugin continues installing dependencies and processing the assets “on the fly”, as usual.
Composer Asset Compiler does not care how the assets are compiled (step 1. above): as long as an archive with pre-compiled assets is found, the plugin can work with it.
Here’s an example of how we can configure pre-compilation for a package:
{
"name": "acme/foo",
"extra": {
"composer-asset-compiler": {
"script": "build",
"pre-compiled": {
"adapter": "gh-action-artifact",
"source": "assets-${ref}",
"target": "./assets/",
"config": {
"repository": "acme/foo"
}
}
}
}
}
The pre-compiled
object tells us the package supports pre-compilation.
Let’s look at the configuration in detail.
Target
pre-compiled.target
is the folder where the pre-compiled assets will be placed after download.
Adapter
pre-compiled.adapter
tells us where the precompiled assets are stored.
"gh-action-artifact"
in the above example tells us that the pre-compiled assets will be stored as GitHub Actions artifacts.
Other supported adapters are:
"gh-release-zip"
(assets save as GitHub release binary)"archive"
(assets saved in an archive accessible via a URL).
Source and Configuration
pre-compiled.source
and pre-compiled.config
have different meanings depending on the adapter
.
GitHub adapters configuration
The "gh-action-artifact"
and the "gh-release-zip"
adapters share the same values for pre-compiled.source
and pre-compiled.config
.
For both adapters, pre-compiled.source
is the name of the archive.
It may contain dynamic placeholders (like the ${ref}
in the snippet above). More on this below.
pre-compiled.config
is a configuration object for the adapter, and its only mandatory property is pre-compiled.config.repository
that is the owner and name of the GitHub repository.
For example, "repository": "acme/some-theme"
means the repository URL is https://github.com/acme/some-theme.git
.
If the repository is private, we need to specify the username of a GitHub user who has access to the repository, and an access token for that user.
The username can be set via the pre-compiled.config.user
property or via the GITHUB_USER_NAME
environment variable in the system running the Composer Asset Compiler.
The access token could be set via the pre-compiled.config.token
property, but this is discouraged. A safer approach is to use the GITHUB_USER_TOKEN
environment variable or rely on Composer authentication using the github-oauth
method. In the latter case, configuring the username is not necessary.
Archive adapter configuration
When using the archive
adapter, pre-compiled.source
is the full archive URL. It may contain dynamic placeholders (more on this below).
pre-compiled.config
is an object, and it is completely optional.
It can have a pre-compiled.config.type
to configure the archive type (supported: “zip”, “rar”, “tar” and “xz”). If it is not specified, it is guessed based on the file extension in the source URL, and if it has no file extension, it defaults to zip
.
An additional pre-compiled.config.auth
property can be used to set up authentication for the archive. It might be an object with user
and password
properties, in which case those will be used for HTTP Basic authentication. Alternatively, it can be a string holding the content of an Authorization
header.
Please note that any authentication set for Composer will apply.
Placeholders
Regardless of the adapter, pre-compiled.source
can contain one or more placeholders that are dynamically replaced when the assets are compiled.
The supported placeholders are:
${ref}
- replaced by the “reference” of the Composer package (which for GitHub hosted packages is the SHA1 of the commit installed).${version}
- replaced by the version of the Composer package.${mode}
- replaced by the Composer Asset Compiler mode (see “Execution Mode”)${hash}
- replaced by the hash of the package (see “Hash and Lock”)
Pre-compilation by stability
Sometimes we would like to have a different mechanism for pre-compilation, depending on whether the installed package has a stable
stability or not.
For example, when a package is required from a version (e. g. "~1.1.0"
), we might want to use the "gh-release-zip"
adapter, whereas when it is required from a branch (e. g. "dev-main"
) we might want to use the "gh-action-artifact"
.
That can be achieved by using two sets of pre-compiled
configuration, one specifying "stable"
and another "dev"
for stability
.
For example:
{
"name": "acme/some-theme",
"extra": {
"composer-asset-compiler": {
"script": "build",
"pre-compiled": [
{
"stability": "stable",
"adapter": "gh-release-zip",
"source": "assets-${version}",
"target": "./assets/",
"config": {
"repository": "acme/some-theme"
}
},
{
"stability": "dev",
"adapter": "gh-action-artifact",
"source": "assets-${ref}",
"target": "./assets/",
"config": {
"repository": "acme/some-theme"
}
}
]
}
}
}