Search code examples
javascriptvue.jswebpackghost-blog

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


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


Solution

  • 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