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

[4.x] Vite #228

Merged
merged 1 commit into from Jul 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 9 additions & 10 deletions README.md
Expand Up @@ -21,6 +21,7 @@ Only the latest major version of Laravel UI receives bug fixes. The table below
| [1.x](https://github.com/laravel/ui/tree/1.x) | 5.8, 6.x |
| [2.x](https://github.com/laravel/ui/tree/2.x) | 7.x |
| [3.x](https://github.com/laravel/ui/tree/3.x) | 8.x |
| [4.x](https://github.com/laravel/ui/tree/4.x) | 9.x |

### Installation

Expand All @@ -46,11 +47,11 @@ php artisan ui react --auth

#### CSS

[Laravel Mix](https://laravel.com/docs/mix) provides a clean, expressive API over compiling SASS or Less, which are extensions of plain CSS that add variables, mixins, and other powerful features that make working with CSS much more enjoyable. In this document, we will briefly discuss CSS compilation in general; however, you should consult the full [Laravel Mix documentation](https://laravel.com/docs/mix) for more information on compiling SASS or Less.
Laravel officially supports [Vite](https://laravel.com/docs/vite), a modern frontend build tool that provides an extremely fast development environment and bundles your code for production. Vite supports a variety of CSS preprocessor languages, including SASS and Less, which are extensions of plain CSS that add variables, mixins, and other powerful features that make working with CSS much more enjoyable. In this document, we will briefly discuss CSS compilation in general; however, you should consult the full [Vite documentation](https://laravel.com/docs/vite#working-with-stylesheets) for more information on compiling SASS or Less.

#### JavaScript

Laravel does not require you to use a specific JavaScript framework or library to build your applications. In fact, you don't have to use JavaScript at all. However, Laravel does include some basic scaffolding to make it easier to get started writing modern JavaScript using the [Vue](https://vuejs.org) library. Vue provides an expressive API for building robust JavaScript applications using components. As with CSS, we may use Laravel Mix to easily compile JavaScript components into a single, browser-ready JavaScript file.
Laravel does not require you to use a specific JavaScript framework or library to build your applications. In fact, you don't have to use JavaScript at all. However, Laravel does include some basic scaffolding to make it easier to get started writing modern JavaScript using the [Vue](https://vuejs.org) library. Vue provides an expressive API for building robust JavaScript applications using components. As with CSS, we may use Vite to easily compile JavaScript components into a single, browser-ready JavaScript file.

### Writing CSS

Expand All @@ -62,13 +63,13 @@ Before compiling your CSS, install your project's frontend dependencies using th
npm install
```

Once the dependencies have been installed using `npm install`, you can compile your SASS files to plain CSS using [Laravel Mix](https://laravel.com/docs/mix#working-with-stylesheets). The `npm run dev` command will process the instructions in your `webpack.mix.js` file. Typically, your compiled CSS will be placed in the `public/css` directory:
Once the dependencies have been installed using `npm install`, you can compile your SASS files to plain CSS using [Vite](https://laravel.com/docs/vite#working-with-stylesheets). The `npm run dev` command will process the instructions in your `vite.config.js` file. Typically, your compiled CSS will be placed in the `public/build/assets` directory:

```bash
npm run dev
```

The `webpack.mix.js` file included with Laravel's frontend scaffolding will compile the `resources/sass/app.scss` SASS file. This `app.scss` file imports a file of SASS variables and loads Bootstrap, which provides a good starting point for most applications. Feel free to customize the `app.scss` file however you wish or even use an entirely different pre-processor by [configuring Laravel Mix](https://laravel.com/docs/mix).
The `vite.config.js` file included with Laravel's frontend scaffolding will compile the `resources/sass/app.scss` SASS file. This `app.scss` file imports a file of SASS variables and loads Bootstrap, which provides a good starting point for most applications. Feel free to customize the `app.scss` file however you wish or even use an entirely different pre-processor by [configuring Vite](https://laravel.com/docs/vite#working-with-stylesheets).

### Writing JavaScript

Expand All @@ -80,13 +81,13 @@ npm install

> By default, the Laravel `package.json` file includes a few packages such as `lodash` and `axios` to help you get started building your JavaScript application. Feel free to add or remove from the `package.json` file as needed for your own application.

Once the packages are installed, you can use the `npm run dev` command to [compile your assets](https://laravel.com/docs/mix). Webpack is a module bundler for modern JavaScript applications. When you run the `npm run dev` command, Webpack will execute the instructions in your `webpack.mix.js` file:
Once the packages are installed, you can use the `npm run dev` command to [compile your assets](https://laravel.com/docs/vite). Vite is a module bundler for modern JavaScript applications. When you run the `npm run dev` command, Vite will execute the instructions in your `vite.config.js` file:

```bash
npm run dev
```

By default, the Laravel `webpack.mix.js` file compiles your SASS and the `resources/js/app.js` file. Within the `app.js` file you may register your Vue components or, if you prefer a different framework, configure your own JavaScript application. Your compiled JavaScript will typically be placed in the `public/js` directory.
By default, the Laravel `vite.config.js` file compiles your SASS and the `resources/js/app.js` file. Within the `app.js` file you may register your Vue components or, if you prefer a different framework, configure your own JavaScript application. Your compiled JavaScript will typically be placed in the `public/build/assets` directory.

> The `app.js` file will load the `resources/js/bootstrap.js` file which bootstraps and configures Vue, Axios, jQuery, and all other JavaScript dependencies. If you have additional JavaScript dependencies to configure, you may do so in this file.

Expand All @@ -95,10 +96,8 @@ By default, the Laravel `webpack.mix.js` file compiles your SASS and the `resour
When using the `laravel/ui` package to scaffold your frontend, an `ExampleComponent.vue` Vue component will be placed in the `resources/js/components` directory. The `ExampleComponent.vue` file is an example of a [single file Vue component](https://vuejs.org/guide/single-file-components) which defines its JavaScript and HTML template in the same file. Single file components provide a very convenient approach to building JavaScript driven applications. The example component is registered in your `app.js` file:

```javascript
Vue.component(
'example-component',
require('./components/ExampleComponent.vue').default
);
import ExampleComponent from './components/ExampleComponent.vue';
Vue.component('example-component', ExampleComponent);
```

To use the component in your application, you may drop it into one of your HTML templates. For example, after running the `php artisan ui vue --auth` Artisan command to scaffold your application's authentication and registration screens, you could drop the component into the `home.blade.php` Blade template:
Expand Down
7 changes: 2 additions & 5 deletions src/Auth/bootstrap-stubs/layouts/app.stub
Expand Up @@ -9,15 +9,12 @@

<title>{{ config('app.name', 'Laravel') }}</title>

<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>

<!-- Fonts -->
<link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<!-- Scripts -->
@vite(['resources/sass/app.scss', 'resources/js/app.js'])
</head>
<body>
<div id="app">
Expand Down
9 changes: 4 additions & 5 deletions src/Presets/Bootstrap.php
Expand Up @@ -14,7 +14,7 @@ class Bootstrap extends Preset
public static function install()
{
static::updatePackages();
static::updateWebpackConfiguration();
static::updateViteConfiguration();
static::updateSass();
static::updateBootstrapping();
static::removeNodeModules();
Expand All @@ -32,18 +32,17 @@ protected static function updatePackageArray(array $packages)
'bootstrap' => '^5.1.3',
'@popperjs/core' => '^2.10.2',
'sass' => '^1.32.11',
'sass-loader' => '^11.0.1',
] + $packages;
}

/**
* Update the Webpack configuration.
* Update the Vite configuration.
*
* @return void
*/
protected static function updateWebpackConfiguration()
protected static function updateViteConfiguration()
{
copy(__DIR__.'/bootstrap-stubs/webpack.mix.js', base_path('webpack.mix.js'));
copy(__DIR__.'/bootstrap-stubs/vite.config.js', base_path('vite.config.js'));
}

/**
Expand Down
48 changes: 41 additions & 7 deletions src/Presets/React.php
Expand Up @@ -16,9 +16,10 @@ public static function install()
{
static::ensureComponentDirectoryExists();
static::updatePackages();
static::updateWebpackConfiguration();
static::updateViteConfiguration();
static::updateBootstrapping();
static::updateComponent();
static::addViteReactRefreshDirective();
static::removeNodeModules();
}

Expand All @@ -32,19 +33,20 @@ protected static function updatePackageArray(array $packages)
{
return [
'@babel/preset-react' => '^7.13.13',
'@vitejs/plugin-react' => '^1.3.2',
'react' => '^17.0.2',
'react-dom' => '^17.0.2',
] + Arr::except($packages, ['vue', 'vue-template-compiler']);
] + Arr::except($packages, ['@vitejs/plugin-vue', 'vue']);
}

/**
* Update the Webpack configuration.
* Update the Vite configuration.
*
* @return void
*/
protected static function updateWebpackConfiguration()
protected static function updateViteConfiguration()
{
copy(__DIR__.'/react-stubs/webpack.mix.js', base_path('webpack.mix.js'));
copy(__DIR__.'/react-stubs/vite.config.js', base_path('vite.config.js'));
}

/**
Expand All @@ -59,8 +61,8 @@ protected static function updateComponent()
);

copy(
__DIR__.'/react-stubs/Example.js',
resource_path('js/components/Example.js')
__DIR__.'/react-stubs/Example.jsx',
resource_path('js/components/Example.jsx')
);
}

Expand All @@ -73,4 +75,36 @@ protected static function updateBootstrapping()
{
copy(__DIR__.'/react-stubs/app.js', resource_path('js/app.js'));
}

/**
* Add Vite's React Refresh Runtime
*
* @return void
*/
protected static function addViteReactRefreshDirective()
{
$view = static::getViewPath('layouts/app.blade.php');

if (! file_exists($view)) {
return;
}

file_put_contents(
$view,
str_replace('@vite(', '@viteReactRefresh'.PHP_EOL.' @vite(', file_get_contents($view))
);
}

/**
* Get full view path relative to the application's configured view path.
*
* @param string $path
* @return string
*/
protected static function getViewPath($path)
{
return implode(DIRECTORY_SEPARATOR, [
config('view.paths')[0] ?? resource_path('views'), $path,
]);
}
}
14 changes: 7 additions & 7 deletions src/Presets/Vue.php
Expand Up @@ -16,7 +16,7 @@ public static function install()
{
static::ensureComponentDirectoryExists();
static::updatePackages();
static::updateWebpackConfiguration();
static::updateViteConfiguration();
static::updateBootstrapping();
static::updateComponent();
static::removeNodeModules();
Expand All @@ -31,26 +31,26 @@ public static function install()
protected static function updatePackageArray(array $packages)
{
return [
'@vitejs/plugin-vue' => '^2.3.3',
'resolve-url-loader' => '^3.1.2',
'sass' => '^1.32.11',
'sass-loader' => '^11.0.1',
'vue' => '^2.6.12',
'vue-template-compiler' => '^2.6.12',
'vue' => '^3.2.37',
] + Arr::except($packages, [
'@babel/preset-react',
'@vitejs/plugin-react',
'react',
'react-dom',
]);
}

/**
* Update the Webpack configuration.
* Update the Vite configuration.
*
* @return void
*/
protected static function updateWebpackConfiguration()
protected static function updateViteConfiguration()
{
copy(__DIR__.'/vue-stubs/webpack.mix.js', base_path('webpack.mix.js'));
copy(__DIR__.'/vue-stubs/vite.config.js', base_path('vite.config.js'));
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Presets/bootstrap-stubs/app.scss
Expand Up @@ -5,4 +5,4 @@
@import 'variables';

// Bootstrap
@import '~bootstrap/scss/bootstrap';
@import 'bootstrap/scss/bootstrap';
22 changes: 13 additions & 9 deletions src/Presets/bootstrap-stubs/bootstrap.js
@@ -1,16 +1,16 @@
window._ = require('lodash');
import _ from 'lodash';
window._ = _;

try {
require('bootstrap');
} catch (e) {}
import 'bootstrap';

/**
* We'll load the axios HTTP library which allows us to easily issue requests
* to our Laravel back-end. This library automatically handles sending the
* CSRF token as a header based on the value of the "XSRF" token cookie.
*/

window.axios = require('axios');
import axios from 'axios';
window.axios = axios;

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

Expand All @@ -22,11 +22,15 @@ window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

// import Echo from 'laravel-echo';

// window.Pusher = require('pusher-js');
// import Pusher from 'pusher-js';
// window.Pusher = Pusher;

// window.Echo = new Echo({
// broadcaster: 'pusher',
// key: process.env.MIX_PUSHER_APP_KEY,
// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
// forceTLS: true
// key: import.meta.env.VITE_PUSHER_APP_KEY,
// wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_CLUSTER}.pusher.com`,
// wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
// wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
// forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
// enabledTransports: ['ws', 'wss'],
// });
11 changes: 11 additions & 0 deletions src/Presets/bootstrap-stubs/vite.config.js
@@ -0,0 +1,11 @@
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
plugins: [
laravel([
'resources/sass/app.scss',
'resources/js/app.js',
]),
],
});
16 changes: 0 additions & 16 deletions src/Presets/bootstrap-stubs/webpack.mix.js

This file was deleted.

File renamed without changes.
4 changes: 2 additions & 2 deletions src/Presets/react-stubs/app.js
Expand Up @@ -4,12 +4,12 @@
* building robust, powerful web applications using React + Laravel.
*/

require('./bootstrap');
import './bootstrap';

/**
* Next, we will create a fresh React component instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/

require('./components/Example');
import './components/Example';
13 changes: 13 additions & 0 deletions src/Presets/react-stubs/vite.config.js
@@ -0,0 +1,13 @@
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';

export default defineConfig({
plugins: [
laravel([
'resources/sass/app.scss',
'resources/js/app.js',
]),
react(),
],
});
16 changes: 0 additions & 16 deletions src/Presets/react-stubs/webpack.mix.js

This file was deleted.