๐ŸŽฉ Vue Demi is a developing utility allows you to write Universal Vue Libraries for Vue 2 & 3

Overview


npm

Vue Demi (half in French) is a developing utility
allows you to write Universal Vue Libraries for Vue 2 & 3
See more details in this blog post



Usage

Install this as your plugin's dependency:

npm i vue-demi
# or
yarn add vue-demi

Add vue and @vue/composition-api to your plugin's peer dependencies to specify what versions you support.

=3.0.0" }, "peerDependenciesMeta": { "@vue/composition-api": { "optional": true } }, "devDependencies": { "vue": "^3.0.0" // or "^2.6.0" base on your preferred working environment }, } ">
{
  "dependencies": {
    "vue-demi": "latest"
  },
  "peerDependencies": {
    "@vue/composition-api": "^1.0.0-rc.1",
    "vue": "^2.0.0 || >=3.0.0"
  },
  "peerDependenciesMeta": {
    "@vue/composition-api": {
      "optional": true
    }
  },
  "devDependencies": {
    "vue": "^3.0.0" // or "^2.6.0" base on your preferred working environment
  },
}

Import everything related to Vue from it, it will redirect to [email protected] + @vue/composition-api or [email protected] based on users' environments.

import { ref, reactive, defineComponent } from 'vue-demi'

Publish your plugin and all is done!

When using with Vite, you will need to opt-out the pre-bundling to get vue-demi work properly by

// vite.config.js
export default defineConfig({
  optimizeDeps: {
    exclude: ['vue-demi']
 }
})

Extra APIs

Vue Demi provides extra APIs to help distinguish users' environments and to do some version-specific logic.

isVue2 isVue3

import { isVue2, isVue3 } from 'vue-demi'

if (isVue2) {
  // Vue 2 only
} else {
  // Vue 3 only
}

Vue2

To avoid bringing in all the tree-shakable modules, we provide a Vue2 export to support access to Vue 2's global API. (See #41.)

import { Vue2 } from 'vue-demi'

if (Vue2) {
  Vue2.config.ignoredElements.push('x-foo')
}

install()

Composition API in Vue 2 is provided as a plugin and needs to be installed on the Vue instance before using. Normally, vue-demi will try to install it automatically. For some usages where you might need to ensure the plugin gets installed correctly, the install() API is exposed to as a safe version of Vue.use(CompositionAPI). install() in the Vue 3 environment will be an empty function (no-op).

import { install } from 'vue-demi'

install()

CLI

Manually Switch Versions

To explicitly switch the redirecting version, you can use these commands in your project's root.

npx vue-demi-switch 2
# or
npx vue-demi-switch 3

Package Aliasing

If you would like to import vue under an alias, you can use the following command

npx vue-demi-switch 2 vue2
# or
npx vue-demi-switch 3 vue3

Then vue-demi will redirect APIs from the alias name you specified, for example:

import * as Vue from 'vue3'

var isVue2 = false
var isVue3 = true
var Vue2 = undefined

export * from 'vue3'
export {
  Vue,
  Vue2,
  isVue2,
  isVue3,
}

Auto Fix

If the postinstall hook doesn't get triggered or you have updated the Vue version, try to run the following command to resolve the redirecting.

npx vue-demi-fix

Isomorphic Testings

You can support testing for both versions by adding npm alias in your dev dependencies. For example:

{
  "scripts": {
    "test:2": "vue-demi-switch 2 vue2 && jest",
    "test:3": "vue-demi-switch 3 && jest",
  },
  "devDependencies": {
    "vue": "^3.0.0",
    "vue2": "npm:[email protected]"
  },
}

or

{
  "scripts": {
    "test:2": "vue-demi-switch 2 && jest",
    "test:3": "vue-demi-switch 3 vue3 && jest",
  },
  "devDependencies": {
    "vue": "^2.6.0",
    "vue3": "npm:[email protected]"
  },
}

Examples

See examples.

Who is using this?

