Skip to content

Commit

Permalink
Merge pull request #13 from gwleuverink/feature/css-loader
Browse files Browse the repository at this point in the history
Feature/css loader
  • Loading branch information
gwleuverink authored Feb 20, 2024
2 parents 0e62bed + 9deb0ca commit 4171887
Show file tree
Hide file tree
Showing 30 changed files with 712 additions and 101 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/browser-tests.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: browser-tests

on:
pull_request:
branches: [development, main]
workflow_run:
workflows: [tests]
types: [completed]
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@
"cd ./workbench && npm ci",
"ln -sf $PWD/workbench/jsconfig.json ./vendor/orchestra/testbench-core/laravel",
"ln -sf $PWD/workbench/node_modules/ ./vendor/orchestra/testbench-core/laravel",
"ln -sf $PWD/workbench/resources/js/ ./vendor/orchestra/testbench-core/laravel/resources"
"ln -sf $PWD/workbench/resources/js/ ./vendor/orchestra/testbench-core/laravel/resources",
"ln -sf $PWD/workbench/resources/css/ ./vendor/orchestra/testbench-core/laravel/resources"
],

"serve": [
Expand Down
4 changes: 2 additions & 2 deletions config/bundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
| and disable this on your local development environment.
|
*/
'caching_enabled' => env('BUNDLE_CACHING_ENABLED', app()->isProduction()),
'caching' => env('BUNDLE_CACHING', true),

/*
|--------------------------------------------------------------------------
Expand Down Expand Up @@ -47,7 +47,7 @@
| won't impact performance when your imports are build for prod.
|
*/
'sourcemaps_enabled' => env('BUNDLE_SOURCEMAPS_ENABLED', false),
'sourcemaps' => env('BUNDLE_SOURCEMAPS', false),

/*
|--------------------------------------------------------------------------
Expand Down
10 changes: 2 additions & 8 deletions docs/advanced-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ All code is minified by default. This can make issues harder to debug at times.

## Sourcemaps

Sourcemaps are disabled by default. You may enable this by setting `BUNDLE_SOURCEMAPS_ENABLED` to true in your env file or by publishing and updating the bundle config.
Sourcemaps are disabled by default. You may enable this by setting `BUNDLE_SOURCEMAPS` to true in your env file or by publishing and updating the bundle config.

Sourcemaps will be generated in a separate file so this won't affect performance for the end user.

{: .note }

> If your project stored previously bundled files you need to run the [bundle:clear](https://laravel-bundle.dev/advanced-usage.html#artisan-bundleclear) command
> If your project stored previously bundled files you need to run the [bundle:clear](https://laravel-bundle.dev/advanced-usage.html#artisan-bundleclear) command after enabling/disabling this feature.
## Cache-Control headers

Expand Down Expand Up @@ -148,9 +148,3 @@ BundleManager::fake();
```

When you'd like to use Dusk for browser testing you need to run Bundle in order for your tests not to blow up. Simply don't fake the BundleManager in your DuskTestCase.

## CSS Loader

Bun doesn't ship with a css loader. They have it on [the roadmap](https://github.com/oven-sh/bun/issues/159){:target="\_blank"} but no release date is known at this time. We plan to support css loading out-of-the-box as soon as Bun does!

We'd like to experiment with Bun plugin support soon. If that is released before Bun's builtin css loader does, it might be possible to write your own plugin to achieve this.
2 changes: 1 addition & 1 deletion docs/caveats.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
nav_order: 7
nav_order: 8
title: Caveats
image: "/assets/social-square.png"
---
Expand Down
74 changes: 74 additions & 0 deletions docs/css-loading.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
nav_order: 5
title: CSS loading
image: "/assets/social-square.png"
---

## CSS Loading

**Beta**

Bun doesn't ship with a CSS loader. They have it on [the roadmap](https://github.com/oven-sh/bun/issues/159){:target="\_blank"} but no release date is known at this time.

We provide a custom CSS loader plugin that just works™. Built on top of [Lightning CSS](https://lightningcss.dev/). Just use the `x-import` directive to load a css file directly. Bundle transpiles them and injects it on your page with zero effort.

```html
<x-import module="tippy.js" as="tippy" />
<x-import module="tippy.js/dist/tippy.css" />
```

Because we use Bun as a runtime when processing your files there is no need to install Lightning CSS as a dependency. When Bun encounters a import that is not installed it will fall back to it's on internal [module resolution algorithm](https://bun.sh/docs/runtime/autoimport) & install the dependency on the fly.

That being said; We do recommend installing Lightning CSS in your project.

```bash
npm install lightningcss --save-dev
```

### Sass

[Sass](https://sass-lang.com/) is supported out of the box. Just like with Lightning CSS you don't have to install Sass as a dependency, but it is recommended.

```bash
npm install lightningcss --save-dev
```

Note that compiled Sass is processed with LightningCSS afterwards, so if you plan on only processing scss files it is recommended to install both Lightning CSS & Sass.

### Local CSS loading

This works similar to [local modules](https://laravel-bundle.dev/local-modules.html). Simply add a new path alias to your `jsconfig.json` file.

```json
{
"compilerOptions": {
"paths": {
"~/css": ["./resources/css/*"]
}
}
}
```

Now you can load css from your resources directory.

```html
<x-import module="css/foo-bar.css" />
```

### Browser targeting

Bundle automatically compiles many modern CSS syntax features to more compatible output that is supported in your target browsers. This includes some features that are not supported by browsers yet, like nested selectors & media queries, without using a preprocessor like Sass. [Check here](https://lightningcss.dev/transpilation.html#syntax-lowering) for the list of the many cool new syntaxes Lightning CSS supports.

You can define what browsers to target using your `package.json` file:

```json
{
"browserslist": ["last 2 versions", ">= 1%", "IE 11"]
}
```

<br/>

{: .note }

> Bundle currently only supports browserslist using your `package.json` file. A dedicated `.browserslistrc` is not suppported at this time.
2 changes: 1 addition & 1 deletion docs/integrations/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
nav_order: 6
nav_order: 7
has_children: true
title: Integration examples
image: "/assets/social-square.png"
Expand Down
2 changes: 1 addition & 1 deletion docs/production-builds.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
nav_order: 5
nav_order: 6
title: Production builds
image: "/assets/social-square.png"
---
Expand Down
18 changes: 10 additions & 8 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
nav_order: 8
nav_order: 9
title: Roadmap
image: "/assets/social-square.png"
---
Expand All @@ -8,7 +8,15 @@ image: "/assets/social-square.png"

Bundle is under active development. If you feel there are features missing or you've got a great idea that's not on on the roadmap please [open a discussion](https://github.com/gwleuverink/bundle/discussions/categories/ideas){:target="\_blank"} on GitHub.

## CSS loader
## ✅ Injecting Bundle's core on every page

**_Added in [v0.1.3](https://github.com/gwleuverink/bundle/releases/tag/v0.1.3)_**

This will reduce every import's size slightly. But more importantly; it will greatly decrease the chance of unexpected behaviour caused by race conditions, since the Bundle's core is available on pageload.

## ✅ CSS loader

**_Added in [v0.1.4](https://github.com/gwleuverink/bundle/releases/tag/v0.1.4)_**

Bun doesn't ship with a CSS loader. They have it on [the roadmap](https://github.com/oven-sh/bun/issues/159){:target="\_blank"} but no release date is known at this time. We plan to support CSS loading out-of-the-box as soon as Bun does!

Expand Down Expand Up @@ -98,12 +106,6 @@ It would be incredible if this object could be forwarded to Alpine directly like
</div>
```

## ✅ Injecting Bundle's core on every page

**_Added in [v0.1.3](https://github.com/gwleuverink/bundle/releases/tag/v0.1.3)_**

This will reduce every import's size slightly. But more importantly; it will greatly decrease the chance of unexpected behaviour caused by race conditions, since the Bundle's core is available on pageload.

## Optionally assigning a import to the window scope

It could be convenient to provide an api to assign imports to a window variable by use of a prop. This idea is still settling in so might change.
Expand Down
7 changes: 7 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@
bootstrap="vendor/autoload.php"
colors="true"
>
<php>
<env name="BUNDLE_MINIFY" value="true" />
<env name="BUNDLE_CACHING" value="false" />
<env name="BUNDLE_SOURCEMAPS" value="false" />
</php>

<testsuites>
<testsuite name="Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>

<source>
<include>
<directory suffix=".php">./app</directory>
Expand Down
10 changes: 7 additions & 3 deletions src/BundleManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ public function __construct(BundlerContract $bundler)

public function bundle(string $script): SplFileInfo
{
$file = "{$this->hash($script)}.min.js";
$min = $this->config()->get('minify')
? '.min'
: '';

$file = "{$this->hash($script)}{$min}.js";

// Return cached file if available
if ($this->config()->get('caching_enabled') && $cached = $this->fromDisk($file)) {
if ($this->config()->get('caching') && $cached = $this->fromDisk($file)) {
return $cached;
}

Expand All @@ -44,7 +48,7 @@ public function bundle(string $script): SplFileInfo
// Attempt bundling & cleanup
try {
$processed = $this->bundler->build(
sourcemaps: $this->config()->get('sourcemaps_enabled'),
sourcemaps: $this->config()->get('sourcemaps'),
minify: $this->config()->get('minify'),
inputPath: $this->tempDisk()->path(''),
outputPath: $this->buildDisk()->path(''),
Expand Down
4 changes: 3 additions & 1 deletion src/Bundlers/Bun.php → src/Bundlers/Bun/Bun.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Leuverink\Bundle\Bundlers;
namespace Leuverink\Bundle\Bundlers\Bun;

use SplFileInfo;
use Illuminate\Support\Facades\Process;
Expand Down Expand Up @@ -33,6 +33,8 @@ public function build(
Process::run("{$bun} {$buildScript} {$this->args($options)}")
->throw(function ($res) use ($inputPath, $fileName): void {
$failed = file_get_contents($inputPath . $fileName);

// TODO: needs to be reworked
throw new BundlingFailedException($res, $failed);
});

Expand Down
69 changes: 69 additions & 0 deletions src/Bundlers/Bun/bin/bun.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// NOTE: we don't have to check if Bun is installed sinsce this script is invoked with the Bun runtime

import { parseArgs } from "util";
import { exit } from "./utils/dump";
import cssLoader from "./plugins/css-loader";

const options = parseArgs({
args: Bun.argv,
strict: true,
allowPositionals: true,

options: {
entrypoint: {
type: "string",
},

inputPath: {
type: "string",
},

outputPath: {
type: "string",
},

sourcemaps: {
type: "boolean",
},

minify: {
type: "boolean",
},
},
}).values;

const result = await Bun.build({
entrypoints: [options.entrypoint],
publicPath: options.outputPath,
outdir: options.outputPath,
root: options.inputPath,
minify: options.minify,

sourcemap: options.sourcemaps ? "external" : "none",

naming: {
entry: "[dir]/[name].[ext]",
chunk: "chunks/[name]-[hash].[ext]", // Not in use without --splitting
asset: "assets/[name]-[hash].[ext]", // Not in use without --splitting
},

target: "browser",
format: "esm",

plugins: [
cssLoader({
minify: Boolean(options.minify),
sourcemaps: Boolean(options.sourcemaps),
}),
],
});

if (!result.success) {
// for (const message of result.logs) {
// console.error(message);
// }
// process.exit(1);

// TODO: needs to be reworked
exit('build-failed', '', result.logs.map(log => log.message))
}
Loading

0 comments on commit 4171887

Please sign in to comment.