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

2

6

I have a simple Vue.js project built after running yarn build. The dist folder contains files like below;

enter image description here

I want to bundle all the files (HTML, js, CSS) into a single js file that can be embedded into a ghost blog post.

Here is an example of how this was done for a ghost blog post.

https://blog.openbloc.com/including-a-js-app-in-a-ghost-post/

My question is how do I bundle my Vue.js project files into a single file that can be deployed in a ghost blog post?

Is webpack the right tool to use? I am open to other alternatives.

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

Alicaalicante answered 25/2, 2022 at 7:33 Comment(1)
I solved it in another question: https://mcmap.net/q/832986/-how-to-include-vue-app-inside-another-vue-appMalebranche
I
14

Creating a single JS file output

To configure Vue CLI to output a single .js file:

  1. Disable CSS extraction with css.extract=false.
  2. Disable Webpack's chunk-splitting with configureWebpack.optimization.splitChunks=false.
// vue.config.js
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  ⋮
  css: {
    extract: false, 1️⃣
  },
  configureWebpack: {
    optimization: {
      splitChunks: false, 2️⃣
    },
  },
})

The build then produces a dist directory containing these files:

dist/js/app.bd71ae48.js      # all app code, including template, scripts, and styles
dist/js/app.bd71ae48.js.map  # source map for development (optional)
dist/favicon.ico             # favicon shown in browser   (optional)
dist/index.html              # initial index              (optional)

Usage in Ghost

  1. In your blog page, insert a custom HTML block.
  1. In the HTML block, add a div with an ID that matches the mounting point in src/main.js from your app's original source (the default ID is "app").

    <div id="app">Vue app loading...</div>
    
  2. Add a <script> that pulls in the app.js file previously built. For example, if you've hosted the script on GitHub, you could use a CDN link like this:

    <script src="https://cdn.jsdelivr.net/gh/tony19-sandbox/vue-cli-single-js-file@master/dist/js/app.bd71ae48.js"></script>
    
  3. I noticed the app's Vue icon and heading are incorrectly aligned (likely due to inherited Ghost styles), so compensate by adding a <style> to the HTML block that re-centers them.

    <style>
    /* compensate for Ghost styles overriding the app's alignment */
    #app {
      display: flex;
      flex-direction: column;
      align-items: center;
    }
    </style>
    

The result looks like this:

GitHub

Ghost page

Imaginative answered 28/2, 2022 at 22:8 Comment(3)
Really sweet. I used a more complicated solution, described here (in short, using build --target-lib --inline-vue --inline-css). Thanks for this.Helgeson
@tony19, I asked a similar question but it is for React.js #72441423Alicaalicante
@tony19, I asked a similar question but this time, it is about bundling the vue.js files into a single HTML file so that it can be posted in Blogger blogspot #77509627Alicaalicante
C
1

The vue cli have a command for this: https://cli.vuejs.org/guide/build-targets.html#library

You need to pass this command --target lib to the vue-cli-service build. This means that you only want one final file.

Also, you can pass another attributes, like:

  • --inline-vue, that will include the Vue in your bundle, what is recommended, based on your use case;
  • --name, the name of you bundle file;
  • and in the end of the command, the entry point for you application, that is the src/Vue.js by default, but can be the main.js, for example. You have to test based on how you built your app;

So, you can try one of these combinations:

vue-cli-service build --target lib
vue-cli-service build --target lib --inline-vue
vue-cli-service build --target lib --inline-vue --name myApp
vue-cli-service build --target lib --inline-vue --name myApp src/main.js
Corky answered 28/2, 2022 at 19:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.