open a PR to add your library ;)

Underhood

See the blog post.

License

MIT License ยฉ 2020 Anthony Fu

Issues
  • Dependency issue with @nuxtjs/composition-api

    Dependency issue with @nuxtjs/composition-api

    I'm trying to use @vueuse/core with @nuxtjs/composition-api in my Nuxt project. And I get a error message:

    This dependency was not found:
    * @vue/composition-api/dist/vue-composition-api.esm.js in ./node_modules/vue-demi/lib/index.mjs
    

    But @vue/composition-api have been install. Because @vue/composition-api is also @nuxtjs/composition-api's dependency. I have no idea how to fix it.

    Here is reproduction link: codesandbox

    Have any solution to fix this? Thank you!

    opened by Ricklin90085 19
  • How to do Vue.use(CompositionAPI) in tests?

    How to do Vue.use(CompositionAPI) in tests?

    Hey, first of all great library it's something that's been much needed ๐Ÿ‘ so thanks a bunch

    I tried to use it in https://github.com/MartinMalinda/vue-concurrency and I hit a blocker that it breaks my test suite.

    I have a quick setup file that is being run before every test:

    https://github.com/MartinMalinda/vue-concurrency/blob/master/test-utils/vue-setup.ts

    This worked fine before but it doesn't do the trick now when I import from vue-demi. I guess I do .use on wrong Vue. Perhaps there needs to be import { Vue } from 'vue-demi'; solely for testing purposes?

    opened by MartinMalinda 13
  • NPM7: Incorrect detection of Vue version

    NPM7: Incorrect detection of Vue version

    Hi, I was trying to use @vueuse/core when I ran into an issue with this package. I'm using npm 7.0.3, node 15.0.1 and my package.json looks like this:

    {
        "private": true,
        "scripts": {
            "development": "mix",
            "watch": "mix watch",
            "watch-poll": "mix watch -- --watch-options-poll=1000",
            "hot": "mix watch --hot",
            "production": "mix --production"
        },
        "devDependencies": {
            "@vue/compiler-sfc": "^3.0.2",
            "autoprefixer": "^10.0.1",
            "axios": "^0.19",
            "cross-env": "^7.0",
            "laravel-mix": "^6.0.0-beta.11",
            "lodash": "^4.17.19",
            "postcss-import": "^12.0.1",
            "postcss-nested": "^4.2.3",
            "postcss-simple-vars": "^5.0.2",
            "resolve-url-loader": "^3.1.0",
            "sass-resources-loader": "^2.1.1",
            "tailwindcss": "^1.9.6",
            "tailwindcss-filters": "^3.0.0",
            "vue": "^3.0.2",
            "vue-loader": "^16.0.0-beta.10",
            "vue-router": "^4.0.0-rc.1",
            "vuex": "^4.0.0-rc.1",
            "@vueuse/core": "^4.0.0-beta.38"
        }
    }
    
    

    I'm using Laravel Mix to compile all the assets (I'll be using Laravel as a backend). Everything was going fine until I tried to use any function from the vueuse package.

    The console error looked like this:

    image

    Going thru the module code I see some lines are overwritten depending of the Vue version and it looks like the module thinks I'm on version 2 of Vue. Manually changing those lines to the 'v3' fixed the issue. I'm not sure this is Laravel Mix fault (webpack wrapper) or not. Let me know how can I help fixing this issue.

    opened by gerardnll 12
  • Error building after last update

    Error building after last update

    Hi,

    After the last update for version 0.8, i cannot run build on my app:

    RROR Failed to compile with 42 errors7:36:04 PM error in ./node_modules/@vueuse/core/node_modules/vue-demi/lib/index.esm.mjs Can't reexport the named export 'computed' from non EcmaScript module (only default export is available) error in ./node_modules/@vueuse/core/node_modules/vue-demi/lib/index.esm.mjs Can't reexport the named export 'createApp' from non EcmaScript module (only default export is available) error in ./node_modules/@vueuse/core/node_modules/vue-demi/lib/index.esm.mjs Can't reexport the named export 'customRef' from non EcmaScript module (only default export is available) error in ./node_modules/@vueuse/core/node_modules/vue-demi/lib/index.esm.mjs Can't reexport the named export 'defineComponent' from non EcmaScript module (only default export is available) error in ./node_modules/@vueuse/core/node_modules/vue-demi/lib/index.esm.mjs Can't reexport the named export 'del' from non EcmaScript module (only default export is available) error in ./node_modules/@vueuse/core/node_modules/vue-demi/lib/index.esm.mjs Can't reexport the named export 'getCurrentInstance' from non EcmaScript module (only default export is available) error in ./node_modules/@vueuse/core/node_modules/vue-demi/lib/index.esm.mjs Can't reexport the named export 'h' from non EcmaScript module (only default export is available)

    needs reproduction 
    opened by miguelfspinto 11
  • v 0.11.1 causes issues to vue-use

    v 0.11.1 causes issues to vue-use

    we re using @vueuse/core 5.0.3 and the latest update to vue demi, breaks our build(which was fine a few hours ago). We re not using vue-demi directly, only through vueuse.

     error  in ./node_modules/vue-demi/lib/index.mjs
    
    Can't reexport the named export 'computed' from non EcmaScript module (only default export is available)
    

    we re seeing a bunch of these, not only "computed"; everything exported from vue-demi causes this issue.

    opened by fk1blow 9
  • [v.6.0] Vue undefined while using reactive

    [v.6.0] Vue undefined while using reactive

    Hello @antfu,

    I am facing a strange issue while using v6.0 of the vue-demi package in my project. I have a global 'store' which can also be accessed outside of the Vue-context (e.g. in main.ts). The Vue.use(VueCompositionApi) call is made before calling any composition-api related functions.

    import { computed, reactive } from "@vue/composition-api"
    import { toReadonlyState } from "@/utils/composition"
    
    interface GeneralStore {
      token: string | null
      isAuthenticated: boolean
      isTranslationPresent: boolean
      translationError: boolean
    }
    
    const state = reactive<GeneralStore>({
      token: null,
      isAuthenticated: false,
      isTranslationPresent: false,
      translationError: false,
    })
    
    export function useGeneralStore() {
      const mutations = {
        setToken: (token?: string) => {
          state.token = token ?? null
        },
        setIsAuthenticated: (isAuthenticated: boolean) => {
          state.isAuthenticated = isAuthenticated
        },
        setIsTranslationPresent: (isTranslationPresent: boolean) => {
          state.isTranslationPresent = isTranslationPresent
        },
        setTranslationError: (translationError: boolean) => {
          state.translationError = translationError
        },
      }
    
      return {
        ...toReadonlyState(state),
        ...mutations,
      }
    }
    
    

    After upgrading vue-demi to v6.0 the whole Vue2 application crashes on load with the following error:

    Uncaught TypeError: Cannot read property 'observable' of undefined
      at ht (vue-composition-api.esm.js:563)
      ah gt (vue-composition-api.esm.js:673)
      ...
    

    It seems Vue is undefined here...

    // vue-composition-api.esm.js
    function reactive(obj) {
        if ((process.env.NODE_ENV !== 'production') && !obj) {
            warn('"reactive()" is called without provide an "object".');
            // @ts-ignore
            return;
        }
        if (!(isPlainObject(obj) || isArray(obj)) ||
            isRaw(obj) ||
            !Object.isExtensible(obj)) {
            return obj;
        }
        var observed = observe(obj); // FIXME: this call crashes due to Vue = undefined (line 673)
        setupAccessControl(observed);
        return observed;
    }
    
    // vue-composition-api.esm.js
    function observe(obj) {
        var Vue = getRegisteredVueOrDefault();
        var observed;
        if (Vue.observable) { // FIXME: Vue is undefined here (line 563)
            observed = Vue.observable(obj);
        }
        else {
            var vm = defineComponentInstance(Vue, {
                data: {
                    $$state: obj,
                },
            });
            observed = vm._data.$$state;
        }
        // in SSR, there is no __ob__. Mock for reactivity check
        if (!hasOwn(observed, '__ob__')) {
            def(observed, '__ob__', mockObserver(observed));
        }
        return observed;
    }
    
    opened by lstoeferle 8
  • Skypack version of vue-demi imports vue 2 but sets isVue3 to true

    Skypack version of vue-demi imports vue 2 but sets isVue3 to true

    https://cdn.skypack.dev/-/[email protected]/dist=es2020,mode=imports/optimized/vue-demi.js

    export * from "/-/[email protected]/dist=es2020,mode=imports/optimized/vue.js";
    import * as vue from "/-/[email protected]/dist=es2020,mode=imports/optimized/vue.js";
    export {vue as Vue};
    var isVue2 = false;
    var isVue3 = true;
    
    opened by Demivan 8
  • Error: [vue-composition-api] must call Vue.use(VueCompositionAPI) before using any function in typescripts

    Error: [vue-composition-api] must call Vue.use(VueCompositionAPI) before using any function in typescripts

    Hello,

    I'm having trouble using your library to implement some functions in typescript. Is showing me the message

    "Error: [vue-composition-api] must call Vue.use (VueCompositionAPI) before using any function."
    

    I leave below the error output. I will appreciate your help and your prompt response.!!

    import {ref, reactive, UnwrapRef, Ref } from 'vue-demi';
    
    export function fxReactive<T extends object>(obj: T): UnwrapRef<T> {
      return reactive(obj);
    }
    
    const fx = fxReactive({
      data: []
    });
    
    console.log(fx.data);
    

    devDependecies

    "@vue/composition-api": "^1.0.0-beta.1",
    "vue": "^2.6.11"
    

    dependecies

    "vue-demi": "latest"
    

    error

    C:\Users\c\Desktop\reactivefx\node_modules\@vue\composition-api\dist\vue-composition-api.common.js:43
            throw new Error("[vue-composition-api] " + msg);
                  ^
    Error: [vue-composition-api] must call Vue.use(VueCompositionAPI) before using any function.
        at assert (C:\Users\c\Desktop\reactivefx\node_modules\@vue\composition-api\dist\vue-composition-api.common.js:43:15)
        at getVueConstructor (C:\Users\c\Desktop\reactivefx\node_modules\@vue\composition-api\dist\vue-composition-api.common.js:83:9)
        at observe (C:\Users\c\Desktop\reactivefx\node_modules\@vue\composition-api\dist\vue-composition-api.common.js:470:15)
        at Function.reactive (C:\Users\c\Desktop\reactivefx\node_modules\@vue\composition-api\dist\vue-composition-api.common.js:595:20)
        at fxReactive (C:\Users\c\Desktop\reactivefx\src\index.ts:6:10)
        at Object.<anonymous> (C:\Users\c\Desktop\reactivefx\src\index.ts:9:12)
        at Module._compile (internal/modules/cjs/loader.js:1176:30)
        at Module.m._compile (C:\Users\c\AppData\Roaming\npm\node_modules\ts-node\src\index.ts:473:23)
        at Module._extensions..js (internal/modules/cjs/loader.js:1196:10)
        at Object.require.extensions.<computed> [as .ts] (C:\Users\c\AppData\Roaming\npm\node_modules\ts-node\src\index.ts:476:12)
    
    needs reproduction 
    opened by ChrisMichaelPerezSantiago 7
  • Why is @vue/composition-api a dependency?

    Why is @vue/composition-api a dependency?

    Shouldn't it be a peer dependency? I think that this is messing with my app after updating @vue/apollo-composable from 4.0 alpha 9 to alpha 10, which adds vue-demi

    opened by NickBolles 7
  • vue-demi does not list @vue/composition-api as a dependency

    vue-demi does not list @vue/composition-api as a dependency

    When using pnpm (hoist = false) or [email protected] webpack build fails as vue-demi tries to access @vue/composition-api without listing it as a dependency. It is the same issue as #9 but for @vue/composition-api. Why was is removed from peer dependencies?

    opened by Demivan 7
