Subscribe on changes!

Empty result with npm webpack on existing website (but working with unpkg)

avatar
Aug 8th 2021

Version

3.1.5

Steps to reproduce

I'm trying to add vue to an existing website using npm webpack. The target div is not changed and is left empty, so it seems that the mounting fails somewhere. No errors are shown in the dev console. If I instead use vue via unpkg then the result is the expected one.


  • package.json:
{
  "name": "foo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node -r esm index.js",
    "build": "webpack --config webpack.config.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "esm": "^3.2.25",
    "express": "^4.17.1",
    "vue": "^3.1.5",
    "webpack": "^5.49.0"
  },
  "devDependencies": {
    "webpack-cli": "^4.7.2"
  }
}
  • webpack.config.js:
module.exports = {
  entry: {
    component: './component.js',
  },
  optimization: {
    minimize: false
  },
  output: {
    path: `${__dirname}/public`,
    filename: '[name].js',
  }
}
  • index.js:
import express from 'express'
const app = express();
app.use(express.static(`${__dirname}/public`));
app.listen(3000, () => console.log(`App listening at http://localhost:${3000}`))
  • component.js:
import { createApp } from 'vue'

createApp({
  template:`
    <div>
      <h2>Component</h2>
      <p>I'm a little component that display a list of numbers</p>
      <ul>
        <li v-for="n in numbers">{{ n }}</li>
      </ul>
    </div>
  `,
  data() {
    return {
      numbers: [1, 2, 3],
    }
  },
}).mount('#my-container')
  • public/index.html:
<html>
  <body>
    <h1>MWE</h1>
    <div id="my-container"></div>
    <script src="component.js"></script>
  </body>
</html>

Resulting html:

<body cz-shortcut-listen="true">
    <h1>MWE</h1>
    <div id="my-container" data-v-app=""><!----></div>
    <script src="component.js"></script>
  

</body>

However, if I instead use vue via unpkg then it works as expected: ``` diff --git a/component.js b/component.js --- a/component.js b/component.js @@ -1,6 1,4 @@ -import { createApp } from 'vue'

-createApp({ Vue.createApp({ template:`

Component

diff --git a/package.json b/package.json --- a/package.json b/package.json @@ -4,15 4,13 @@ "description": "", "main": "index.js", "scripts": {

  • "start": "node -r esm index.js",
  • "build": "webpack --config webpack.config.js" "start": "node -r esm index.js" }, "author": "", "license": "ISC", "dependencies": { "esm": "^3.2.25", "express": "^4.17.1",
  • "vue": "^3.1.5", "webpack": "^5.49.0" }, "devDependencies": { diff --git a/public/index.html b/public/index.html --- a/public/index.html b/public/index.html @@ -1,4 1,7 @@
  • <script src="https://unpkg.com/vue@3.1.5"></script>
    
  • MWE

    diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 --- a/webpack.config.js /dev/null @@ -1,12 0,0 @@ -module.exports = {
  • entry: {
  • component: './component.js',
  • },
  • optimization: {
  • minimize: false
  • },
  • output: {
  • path: ${__dirname}/public,
  • filename: '[name].js',
  • } -}
  `cp component.js public/`

Resulting html:
```html
<body cz-shortcut-listen="true">
    <h1>MWE</h1>
    <div id="my-container" data-v-app=""><div><h2>Component</h2><p>I'm a little component that display a list of numbers</p><ul><li>1</li><li>2</li><li>3</li></ul></div></div>
    <script src="component.js"></script>
  

</body>

What is expected?

For the div element to get replaced with the component

What is actually happening?

vue silently does not mount the component


No errors are shown

avatar
Aug 8th 2021

Your webpack config is missing an alias to pont to the right build of Vue - one that includes a runtime-compiler for string templates:

https://v3.vuejs.org/guide/installation.html#with-a-bundler

avatar
Aug 8th 2021

Hi @LinusBorg, is there some basic example of a webpack configuration that allows this to work? I'm fairly new to bundling in general and the provided link is not clear enough to me.

avatar
Aug 8th 2021

In particular, what does an alias to the "the right build of Vue" mean?

avatar
Aug 9th 2021

In particular, what does an alias to the "the right build of Vue" mean?

In order to use the functionality of the vue.js template, you need to load the finished package with the compiler and runtime, but vue.js by default loads the runtime only version, so you need to explicitly specify the version (vue.esm-bundler.js)

try this

// webpack.config.js
module.exports = {
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm-bundler.js'
        }
    }
}
avatar
Aug 9th 2021

Got it, tyvm!