Home > Blockchain >  Why is Vue undefined in my webpack-bundled app after trying to import it as a client-side library
Why is Vue undefined in my webpack-bundled app after trying to import it as a client-side library

Time:02-11

I have been having an issue for 2 days and finally isolated it. Importing Vue and VueRouter gives me undefined in my frontend code. This is because the output from webpack, using the externals property to load client-side libraries, checks for module.__esModule when you import an externally loaded library, and if true then it returns module.default. In this case Vue.__esModule and VueRouter.__esModule are true while Vue.default and VueRouter.default are undefined. I'm not even sure who to file a bug with, or whether there is something I can add to webpack.config.js to make this work as before. It could be Vue for including __esModule on their global builds. Or it could be something in the internals of webpack.

Here is a section of my package.json

"devDependencies": {
  "@babel/core": "^7.17.0",
  "@babel/preset-env": "^7.16.11",
  "@vue/compiler-sfc": "^3.2.30",
  "babel-loader": "^8.2.3",
  "css-loader": "^6.6.0",
  "mini-css-extract-plugin": "^2.5.3",
  "node-sass": "^7.0.1",
  "sass-loader": "^12.4.0",
  "vue-loader": "^17.0.0",
  "webpack": "^5.68.0",
  "webpack-cli": "^4.9.2"
},
"dependencies": {
    "vue": "^3.2.29"
}

And webpack.config.js

const VueLoader = require('vue-loader');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    mode: 'production',
    stats: 'errors-warnings',
    entry: [
        './src/app.js',
    ],
    output: {
        filename: 'compiled.js',
        path: __dirname   '/js',
    },
    optimization: {
        minimize: true,
    },
    performance: {
        hints: 'warning',
        maxEntrypointSize: 250000, // JS output 250 kB
        maxAssetSize: 250000, // CSS output 250 kB
    },
    externals: {
        'vue': 'Vue',
        'vuex': 'Vuex',
        'vue-router': 'VueRouter',
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader',
            },
            {
                test: /\.m?js$/,
                resolve: {
                    fullySpecified: false,
                },
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            ['@babel/preset-env', {targets: '>1%'}],
                        ],
                    },
                },
            },
            {
                test: /\.s?css$/,
                use: [
                    MiniCssExtractPlugin.loader, // add support for `import 'file.scss';` in JS
                    {
                        loader: 'css-loader',
                        options: {
                            url: false, // whether to resolve urls; leave urls in the code as written
                        },
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            sassOptions: {
                                includePaths: [
                                    //__dirname   '/bower_components/bootstrap-sass/assets/stylesheets',
                                ],
                            },
                        },
                    },
                ],
            },
        ],
    },
    plugins: [
        new VueLoader.VueLoaderPlugin(),
        new MiniCssExtractPlugin({
            // Output destination for compiled CSS
            filename: '../css/compiled.css',
        }),
    ],
};

And index.html loads Vue, VueRouter, Vuex, and then my bundled webapp:

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.29/vue.runtime.global.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/4.0.2/vuex.global.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/4.0.12/vue-router.global.js"></script>
<script>console.log('healthcheck', Vue, Vuex, VueRouter);</script>
<script src="/js/compiled.js"></script>

Then in my frontend code, bundled with webpack:

import Vue from "vue";
import Vuex from "vuex";
import VueRouter from "vue-router";

console.log('client', Vue, Vuex, VueRouter);

Logs healthcheck {...} {...} {...} in the HTML and then the compiled app logs client undefined, {...}, undefined (Vuex is defined because Vuex.__esModule is undefined)

Any ideas what to do?

CodePudding user response:

Answered here https://github.com/vuejs/core/issues/5380

Vue 3 only supports named imports, like import {createApp} from 'vue';

  • Related