This gist describes how to bundle a built Vue.js project – the dist
folder – together with a local web server in a stand-alone executable (no Node.js installation needed on the client).
When we want to present a completed Vue project to a third party (a client, a collaborator, etc.), we cannot just send the dist
folder and explain how to open the index.html
file. This won’t work because Vue presupposes a web server to run (at least as long as we don't manipulate the publicPath
configuration). Setting up a whole web hosting environment, organizing a domain name, and securing it with a server lock, among other things, can be a bit much. On the other hand, explaining someone with no technical background how to install Node.js and run a local web server just to see our project is equally inconvenient. This can be a problem.
We create an executable package that contains a web server and our project. A simple double click on the executable will start the web server, open Google Chrome, and run our project.
This solution is not restricted to Vue projects alone. It can be adapted to all sorts of builds that require a webserver in order to run.
1. Install npm modules http-server and pkg in the root of your Vue project
npm i http-server pkg
Copy the content of pkg.js
as shown here to the file and save it (or clone this gist).
Add a key bin
to your package.json with our file name as value.
"bin" : "pkg.js",
This tells pkg the entry point of the executable. Also, the package.json should contain:
"pkg": {
"scripts": [
"pkg.js",
"package.json"
],
"assets": "dist/**/*",
"targets": [
"node18-macos-x64",
"node18-win-x64"
],
"outputPath": "executable"
}
- "scripts": the scripts you want to see included in the executable
- "assets": your build of the Vue.js app, including all subfolders and resources; most likely, this is the folder ./dist
- "targets": Node.js version, OS, and processors you want to build the pkg for
- "outputPath": The folder your executables will be built in
If your project contains routes, you might want to be able to address these routes directly by entering the route in the URL address field of the browser, like: http://localhost:8080/my-route/
. In an unmodified state of the .htaccess
file, Vue projects can only be navigated programmatically from the entry point, but routes will not be resolved from the browser’s address bar.
To fix this, you can create a custom .htaccess folder and place it in the dist folder on the level of your index.html:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
To see if your pkg.js
does, what it should, simply run
node pkg.js
This should start http-server, open Google Chrome and run your app.
If the test is fine, do:
pkg .
Your executable files (Mac/Win) will be build to the folder ./executable
according to the specs given in the package.json. (This is what the dot '.' argument after the pkg command means: use the configutation as defined in the package.json).
Done! Happy Coding.