Bundle Vue project into a single html file that can be embedded into a Blogger blogspot post [duplicate]
Asked Answered
U

1

2

I want to bundle all the Vue.js project files (HTML, js, CSS) into a single HTML file so that it can be deployed in a blogger blogspot post.

A similar question was asked in the past for a ghost blog but it was about bundling the files into a single js file.

Bundle Vue project into single js file that can be embedded in Ghost blog post

I am using @vue/cli 5.0.1, yarn v1.22.21

Unselfish answered 18/11, 2023 at 23:58 Comment(1)
Does this answer your question? How to bundle html, js and css in one html file with webpack?Hexad
S
2

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

Snare answered 25/11, 2023 at 16:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.