Home > Mobile >  App built with vue CLI works perfectly, but when built with webpack appears to work but components f
App built with vue CLI works perfectly, but when built with webpack appears to work but components f

Time:11-08

Been chasing this one for a little while, and managed to narrow it down to my webpack config. I have to use webpack for various reasons, so not using it isn't an option.

Basically I have a 'Hello World' Vue project. When I serve this app through npx vue-cli-service serve it works perfectly, and I get no issues. For reference I have a component that looks like this:

<template>
    <header >
        {{ items }}
        {{ msg }}

        <ul>
            <li v-for="item in items" :key="item.message">
                {{ item.message }}
            </li>
        </ul>
    </header>
</template>

<script>
export default {
    name: 'TheAppHeader',
    props: {
        msg: String
    },
    data() {
        return {
            items: [{ message: 'Foo' }, { message: 'Bar' }],
        }
    },
    created() {
      // eslint-disable-next-line no-console
      console.log('here');
      this.items.push({ message: 'FooBar' });
    }
}
</script>

that works perfectly when served this way - the template that uses it does so via <TheAppHeader msg="test"></TheAppHeader>. I see the msg come through, and I see the rendered this.items correctly (as well as the console.log coming through).

When I build the app via npx webpack build the app half works. I see the msg come through as before, but this.items does not render and the console.log does not come through. Neither data() nor created() are invoked. I cannot figure out what is wrong with my webpack config to create such an obscure issue? Is this common?

my vue.config.js looks like this

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  configureWebpack: {
    devtool: 'source-map',
  }
})

and my webpack.config.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { VueLoaderPlugin } = require('vue-loader')
const webpack = require('webpack');
const ESLintPlugin = require('eslint-webpack-plugin');


module.exports  = (env, argv) => { 
    let config = {
        target: 'web',
        mode: 'development',
        module: {
            rules: [
                {
                    test: /\.(png|jpe?g|gif|svg)$/i,
                    type: 'asset/resource',
                    generator: {
                        filename: 'images/[hash][ext][query]'
                    }
                },
                {  
                    test: /\.(woff|woff2|eot|ttf|otf)$/,
                    type: 'asset/resource',
                    generator: {
                        filename: 'fonts/[hash][ext][query]'
                    }
                },
                {
                    test: /\.vue$/,
                    loader: 'vue-loader',
                    options: {
                        babelParserPlugins: [
                          'jsx',
                          'classProperties',
                          'decorators-legacy'
                        ]
                      }
                },
                // this will apply to both plain `.js` files
                // AND `<script>` blocks in `.vue` files
                {
                    test: /\.js$/,
                    loader: 'babel-loader'
                },
                // this will apply to both plain `.css` files
                // AND `<style>` blocks in `.vue` files
                {
                    test: /\.css$/,
                    use: [
                        'vue-style-loader',
                        'css-loader'
                    ]
                },
            ],
        },
        entry: {
            vue:     './src/main.js'
        },
        optimization: {
            minimize: true
        },
        output: {
            filename: '[name].bundle.js',
            path: path.resolve(__dirname, 'distribution'),
            clean:true,
            publicPath: '/app/',
        },
        plugins: [
            new HtmlWebpackPlugin({
                template: './public/index.html'
            }),
            new VueLoaderPlugin(),
            new webpack.DefinePlugin({
                // Drop Options API from bundle
                __VUE_OPTIONS_API__: false,
                // Enable devtools support
                __VUE_PROD_DEVTOOLS__ : true,
                'process.env': {
                    BASE_URL: '"/"'
                  }
            }),
            new ESLintPlugin(
                {
                
                  extensions: [
                    '.js',
                    '.jsx',
                    '.vue'
                  ],
                  cache: true,
                  failOnWarning: false,
                  failOnError: true,
                  formatter: 'stylish',
                }),
        ],
    }
    return config;
}

CodePudding user response:

<Component>.data() and <Component>.created() are part of the Options API (as per vuejs.org/api). By adding

    new webpack.DefinePlugin({
        // Drop Options API from bundle
        __VUE_OPTIONS_API__: false,
    }),

I was specifically disabling those functions from being called.

I should follow the composition way of doing it with that flag set, as per this answer: Vue 3 Composition API data() function I need to stop using data() and use the setup() call instead.

  • Related