Releases(v0.11.2)
Owner
VueUse
Collection of Vue Composition Utilities
VueUse
๐ŸŒˆ An enterprise-class UI components based on Ant Design and Vue. ๐Ÿœ

Ant Design Vue An enterprise-class UI components based on Ant Design and Vue. English | ็ฎ€ไฝ“ไธญๆ–‡ Features An enterprise-class UI design system for desktop

vueComponent 14.9k Jul 24, 2021
๐Ÿ‰ Material Component Framework for Vue

Supporting Vuetify Vuetify is a MIT licensed project that is developed and maintained full-time by John Leider and Heather Leider; with support from t

vuetify 31.6k Jul 25, 2021
BootstrapVue provides one of the most comprehensive implementations of Bootstrap v4 for Vue.js. With extensive and automated WAI-ARIA accessibility markup.

With more than 85 components, over 45 available plugins, several directives, and 1000+ icons, BootstrapVue provides one of the most comprehensive impl

BootstrapVue 13.3k Jul 25, 2021
โšก๏ธ Build scalable and accessible Vue.js applications with ease.

Build scalable and accessible Vue.js applications with ease. @chakra-ui/vue gives you a set of accessible and composable Vue components that you can u

Chakra UI 1.2k Jul 21, 2021
Vue.js components implementation of Fundamental Library Styles guidelines. The library is aiming to provide a Vue.js implementation of the components designed in Fundamental Library Styles.

