Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Next basset version #143

Open
wants to merge 46 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
423c921
wip
pxpm Oct 21, 2024
d6ea3df
wip
pxpm Oct 22, 2024
84bc9fb
Apply fixes from StyleCI
tabacitu Oct 22, 2024
2621695
wip
pxpm Oct 23, 2024
94f4862
wip
pxpm Oct 23, 2024
0785bff
Apply fixes from StyleCI
tabacitu Oct 23, 2024
8a477d4
wip
pxpm Oct 31, 2024
a2f18c1
Apply fixes from StyleCI
tabacitu Oct 31, 2024
c2a5a3d
wip
pxpm Nov 12, 2024
c0fa406
Apply fixes from StyleCI
tabacitu Nov 12, 2024
0799f7c
wip
pxpm Nov 13, 2024
1b48fe7
wip
pxpm Nov 14, 2024
914042e
Apply fixes from StyleCI
tabacitu Nov 14, 2024
aa5277d
wip
pxpm Nov 15, 2024
45cd919
wip
pxpm Nov 15, 2024
184a8b1
Apply fixes from StyleCI
tabacitu Nov 15, 2024
61afd11
fix stan
pxpm Nov 15, 2024
61f7b75
Apply fixes from StyleCI
tabacitu Nov 15, 2024
54bb591
Merge pull request #142 from Laravel-Backpack/remove-symlink
pxpm Nov 21, 2024
2a0018a
wip
pxpm Nov 25, 2024
dde32a7
Apply fixes from StyleCI
tabacitu Nov 25, 2024
b88a1b5
wip
pxpm Dec 16, 2024
62a0d3d
Apply fixes from StyleCI
tabacitu Dec 16, 2024
9b709ff
remove unused variables
pxpm Dec 16, 2024
de0bada
Merge branch 'next' of https://github.com/Laravel-Backpack/basset int…
pxpm Dec 16, 2024
a615cff
Apply fixes from StyleCI
tabacitu Dec 16, 2024
7c31ab3
fix tests
pxpm Dec 16, 2024
4eaf9b7
wip
pxpm Dec 17, 2024
0d23dbb
Apply fixes from StyleCI
tabacitu Dec 17, 2024
6964d02
wip
pxpm Dec 17, 2024
419f0c1
Apply fixes from StyleCI
tabacitu Dec 17, 2024
8785565
public files dont need to be internalized
pxpm Dec 26, 2024
4c6a702
Apply fixes from StyleCI
tabacitu Dec 26, 2024
306d622
fix for vendor files
pxpm Dec 26, 2024
2383f8b
Merge branch 'next' of https://github.com/Laravel-Backpack/basset int…
pxpm Dec 26, 2024
fc00c75
wip
pxpm Dec 26, 2024
aac27a7
wip
pxpm Dec 31, 2024
e2cbbe9
Apply fixes from StyleCI
tabacitu Dec 31, 2024
a8936df
wip
pxpm Jan 2, 2025
92e60be
Apply fixes from StyleCI
tabacitu Jan 2, 2025
497faf6
wip
pxpm Jan 2, 2025
74a6b43
Update readme.md
tabacitu Jan 14, 2025
2f77066
fix local files inclusion
pxpm Jan 22, 2025
bdb5284
Apply fixes from StyleCI
tabacitu Jan 22, 2025
d82527f
Merge pull request #144 from Laravel-Backpack/fix-local-files
pxpm Jan 22, 2025
7fc051a
Update readme.md
tabacitu Jan 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@
<script src="{{ basset('https://cdn.com/path/to/file.js') }}">
```

That's all you need to do. **Basset will download the file to `storage/app/public/bassets` from wherever it is, then output the now-public path to your asset.**
That's all you need to do. **Basset will download the file to the predefined disk, then output that disk path to your asset.**

Using Basset, you easily internalize and use:
- files from external URLs (like CDNs)
- files from internal, but non-public URLs (like the vendor directory)
- entire archives from external URLs (like GitHub)
- entire directories from local, non-public paths (like other local projects)

No more publishing package files. No more using NPM just to download some files. It's a simple yet effective solution in the age of `HTTP/2` and `HTTP/3`.
No more publishing package files. No more NPM bloat, just to download some files. It's a simple yet effective solution in the age of `HTTP/2` and `HTTP/3`.

## Installation

Expand All @@ -38,15 +38,27 @@ php artisan basset:install
php artisan vendor:publish --provider="Backpack\Basset\BassetServiceProvider"
```

> **Note**
> Basset is disabled by default on local environment. If you want to change it, please set `BASSET_DEV_MODE=false` in your env file.

#### Storage Symlink
Basset uses the `public` disk to store cached assets in a directory that is publicly-accessible. So it needs you to run `php artisan storage:link` to create the symlink. The installation command will create ask to run that, and to add that command to your `composer.json`. That will most likely make it work on your development/staging/production servers. If that's not the case, make sure you create the links manually wherever you need them, with the command `php artisan storage:link`.
By default, Basset uses the `storage` directory to store cached assets in a directory that is publicly-accessible. So it needs you to run `php artisan storage:link` to create the symlink. The installation command will ask to run that, and to add that command to your `composer.json`. That will most likely make it work on your development/staging/production servers. If that's not the case, make sure you create the links manually wherever you need them, with the command `php artisan storage:link`.

