Vue, Vite customize dist directory and filenames

How to config custom js and css file names in Vuejs and Vite.

Vue app

Install nodejs, npm

# Using Ubuntu
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

# Using Debian, as root
curl -fsSL https://deb.nodesource.com/setup_18.x | bash -
apt-get install -y nodejs

# Update [email protected]
npm install -g npm@latest

Create vue project

npm init vue@latest

Run project

cd <your-project-name>
npm install
# Dev
npm run dev
# Prod
npm run build

Configuration

Custom dist assets filenames

File: laravel-app/vue/vite.config.js

// vite.config.js

import { fileURLToPath, URL } from 'url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import pkg from './package.json';
const { resolve } = require('path')

// https://vitejs.dev/config/
export default defineConfig({
	plugins: [vue()],
	resolve: {
		alias: {
		  '@': fileURLToPath(new URL('./src', import.meta.url))
		}
	},
	build: {
		// entry: 'src/main.js',
		// outDir: resolve(__dirname, 'dist'),
		rollupOptions: {
			output: {
				// Default
				// dir: 'dist',
				// With laravel: laravel-app/public/js
				dir: '../public/js',
				entryFileNames: 'app-[name].js',
				assetFileNames: 'app-[name].css',
				chunkFileNames: "chunk-[name].js",
				manualChunks: undefined,
			}
		}
	}
})

Laravel view welcome.blade.php

Copy html from public/js/index.html file (vue dist dir)

<!DOCTYPE html>
<html lang="pl">
	<head>
		<meta charset="UTF-8" />
		<link rel="icon" href="/favicon.ico" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Vue Vite App</title>
		
		<script type="module" crossorigin src="/js/app-index.js"></script>
		<link rel="stylesheet" href="/js/app-index.css">
	</head>
	<body>
		<div id="app"></div>
	</body>
</html>

Laravel view welcome.blade.php

Include html from public/js/index.html file (vue dist dir)

@php 
	echo file_get_contents(app_path() . '/public/js/index.html'); 
@endphp

Laravel routes

<?php

use Illuminate\Support\Facades\Route;

// Docs
// require_once('_restdoc/routes.php');

// Panel
// require('panel.php');

// Vue login page
Route::get('/login', function () {
	return view('welcome');
})->name('login');

// Vue fallback
Route::fallback(function () {
	return view('welcome');
	// throw new \Exception('Web page error.', 404);
});

Variables

Define .env file vars

VITE_API_KEY=hash12345

Get .env vars

// Title.vue component
<script>
export default {
	name: "Title",
	data() {
		return {
			title: 'Welcome',
			base_url: import.meta.env.BASE_URL,
			api_key: import.meta.env.VITE_API_KEY, // Get .env variable
		}
	},
	mounted() {
		console.log(`The api_key .env variable is ${this.api_key} type string.`)
	}
};
</script>

<template>
	<h2>{{ title }}</h2>
</template>

Add javascript

Create js file in public directorry

// vue-project/public/js/sample.js it will be placed in dist/js directory after build

let some_data = 'App Name 123'

window.onload = function() {
  console.log(`Variable ${some_data}`)
}

Import js from component

Load js script with setup or with mounted() function in vue

<script setup>
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from '@/components/HelloWorld.vue'

// Load external script
let rs = document.createElement('script')
rs.setAttribute('src', 'https://www.google.com/recaptcha/api.js')
document.head.appendChild(rs)

// Load local script from vue-project/public/js/sample.js after build will be in dist/js/sample.js
let o = document.createElement('script')
o.setAttribute('src', '/js/sample.js')
document.head.appendChild(o)
</script>

<template>
	<HelloWorld msg="You did it!" />
	
  	<!-- add more content -->
</template>

<style>
@import '@/assets/base.css';

/* add more style */
</style>

Load script async

function loadScript(src) {
    return new Promise(function (resolve, reject) {
        var s;
        s = document.createElement('script');
        s.src = src;
        s.onload = resolve;
        s.onerror = reject;
        document.head.appendChild(s);
    });
}

loadScript(cdnSource)
	.then(callBack)

loadScript(cdnSource)
	.catch(loadScript.bind(null, localSource))
	.then(successCallback, failureCallback);

Deploy

Nginx virtualhost

# Nginx
sudo apt install nginx mysql-server php8.1 php8.1-fpm

# Local domain
127.0.0.10 vue.xx www.vue.xx

# Virtualhost laravel
server {
	listen 80;
	listen [::]:80;
	server_name vue.xx www.vue.xx;
	root /www/vue.xx/public;
	index index.html index.php;
	location / {
		# try_files $uri $uri/ =404;
		try_files $uri $uri/ /index.php$is_args$args;
	}
	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
		fastcgi_pass unix:/run/php/php8.0-fpm.sock;
		# fastcgi_pass 127.0.0.1:9000;
	}
	location ~* \.(js|css|png|jpg|jpeg|gif|webp|svg|ico)$ {
		expires -1;
		access_log off;
	}
	disable_symlinks off;
	client_max_body_size 100M;
	charset utf-8;
	source_charset utf-8;
}

Docs

GitHub

View Github