Laravel如何将CSS/JS存于外部assets目录并通过asset()访问?
Great question! Let me break down how to replicate this setup in your own Laravel project—just creating an external assets directory won’t work on its own, since Laravel’s default asset() helper is tied to the public directory. Here’s what you need to do step by step:
1. Create the External Assets Directory
First, set up your directory structure exactly like the example:
Your-Project-Root/ ├─ assets/ │ ├─ css/ │ ├─ js/ │ └─ images/ └─ core/ ├─ app/ ├─ public/ └─ (rest of Laravel directories)
Make sure the assets folder lives outside your Laravel core project folder.
2. Configure Laravel’s Filesystem
Laravel uses filesystems to manage file storage and URLs. We’ll add a custom disk for our external assets:
Open config/filesystems.php and add a new entry to the disks array:
'disks' => [ // ... keep your existing disks (public, local, etc.) 'assets' => [ 'driver' => 'local', 'root' => base_path('../assets'), // Points to the external assets folder 'url' => env('APP_URL') . '/assets', 'visibility' => 'public', ], ],
base_path('../assets')works becausebase_path()returns the path to your Laravelcorefolder—adding../moves up one level to the project root where yourassetsfolder lives.- The
urlsetting defines the public URL prefix for these assets (e.g.,https://your-app.com/assets/css/style.css).
3. Configure Web Server Rewrites
Your web server (Apache/Nginx) needs to know how to handle requests to /assets—since this folder isn’t inside Laravel’s public directory, we need to add rewrite rules.
For Apache (using .htaccess)
If your project root has an .htaccess file (like the example), add these rules:
# Serve external assets directly RewriteRule ^assets/(.*)$ assets/$1 [L] # Forward all other requests to Laravel's public folder RewriteRule ^(.*)$ core/public/$1 [L]
This tells Apache:
- Any request starting with
/assetsshould load files directly from the externalassetsfolder. - All other requests get forwarded to Laravel’s
core/publicentry point.
For Nginx
Update your Nginx server block to include a location rule for assets:
server { listen 80; server_name your-app.com; root /path/to/your-project-root; # Point to your project root, not core/public # Serve external assets location /assets { alias /path/to/your-project-root/assets; expires 30d; add_header Cache-Control "public, immutable"; } # Forward Laravel requests to core/public/index.php location / { try_files $uri $uri/ /core/public/index.php?$query_string; } # PHP handler (adjust path to your PHP-FPM socket if needed) location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } }
4. Access Assets in Your Laravel App
Now you can generate URLs for your external assets using Laravel’s Storage facade, or create a custom helper function for cleaner code.
Option 1: Use the Storage Facade
In your Blade templates or controllers, use:
{{ Storage::disk('assets')->url('css/style.css') }} {{ Storage::disk('assets')->url('js/app.js') }}
This will generate the correct public URL (e.g., https://your-app.com/assets/css/style.css).
Option 2: Create a Custom Helper Function
If you want a cleaner syntax similar to asset(), create a custom helper:
- Create a new file
app/Helpers.php:
<?php if (!function_exists('asset_assets')) { function asset_assets(string $path): string { return Illuminate\Support\Facades\Storage::disk('assets')->url($path); } }
- Update
composer.jsonto autoload this file:
"autoload": { "files": [ "app/Helpers.php" ], // ... keep your existing autoload settings }
- Run
composer dump-autoloadto apply the changes.
Now you can use this helper in Blade:
{{ asset_assets('css/style.css') }}
Why This Works
Laravel’s default asset() helper is hardcoded to use the public disk, which points to the core/public folder. By setting up a custom filesystem disk and web server rewrites, we’re telling Laravel how to locate the external assets and how to generate valid public URLs for them—while ensuring the web server can serve those files directly.
内容的提问来源于stack exchange,提问作者davies

