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

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 npm@8.11.0
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