I have a vue project created with vue-cli. The normal output when running yarn build
is a dist folder with an index.html
and a js and css sub-directory with the corresponding .js and .css files.
I want the build output to be a single html file that contains the js and css.
I added a vue.config.js
file in the root of my project and set it to output a single js file and that is working ok. But I want to only have a single html file with the js and any css already on the html file.
module.exports = { css: { extract: false, }, configureWebpack: { optimization: { splitChunks: false } } }
Basically I want my html file to be something like this:
<html lang=en> <head> ... meta tags <title>my title</title> </head> <body> <div id=app></div> <script> // contents of the output js file here </script> </body> </html>
Is this possible?
Using Vue 3.9.3
Advertisement
Answer
Someone answered with a suggestion to look into html-webpack-inline-source-plugin but removed their answer. But that was exactly what I needed to get this done.
The plugin is not Vue or Vue-CLI specific but it works if you do the following:
1) Add a vue.config.js
file in the root of the app.
2) The linked plugin above is actually an extension of another package. You need both.
npm install --save-dev html-webpack-plugin npm install --save-dev html-webpack-inline-source-plugin
3)
// vue.config.js const HtmlWebpackPlugin = require('html-webpack-plugin') const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin'); module.exports = { css: { extract: false, }, configureWebpack: { optimization: { splitChunks: false // makes there only be 1 js file - leftover from earlier attempts but doesn't hurt }, plugins: [ new HtmlWebpackPlugin({ filename: 'output.html', // the output file name that will be created template: 'src/output-template.html', // this is important - a template file to use for insertion inlineSource: '.(js|css)$' // embed all javascript and css inline }), new HtmlWebpackInlineSourcePlugin() ] } }
4) Add a template. This is necessary for working in the Vue context because without this the output html file by default won’t have the necessary <div id="app"></div>
and Vue won’t mount to anything. I basically took the normal output html file and modified it a little.
<!-- output-template.html --> <!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <meta http-equiv=X-UA-Compatible content="IE=edge"> <meta name=viewport content="width=device-width,initial-scale=1"> <title>example title</title> </head> <body><noscript><strong>We're sorry but my example doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript> <div id=app> </div> <!-- plugin will insert js here by default --> </body> </html>
Then build like normal and the output.html
file will be in the /dist
folder