diff --git a/.env.example b/.env.example index 59e1c775..009cc76f 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,8 @@ APP_DEBUG=false APP_ENV=production -WEBPACK_ENV=production + +ASSET_ENV=production +ASSET_URL= DB_CONNECTION=mysql DB_HOST=localhost diff --git a/app/Services/Webpack.php b/app/Services/Webpack.php index ab1e79d2..a9fbae64 100644 --- a/app/Services/Webpack.php +++ b/app/Services/Webpack.php @@ -5,22 +5,42 @@ declare(strict_types=1); namespace App\Services; use Illuminate\Support\Arr; +use Illuminate\Support\Str; use Illuminate\Filesystem\Filesystem; class Webpack { protected $manifest = []; - public function __construct(Filesystem $filesystem) + /** @var Option */ + protected $options; + + public function __construct(Filesystem $filesystem, Option $options) { $path = public_path('app/manifest.json'); if ($filesystem->exists($path)) { $this->manifest = json_decode($filesystem->get($path), true); } + + $this->options = $options; } public function __get(string $path) { return Arr::get($this->manifest, $path, ''); } + + public function url(string $path): string + { + if (Str::startsWith(config('app.asset.env'), 'dev')) { + $base = config('app.asset.url'); + + return "$base:8080/$path"; + } else { + $path = $this->$path; + $cdn = $this->options->get('cdn_address'); + + return $cdn ? "$cdn/app/$path" : url("/app/$path"); + } + } } diff --git a/app/helpers.php b/app/helpers.php index 75b50e7d..153bc7bd 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -7,20 +7,9 @@ use Illuminate\Support\Arr; use Illuminate\Support\Str; if (! function_exists('webpack_assets')) { - function webpack_assets(string $relativeUri): string + function webpack_assets(string $path): string { - if (env('WEBPACK_ENV', 'production') == 'development') { - // @codeCoverageIgnoreStart - $host = parse_url(url('/'), PHP_URL_HOST); - - return "http://$host:8080/$relativeUri"; - // @codeCoverageIgnoreEnd - } else { - $path = resolve(\App\Services\Webpack::class)->$relativeUri; - $cdn = option('cdn_address'); - - return $cdn ? "$cdn/app/$path" : url("/app/$path"); - } + return resolve(\App\Services\Webpack::class)->url($path); } } diff --git a/config/app.php b/config/app.php index c9f619fd..432e8353 100644 --- a/config/app.php +++ b/config/app.php @@ -64,6 +64,19 @@ return [ 'url' => env('APP_URL', 'http://localhost'), + /* + |-------------------------------------------------------------------------- + | Assets + |-------------------------------------------------------------------------- + | + | This is related to front-end assets. The asset URL is only available for + | development, not for production. + */ + 'asset' => [ + 'env' => env('ASSET_ENV', 'production'), + 'url' => env('ASSET_URL', 'http://localhost'), + ], + /* |-------------------------------------------------------------------------- | Application Timezone diff --git a/tests/ServicesTest/WebpackTest.php b/tests/ServicesTest/WebpackTest.php index f2cf6bb3..9e0a53af 100644 --- a/tests/ServicesTest/WebpackTest.php +++ b/tests/ServicesTest/WebpackTest.php @@ -2,6 +2,7 @@ namespace Tests; +use App\Services\Webpack; use Illuminate\Filesystem\Filesystem; class WebpackTest extends TestCase @@ -19,7 +20,42 @@ class WebpackTest extends TestCase ->once() ->andReturn(json_encode(['a' => 'b'])); }); - $this->assertEquals('b', resolve(\App\Services\Webpack::class)->{'a'}); - $this->assertEquals('', resolve(\App\Services\Webpack::class)->{'nope'}); + + $this->app->forgetInstance(Webpack::class); + $webpack = $this->app->make(Webpack::class); + $this->assertEquals('b', $webpack->{'a'}); + $this->assertEquals('', $webpack->{'nope'}); + } + + public function testUrl() + { + $this->mock(Filesystem::class, function ($mock) { + $mock->shouldReceive('exists') + ->with(public_path('app/manifest.json')) + ->twice() + ->andReturn(true); + + $mock->shouldReceive('get') + ->with(public_path('app/manifest.json')) + ->twice() + ->andReturn(json_encode(['a' => 'b'])); + }); + + $this->app->forgetInstance(Webpack::class); + $webpack = $this->app->make(Webpack::class); + $this->assertEquals('http://localhost/app/b', $webpack->url('a')); + + $this->mock(\App\Services\Option::class, function ($mock) { + $mock->shouldReceive('get') + ->with('cdn_address') + ->once() + ->andReturn('http://cdn.test'); + }); + $this->app->forgetInstance(Webpack::class); + $webpack = $this->app->make(Webpack::class); + $this->assertEquals('http://cdn.test/app/b', $webpack->url('a')); + + config(['app.asset.env' => 'development']); + $this->assertEquals('http://localhost:8080/a', $webpack->url('a')); } }