#### Disk
By default Basset uses the `public` disk. If you're having trouble with the assets not showing up on page, you might have an old Laravel configuration for it. Please make sure your disk is properly setup on `config/filsystems.php` - it should look like [the default one](https://github.com/laravel/laravel/blob/10.x/config/filesystems.php#L39-L45).

#### Where to store cached assets?

Basset provides a few options out-of-the-box:
- (a) inside the storage directory, eg. `storage/app/basset` [default]
- PROs: the Git history is clean - because your cached assets will NOT be tracked by Git;
- CONs: in rare cases, your deployments to staging/production could break, because assets are being re-cached upon `composer update`; if a CDN is down during deployment, the system will not be able to internalize it; if will however internalize it when the CDN is back on, and the page that loads the file gets accessed;
- How to enable: do nothing, or do `BASSET_DISK=basset` in your .env file;
- (b) inside the public directory, eg. `public/basset`
- PROs: you are certain the same assets you have on localhost will be in production, because the assets are commited to Git;
- CONs: your Git history will be dirtier, because it will contain changes to libraries of CSS/JS files;
- How to enable: do `BASSET_DISK=public_basset` in your .env file or `config/backpack/basset.php` config file;
- (c) custom - you can completely customize what disk is used to store the assets; take a look at the config file for details; most common customizations:
- store assets on a S3 bucket (using a custom disk);

## Usage

### The `basset()` Helper
Expand All @@ -59,14 +71,14 @@ For local from CDNs:
<link href="{{ asset('path/to/public/file.css') }}">

{{-- you can do --}}
<link href="{{ basset('path/to/public/file.css' }}">
<link href="{{ basset('path/to/public/file.css') }}">
<link href="{{ basset('https://cdn.com/path/to/file.css') }}">
<link href="{{ basset(base_path('vendor/org/package/assets/file.css')) }}">
<link href="{{ basset(storage_path('file.css')) }}">
```

Basset will:
- copy that file from the vendor directory to your `storage` directory (aka. internalize the file)
- copy that file from the vendor directory to your public disk.
- use the internalized file on all requests

### The `@basset()` Directive
Expand Down Expand Up @@ -171,10 +183,18 @@ If you require customized behavior after each asset is cached, you can set up a
## Configuration

Take a look at [the config file](https://github.com/Laravel-Backpack/basset/blob/main/src/config/backpack/basset.php) for all configuration options. Notice some of those configs also have ENV variables, so you can:
- enable/disable dev mode using `BASSET_DEV_MODE=false` - this will force Basset to internalize assets even on localhost
- enable/disable dev mode using `BASSET_DEV_MODE=false` - when enabled Basset will check for changes in your url/files and update the cached assets
- change the disk where assets get internalized using `BASSET_DISK=yourdiskname`
- disable the cache map using `BASSET_CACHE_MAP=false` (needed on serverless like Laravel Vapor)

### Storing assets in the application repository

If you would like to track the assets in your application repository and avoid downloading them on each deployment, you can set the `BASSET_DISK` environment variable to `public_basset`. This will store the assets in the `public/basset` directory by default and they can now be committed alongside the rest of your application code.

This is advantageous as you know what assets are in your application right when you deploy, avoiding issues like a cdn being down at the deployment time and breaking your application production.

```bash

## Deployment

There are a lot of deployment options for Laravel apps, but we'll try to cover the gotchas of the most popular ones here:
Expand Down
23 changes: 23 additions & 0 deletions src/AssetHashManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Backpack\Basset;

use Backpack\Basset\Contracts\AssetHashManagerInterface;

final class AssetHashManager implements AssetHashManagerInterface
{
public function generateHash(string $content): string
{
return hash('xxh32', $content);
}

public function appendHashToPath(string $path, string $hash): string
{
return preg_replace('/\.(css|js)$/i', "-{$hash}.$1", $path);
}

public function validateHash(string $content, string $hash): bool
{
return $this->generateHash($content) === $hash;
}
}
47 changes: 47 additions & 0 deletions src/AssetPathManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Backpack\Basset;

use Backpack\Basset\Contracts\AssetPathManagerInterface;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;

final class AssetPathManager implements AssetPathManagerInterface
{
private string $basePath;

public function __construct()
{
$this->basePath = (string) Str::of(config('backpack.basset.path'))->finish('/');
}

public function getBasePath(): string
{
return $this->basePath;
}

public function getPathOnDisk(string $asset): string
{
return Str::of($this->basePath)
->append($this->getCleanPath($asset))
->replace(['//'], '/');
}

public function getCleanPath(string $asset): string
{
return Str::of($asset)
->replace([base_path().'/', base_path(), base_path().'\\', 'http://', 'https://', '://', '<', '>', ':', '"', '|', "\0", '*', '`', ';', "'", '+'], '')
->before('?')
->replace(['/\\', '\\'], '/');
}

public function isLocal(string $path): bool
{
return File::exists($path);
}

public function setBasePath(string $basePath): void
{
$this->basePath = $basePath;
}
}
Loading
Loading