To generate a single HTML file with embedded JS, CSS, images you can use the HTML Bundler Plugin for Webpack. This plugin can inline assets into HTML.
For example, there is a simple Vue app including SCSS, TS and image files:
index.html
<!doctype html>
<html lang="en">
<head>
<!-- source icon file -->
<link href="./favicon.ico" rel="icon" />
<!-- source style file -->
<link href="./main.scss" rel="stylesheet" />
<title>Vue</title>
</head>
<body>
<div id="app">
<h1>{{ title }}</h1>
<!-- source image file -->
<img src="./picture.png" />
<my-button></my-button>
</div>
<!-- source TS file -->
<script src="./index.ts"></script>
</body>
</html>
index.ts
import { createApp, ref } from 'vue';
import MyButton from './MyButton.vue';
import './styles.scss';
createApp({
setup() {
return {
title: ref('Hello Vue!'),
};
},
})
.component('my-button', MyButton)
.mount('#app');
MyButton.vue
<template>
<button>{{ text }}</button>
</template>
<script setup>
import { ref } from 'vue';
const text = ref('Button');
</script>
<!-- source style file -->
<style src="./MyButton.scss" lang="scss"></style>
simple Webpack config:
const path = require('path');
const { VueLoaderPlugin } = require('vue-loader');
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
module.exports = {
mode: 'production',
output: {
path: path.join(__dirname, 'dist/'),
},
resolve: {
alias: {
vue: 'vue/dist/vue.esm-bundler',
},
extensions: ['.ts', '...'],
},
plugins: [
new VueLoaderPlugin(),
new HtmlBundlerPlugin({
entry: {
// define HTML templates here
index: './src/views/index.html', // => dist/index.html
},
js: {
// output JS filename, used only if the `inline` option is false
filename: '[name].[contenthash:8].js',
inline: true, // inline JS into HTML
},
css: {
// output CSS filename, used only if the `inline` option is false
filename: '[name].[contenthash:8].css',
inline: true, // inline CSS into HTML
},
minify: 'auto', // minify html in production mode only
}),
],
module: {
rules: [
{
test: /\.vue$/i,
use: ['vue-loader'],
},
{
test: /\.(css|scss)$/,
use: ['css-loader', 'sass-loader'],
},
{
test: /\.(ico|png|jp?g|svg)$/,
type: 'asset/inline', // inline all images into HTML/CSS
},
],
},
};
The generated HTML file dist/index.html
will be looks like:
<!doctype html><html lang="en"><head><meta charset="UTF-8"/>
<link href="data:image/vnd.microsoft.icon;base64,iVBORw0KGg..." rel="icon"/>
<style>...embedded CSS...</style><title>Vue</title></head>
<body><div id="app"><h1>{{ title }}</h1>
<img src="data:image/png;base64,iVBORw0KGgoA..."/><my-button></my-button></div>
<script>...embedded JS...</script></body></html>
The compiled CSS, JS and images will be inlined in generated HTML.
View the working example in browser on StackBlitz
View complete source code on GitHub