Building static assets is slow and resource-intensive.
It's often done in CI pipelines (via Mix, Webpack, and friends) to ensure test pass, even if we don't need the static assets.
Let's see how to avoid building static assets!
Feature Tests
The primary reason to build static assets in a CI pipeline is to generate the mix-manifest.json
file.
This allows the mix()
helper to work when running Laravel Feature tests. The feature tests make HTTP calls into your app, and thus often render blade templates that use the mix()
helper.
If you don’t have a manifest file, an error is thrown!
To generate the manifest file, we typically use npm (or yarn) to install dependencies and run Webpack/Vite tasks:
# Build static assets
npm ci --no-audit
npm run dev
Sidenote: You should almost definitely be committing your
package-lock.json
file and runningnpm ci --no-audit
instead ofnpm install
!
Skipping NodeJS Tasks
Your public/mix-manifest.json
file likely looks something like this:
{
"/js/app.js": "/js/app.js",
"/js/foo.js": "/js/foo.js",
"/css/app.css": "/css/app.css"
}
Or if you're using Vite, your public/build/manifest.json
file might look like this:
{
"resources/css/app.css": {
"file": "assets/app.74390ffe.js",
"src": "resources/css/app.css",
"isEntry": true
},
"resources/js/app.js": {
"file": "assets/app.f40b63e3.js",
"src": "resources/js/app.js",
"isEntry": true
}
}
As noted, without these files, the mix()
and vite()
helpers will raise an error.
Here's the secret: You don't necessarily need this file to exist for your tests!
Within your test's setUp()
method, you can add the following magic:
protected function setUp(): void
{
parent::setUp();
// If using Mix
$this->withoutMix();
// If using Vite
$this->withoutVite();
}
With that in place, the mix()
/vite()
helper won't return any errors with a missing manifest file. Your tests can pass without needing to run NodeJS tasks!
Alternative Method
Another thing you can do is create a manifest file for your CI pipeline that you copy for testing.
We can commit a "test" manifest file (perhaps in tests/mix-manifest.json
. Then, in our CI pipeline scripts, we copy that "fake" mix file just before running tests:
# What if we created a manifest file just for testing?
# During CI, we can just move it where it needs to go
# Mix/Webpack
cp tests/mix-manifest.json public/mix-manifest.json
# Vite
mkdir -p public/build
cp tests/text-manifest.json public/build/manifest.json
# And then run your tests, no NodeJS required!
php artisan test
This (or any method!) that creates a correct manifest file can help you save a LOT of time and server resources in your CI build pipelines.
With this method, you'll need to keep
tests/mix-manifest.json
up to date with the correct list of files your configuration generates.
When do you need to build assets?
Here's the most common times you can't use the above, and DO need to build assets in your CI pipelines:
- When building a deployable "artifact" (zip file, container image, etc) that needs static assets
- Running Node commands (
eslint
) as part of your test suite - When you are browser testing with something like Laravel Dusk or Cypress
What if I need to build assets?
You can still save precious time even if you need to build your static assets in your CI scripts!
My favorite package for this is Airdrop (by Aaron Francis). It helps you build static assets only if they’ve changed between commits. If they have not changed, you can download them from a file system driver such as S3.