Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue-toastification does not show toasts with vue 3 #354

Open
netandreus opened this issue Nov 17, 2022 · 2 comments
Open

Vue-toastification does not show toasts with vue 3 #354

netandreus opened this issue Nov 17, 2022 · 2 comments
Labels
Type: Bug Something isn't working

Comments

@netandreus
Copy link

Versions

  • 2.0.0-rc.5, and next version also.

Describe the bug

I just installed this package like this:

main.ts

import { createApp } from "vue"
import App from "./components/App.vue"
import Toast, { PluginOptions } from "vue-toastification";
import "vue-toastification/dist/index.css";

const app = createApp(App);
const options: PluginOptions = {
    // You can set your default options here
};
app.use(Toast, options);
...
app.mount("#vue-app");

I use Pinia for state management. Somewhere in

./stores/AuthStore.ts

import { useToast } from "vue-toastification";
...
export const useAuthStore = defineStore({
...
     async onLoginButtonClick() {
           let url: string = '/api/user/auth'
           let toastr = useToast();
            ...
            toastr.success("You are logged in");
            ...
});

There is no toast shows at the page. In browser console there is this error:

[Vue warn]: Property "positions" was accessed during render but is not defined on instance.

Expected behavior

Toast is visible at the page.

Steps to reproduce

Install with this config files.

packages.json

{
...
    "devDependencies": {
        "@babel/core": "^7.19.6",
        "@babel/preset-env": "^7.19.0",
        "@popperjs/core": "^2.11.6",
        "autoprefixer": "^10.4.8",
        "babel-loader": "^9.0.1",
        "bootstrap": "^5.2.2",
        "@types/bootstrap": "5.1.9",
        "copy-webpack-plugin": "^11.0.0",
        "css-loader": "^6.7.1",
        "dotenv-webpack": "^8.0.1",
        "fast-glob": "^3.2.12",
        "mime-types": "^2.1.34",
        "mini-css-extract-plugin": "^2.6.1",
        "path": "^0.12.7",
        "postcss": "^8.4.12",
        "postcss-loader": "^7.0.1",
        "postcss-preset-env": "^7.8.1",
        "sass": "^1.54.9",
        "sass-loader": "^13.0.2",
        "sharp": "^0.31.0",
        "style-loader": "^3.3.1",
        "trash": "^8.1.0",
        "uuid": "^9.0.0",
        "webpack": "^5.74.0",
        "webpack-cli": "4.10.0",
        "typescript": "^4.8.4",
        "ts-loader": "^9.4.1",
        "@types/node": "18.11.9",
        "source-map-loader": "^4.0.1",
        "vue": "^3.2.41",
        "vue-loader": "^17.0.1",
        "@vue/compiler-sfc": "^3.2.41",
        "pinia": "^2.0.23",
        "vue-router": "^4.1.6",
        "vue-style-loader": "4.1.3",
        "rsdi": "2.2.2",
        "emoji-button": "file:../shared/emoji-button/",
        "autosize": "^5.0.1",
        "dropzone": "^5.9.3",
        "zoom-vanilla.js": "^2.0.6",
        "@types/autosize": "4.0.1",
        "@types/dropzone": "5.7.4",
        "html-loader": "4.2.0",
        "axios": "0.27.2",
        "pinia-plugin-persist": "1.0.0",
        "vue-toastification": "^2.0.0-rc.5"
    }
}

webpack.config.js

import Dotenv from "dotenv-webpack"
import path from "path"
import MiniCssExtractPlugin from "mini-css-extract-plugin"
import CopyPlugin from "copy-webpack-plugin"
import webpack from "webpack"
import {VueLoaderPlugin} from "vue-loader"
import Autoprefixer from "autoprefixer"

export default (env, argv) => {
  console.log(`Running webpack in ${argv.mode} mode ...`);

  return [{
    // Watch for hot reload during development
    watchOptions: {
      aggregateTimeout: 200,
        poll: 600,
        ignored: /node_modules/,
    },
    resolve: {
      extensions: [
        ".ts",
        ".tsx",
        ".js",
        ".jsx",
        ".vue",
        ".scss"
      ],
      alias: {
        vue: (argv.mode === 'production') ? 'vue/dist/vue.runtime.esm-bundler.prod.js' : 'vue/dist/vue.runtime.esm-bundler.js'
      },
    },
    // Define the entry points of our application (can be multiple for different sections of a website)
    entry: {
      main: "./src/main.ts",
      "template.light": "./src/scss/template.light.scss",
      "template.dark": "./src/scss/template.dark.scss"
    },

    // Define the destination directory and filenames of compiled resources
    output: {
      filename: "js/[name].js",
      path: path.resolve(process.cwd(), "./public"),
    },

    // Define development options
    devtool: "source-map",

      // Define loaders
      module: {
    rules: [
      // Use babel for JS files
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        use: {
          loader: "babel-loader",
          options: {
            presets: [
              "@babel/preset-env"
            ],
            sourceMap: process.env.NODE_ENV !== 'production',
          }
        }
      },
      // CSS, PostCSS, and Sass
      {
        test: /\.(scss|css)$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              importLoaders: 2,
              sourceMap: process.env.NODE_ENV !== 'production',
              url: false,
            }
          },
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  new Autoprefixer({
                    overrideBrowserslist: ['last 2 versions']
                  }),
                ]
              },
              sourceMap: process.env.NODE_ENV !== 'production',
            }
          },
          "sass-loader"
        ],
      },
      // File loader for images
      {
        test: /\.(jpg|jpeg|png)$/i,
        type: "asset/resource",
      },
      // Inline load SVG-s for use styles from css
      {
        test: /\.svg$/,
        use: [{ loader: 'html-loader' }]
      },
      {
        test: /.y(a?)ml$/,
        exclude: /node_modules/,
        loader: 'json-loader'
      },
      {
        test: /.y(a?)ml$/,
        exclude: /node_modules/,
        loader: 'yaml-loader'
      },
      {
        test: /\.ts(x?)$/,
        loader: "ts-loader",
        options: {
          configFile: path.resolve(process.cwd(), './tsconfig.json'),
          appendTsSuffixTo: [/\.vue$/],
        }
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            ts: 'ts-loader',
            sourceMap: process.env.NODE_ENV !== 'production',
          },
          esModule: true
        }
      },
      {
        enforce: "pre",
        test: /\.[tj]s(x?)$/,
        loader: "source-map-loader",
        options: {
          filterSourceMappingUrl: (url, resourcePath) => {
            if (resourcePath.includes('rsdi')) {
              return false;
            }
            return true;
          },
        },
      },
      // For Pinia (https://github.com/vuejs/pinia/blob/v2/packages/docs/cookbook/migration-v1-v2.md#webpack-4-support)
      {
        test: /\.mjs$/,
        include: /node_modules/,
        type: 'javascript/auto',
      },
    ],
  },

    // Define used plugins
    plugins: [
      // Load .env file for environment variables in JS
      new Dotenv({
        path: "./.env"
      }),

      // Extracts CSS into separate files
      new MiniCssExtractPlugin({
        filename: "css/[name].css",
        chunkFilename: "[id].css"
      }),

      // Copy images to the public folder
      new CopyPlugin({
        patterns: [
          {
            from: "src/images",
            to: "images",
          }
        ]
      }),
      // For Vue.js
      new VueLoaderPlugin(),
      new webpack.DefinePlugin({
        __VUE_OPTIONS_API__: false,
        __VUE_PROD_DEVTOOLS__: false,
      }),
    ],
    // Performance configuration
    performance: {
    hints: false
  }
  }]
};

Environment

  • Device: Parallels VM
  • OS: Ubuntu 20.04.2 LTS
  • Browser: Brave (Chrome)
  • Version: 1.45.127

I also try to use next version without success.

Cause

As lllopo mentioned in issue-305 while your plugin states it is for the composition API, it internally uses the options API for the components. So, setting VUE_OPTIONS_API to false in webpack actually breaks it. And it was my case.

Temporary workaround

Set this

new webpack.DefinePlugin({
     __VUE_OPTIONS_API__: true,
}),

in webpack.config.js solves this issue, but It should be well documented in manual at least. It's a serous problem for all people trying to use this package with vue 3.

@netandreus netandreus added the Type: Bug Something isn't working label Nov 17, 2022
@bad-mushroom
Copy link

I've spent the last day trying to understand why my Toasts work in development but not production 😓 . This bug report led me to the answer... I had __VUE_OPTIONS_API__ explicitly false in my prod webpack build. Changing to true has my app Toast'ing again. Thank you!

@rasteiner
Copy link

Looks like the only place the options api is used is here:

<script lang="ts">
export default {
devtools: {
hide: true,
},
}
</script>

Every other component seems to only use <script setup> tags (or no <script> at all), I guess the snippet above could be safely removed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants