Skip to content

Commit

Permalink
feat!: use vue 2.7 to provide composition api (#378)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe authored Jul 2, 2022
1 parent 31eb117 commit b55dc9d
Show file tree
Hide file tree
Showing 18 changed files with 1,106 additions and 1,342 deletions.
1 change: 1 addition & 0 deletions build.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default defineBuildConfig({
externals: [
'webpack',
'vite',
'vue',
'vue-meta'
]
})
8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
"@nuxt/schema": "^3.0.0-rc.4",
"@nuxt/ui-templates": "^0.1.1",
"@vitejs/plugin-legacy": "^1.8.2",
"@vue/composition-api": "^1.6.2",
"acorn": "^8.7.1",
"cookie-es": "^0.5.0",
"defu": "^6.0.0",
Expand Down Expand Up @@ -71,9 +70,8 @@
"unplugin-vue2-script-setup": "^0.11.0",
"untyped": "^0.4.4",
"vite": "^2.9.13",
"vite-plugin-vue2": "^2.0.1",
"vue-bundle-renderer": "^0.3.9",
"vue-template-compiler": "^2.6.14"
"@vitejs/plugin-vue2": "^1.1.2",
"vue-bundle-renderer": "^0.3.9"
},
"devDependencies": {
"@nuxt/bridge": "link:.",
Expand All @@ -92,7 +90,7 @@
"nuxt": "^2",
"unbuild": "0.7.4",
"vitest": "^0.16.0",
"vue": "^2",
"vue": "^2.7.0",
"vue-router": "^3"
},
"engines": {
Expand Down
9 changes: 3 additions & 6 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,16 @@ export async function setupAppBridge (_options: any) {
references.push({ path: resolve(nuxt.options.buildDir, 'types/schema.d.ts') })
})

// Alias vue to have identical vue3 exports
// Alias vue3 utilities to vue2
const { dst: vueCompat } = addTemplate({ src: resolve(distDir, 'runtime/vue2-bridge.mjs') })
addWebpackPlugin(VueCompat.webpack({ src: vueCompat }))
addVitePlugin(VueCompat.vite({ src: vueCompat }))

nuxt.hook('prepare:types', ({ tsConfig, references }) => {
// Type 'vue' module with composition API exports
references.push({ path: resolve(distDir, 'runtime/vue2-bridge.d.ts') })

nuxt.hook('prepare:types', ({ tsConfig }) => {
// Enable Volar support with vue 2 compat mode
// @ts-ignore
tsConfig.vueCompilerOptions = {
experimentalCompatMode: 2
target: 2.7
}
})

Expand Down
4 changes: 2 additions & 2 deletions src/auto-imports.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { installModule, useNuxt } from '@nuxt/kit'
import * as CompositionApi from '@vue/composition-api'
import * as CompositionApi from 'vue'
import type { Preset } from 'unimport'
import autoImports from './auto-imports/module'

Expand All @@ -9,7 +9,7 @@ export function setupAutoImports () {
const nuxt = useNuxt()

const bridgePresets: Preset[] = [{
from: '@vue/composition-api',
from: 'vue',
imports: vue3Keys.filter(i => CapiHelpers.has(i as string))
}]

Expand Down
21 changes: 2 additions & 19 deletions src/capi.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { createRequire } from 'module'
import { useNuxt, addPluginTemplate, addVitePlugin, addWebpackPlugin } from '@nuxt/kit'
import { resolve } from 'pathe'
import { BridgeConfig } from '../types'
Expand All @@ -13,15 +12,7 @@ export function setupCAPIBridge (options: Exclude<BridgeConfig['capi'], boolean>
throw new Error('Please remove `@nuxtjs/composition-api` from `buildModules` to avoid conflict with bridge.')
}

// Add composition-api support
const _require = createRequire(import.meta.url)
const vueCapiEntry = _require.resolve('@vue/composition-api/dist/vue-composition-api.mjs')
nuxt.options.alias['@vue/composition-api/dist/vue-composition-api.common.js'] = vueCapiEntry
nuxt.options.alias['@vue/composition-api/dist/vue-composition-api.common.prod.js'] = vueCapiEntry
nuxt.options.alias['@vue/composition-api/dist/vue-composition-api.esm.js'] = vueCapiEntry
nuxt.options.alias['@vue/composition-api/dist/vue-composition-api.js'] = vueCapiEntry
nuxt.options.alias['@vue/composition-api/dist/vue-composition-api.mjs'] = vueCapiEntry
nuxt.options.alias['@vue/composition-api'] = vueCapiEntry
// Add support for onGlobalSetup
const capiPluginPath = resolve(distDir, 'runtime/capi.plugin.mjs')
addPluginTemplate({ filename: 'capi.plugin.mjs', src: capiPluginPath })

Expand All @@ -31,24 +22,16 @@ export function setupCAPIBridge (options: Exclude<BridgeConfig['capi'], boolean>
nuxt.options.plugins.unshift(appPlugin)
})

// Register Composition API before loading the rest of app
nuxt.hook('webpack:config', (configs) => {
// @ts-ignore
configs.forEach(config => config.entry.app.unshift(capiPluginPath))
})

if (options.legacy === false) {
// Skip adding `@nuxtjs/composition-api` handlers if legacy support is disabled
return
}

// Handle legacy `@nuxtjs/composition-api`
nuxt.options.alias['@nuxtjs/composition-api'] = resolve(distDir, 'runtime/capi.legacy.mjs')
nuxt.options.build.transpile.push('@nuxtjs/composition-api', '@vue/composition-api')
nuxt.options.build.transpile.push('@nuxtjs/composition-api')

// Enable automatic ssrRef key generation
addVitePlugin(KeyPlugin.vite())
addWebpackPlugin(KeyPlugin.webpack())

// TODO: Add @nuxtjs/composition-api shims
}
3 changes: 3 additions & 0 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ export default defineNuxtModule({
if (opts.vite) {
const viteModule = await import('./vite/module').then(r => r.default || r) as NuxtModule
nuxt.hook('modules:done', () => installModule(viteModule))
} else {
// with webpack, we need to transpile vue to handle the default/named exports in Vue 2.7
nuxt.options.build.transpile.push('vue')
}
if (opts.postcss8) {
await installModule(_require.resolve('@nuxt/postcss8'))
Expand Down
19 changes: 10 additions & 9 deletions src/runtime/capi.legacy.mjs
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
import { defu } from 'defu'
import { computed, getCurrentInstance as getVM, isReactive, isRef, onBeforeMount, onServerPrefetch, reactive, ref, set, shallowRef, toRaw, toRefs, watch } from '@vue/composition-api'
import { computed, getCurrentInstance as getVM, isReactive, isRef, onBeforeMount, onServerPrefetch, reactive, ref, set, shallowRef, toRaw, toRefs, watch } from 'vue'
import { useNuxtApp } from './app'
import { useRouter as _useRouter, useState } from './composables'

// Vue composition API export
export {
computed,
createApp,
createRef,
customRef,
defineAsyncComponent,
del,
effectScope,
getCurrentInstance,
getCurrentScope,
h,
inject,
isRaw,
isReactive,
isReadonly,
isRef,
Expand All @@ -34,7 +30,6 @@ export {
onUnmounted,
onUpdated,
provide,
proxyRefs,
reactive,
readonly,
set,
Expand All @@ -48,15 +43,14 @@ export {
unref,
useAttrs,
useCssModule,
useCSSModule,
useCssModule as useCSSModule,
useSlots,
version,
warn,
watch,
watchEffect,
watchPostEffect,
watchSyncEffect
} from '@vue/composition-api'
} from 'vue'

export { ref }

Expand All @@ -73,6 +67,13 @@ const warnOnce = (id, message) => {
}
}

export const createApp = () => unsupported('`createApp` is not provided by Vue 2.7.')
export const createRef = () => unsupported('`createRef` is not provided by Vue 2.7.')
export const defineAsyncComponent = () => unsupported('`defineAsyncComponent` is not provided by Vue 2.7.')
export const isRaw = () => unsupported('`isRaw` is not provided by Vue 2.7.')
export const proxyRefs = () => unsupported('`proxyRefs` is not provided by Vue 2.7.')
export const warn = () => unsupported('`warn` is not provided by Vue 2.7.')

// Warn in case of having any imports from `@nuxtjs/composition-api`
warnOnce('import', '`@nuxtjs/composition-api` is deprecated.')

Expand Down
4 changes: 0 additions & 4 deletions src/runtime/capi.plugin.mjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'
import { defineNuxtPlugin } from '#app'

Vue.use(VueCompositionAPI.default || VueCompositionAPI)

export default defineNuxtPlugin((nuxtApp) => {
const _originalSetup = nuxtApp.nuxt2Context.app.setup

Expand Down
4 changes: 2 additions & 2 deletions src/runtime/composables.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getCurrentInstance, onBeforeUnmount, isRef, watch, reactive, toRef, isReactive, Ref, set } from '@vue/composition-api'
import { getCurrentInstance, onBeforeUnmount, isRef, watch, reactive, toRef, isReactive, Ref, set } from 'vue'
import type { CombinedVueInstance } from 'vue/types/vue'
import type { MetaInfo } from 'vue-meta'
import type VueRouter from 'vue-router'
Expand All @@ -13,7 +13,7 @@ export { useLazyFetch } from './fetch'
export { useCookie } from './cookie'
export { useRequestHeaders, useRequestEvent } from './ssr'

export * from '@vue/composition-api'
export * from 'vue'

const mock = () => () => { throw new Error('not implemented') }

Expand Down
2 changes: 1 addition & 1 deletion src/runtime/head/vueuse-head.plugin.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createHead, renderHeadToString } from '@vueuse/head'
import { computed, ref, watchEffect, onBeforeUnmount, getCurrentInstance, ComputedGetter } from '@vue/composition-api'
import { computed, ref, watchEffect, onBeforeUnmount, getCurrentInstance, ComputedGetter } from 'vue'
import { defu } from 'defu'
import type { MetaObject } from '..'
import { defineNuxtPlugin } from '#app'
Expand Down
60 changes: 0 additions & 60 deletions src/runtime/vue2-bridge.d.ts

This file was deleted.

13 changes: 1 addition & 12 deletions src/runtime/vue2-bridge.mjs
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
import Vue from 'vue'

export { EffectScope, computed, createApp, createRef, customRef, defineAsyncComponent, defineComponent, del, effectScope, getCurrentInstance, getCurrentScope, h, inject, isRaw, isReactive, isReadonly, isRef, markRaw, nextTick, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, provide, proxyRefs, reactive, readonly, ref, set, shallowReactive, shallowReadonly, shallowRef, toRaw, toRef, toRefs, triggerRef, unref, useAttrs, useCSSModule, useCssModule, useSlots, warn, watch, watchEffect, watchPostEffect, watchSyncEffect } from '@vue/composition-api'
export * from 'vue'

export const isFunction = fn => fn instanceof Function

export { Vue as default }

// mock for vue-demi
export const Vue2 = Vue
export const isVue2 = true
export const isVue3 = false
export const install = () => {}
export const version = Vue.version
2 changes: 1 addition & 1 deletion src/vite/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { resolve } from 'pathe'
import * as vite from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'
import createVuePlugin from '@vitejs/plugin-vue2'
import PluginLegacy from '@vitejs/plugin-legacy'
import { logger } from '@nuxt/kit'
import { joinURL } from 'ufo'
Expand Down
2 changes: 1 addition & 1 deletion src/vite/server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { resolve } from 'pathe'
import * as vite from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'
import createVuePlugin from '@vitejs/plugin-vue2'
import { logger } from '@nuxt/kit'
import fse from 'fs-extra'
import { debounce } from 'perfect-debounce'
Expand Down
6 changes: 3 additions & 3 deletions src/vite/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { InlineConfig, SSROptions } from 'vite'
import type { VueViteOptions } from 'vite-plugin-vue2'
import type { Options as VueViteOptions } from '@vitejs/plugin-vue2'

export interface Nuxt {
options: any;
Expand All @@ -10,9 +10,9 @@ export interface Nuxt {

export interface ViteOptions extends Omit<InlineConfig, 'build'> {
/**
* Options for vite-plugin-vue2
* Options for @vitejs/plugin-vue2
*
* @see https://github.com/underfin/vite-plugin-vue2
* @see https://github.com/vitejs/vite-plugin-vue2
*/
vue?: VueViteOptions

Expand Down
23 changes: 1 addition & 22 deletions src/vue-compat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,30 +45,9 @@ export const VueCompat = createUnplugin((opts: { src?: string }) => {
})

const vueAliases = [
// vue
'vue',
// vue 3 helper packages
'@vue/shared',
'@vue/reactivity',
'@vue/runtime-core',
'@vue/runtime-dom',
// vue-demi
'vue-demi',
...[
// vue 2 dist files
'vue/dist/vue.common.dev',
'vue/dist/vue.common',
'vue/dist/vue.common.prod',
'vue/dist/vue.esm.browser',
'vue/dist/vue.esm.browser.min',
'vue/dist/vue.esm',
'vue/dist/vue',
'vue/dist/vue.min',
'vue/dist/vue.runtime.common.dev',
'vue/dist/vue.runtime.common',
'vue/dist/vue.runtime.common.prod',
'vue/dist/vue.runtime.esm',
'vue/dist/vue.runtime',
'vue/dist/vue.runtime.min'
].flatMap(m => [m, `${m}.js`])
'@vue/runtime-dom'
]
8 changes: 2 additions & 6 deletions test/bridge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,7 @@ describe('dynamic paths', () => {
const html = await $fetch('/foo/assets')
for (const match of html.matchAll(/(href|src)="(.*?)"/g)) {
const url = match[2]
// TODO: should be /foo/public.svg
expect(
url.startsWith('/foo/_other/') || url === '/public.svg'
).toBeTruthy()
expect(url.startsWith('/foo/_other/') || url === '/foo/public.svg').toBeTruthy()
}
})

Expand All @@ -107,9 +104,8 @@ describe('dynamic paths', () => {
const html = await $fetch('/foo/assets')
for (const match of html.matchAll(/(href|src)="(.*?)"/g)) {
const url = match[2]
// TODO: should be https://example.com/public.svg
expect(
url.startsWith('https://example.com/_cdn/') || url === '/public.svg'
url.startsWith('https://example.com/_cdn/') || url === 'https://example.com/public.svg'
).toBeTruthy()
}
})
Expand Down
Loading

0 comments on commit b55dc9d

Please sign in to comment.