Fundamental Vue Description The fundamental-vue library is a set of Vue.js components built using Fundamental Library Styles. Fundamental Library for

SAP 176 Jul 9, 2021
Material design for Vue.js

Material Design for Vue.js Vue Material is Simple, lightweight and built exactly according to the Google Material Design specs Build well-designed app

Vue Material 9.4k Jul 24, 2021
๐ŸŒŸShards Vue is a free, beautiful and modern Vue.js UI kit based on Shards.

Shards Vue is a free, beautiful and modern Vue.js UI kit based on Shards. Documentation & Demo โ€ข Official Page Getting Started Getting started with Sh

DesignRevision 395 Jun 24, 2021
Vue Bootstrap with Material Design - Powerful and free UI KIT

Vue Bootstrap with Material Design Based on the latest Bootstrap 4 and Vue. 400+ material UI elemens, 600+ material icons, 74 CSS animations, SASS fil

MDBootstrap 810 Jul 24, 2021
:trophy:Mui component for Vue.js(1.x ~ 2.x)

vue-awesome-mui Design Mui library for Vuejs 2.x Links Demo Page Muiไธญๆ–‡ๆ–‡ๆกฃ Install Install vue-awesome-mui npm install vue-awesome-mui -save Get Started

Eno Yao 307 Feb 2, 2021
:diamonds: A modular and customizable UI library based on Material Design and Vue

BalmUI Next Generation Material UI for Vue.js Introduction BalmUI is a modular and customizable Material Design UI library for Vue.js. ?? NOW, balm-ui

BalmJS 183 Jul 22, 2021
๐Ÿ› Oruga is a lightweight library of UI components without CSS framework dependency

Oruga UI is like a caterpillar, minimal and yet functional. It's in your hands turning it into a butterfly ( ?? ) => ?? Oruga is a lightweight library

Oruga 387 Jul 27, 2021
A Vue.js design-system for Web.

A Vue.js Design System for Web. Responsive, user-friendly and lightweight library helping us build great products for our customers. This library for

Qvant 195 Jul 25, 2021
Vue 3 & Bootstrap 5 & Material Design 2.0 UI KIT

Vue 3 & Bootstrap 5 & Material Design 2.0 UI KIT

MDBootstrap 67 Jul 21, 2021