Skip to content

Commit

Permalink
feat: experimental vite support (#387)
Browse files Browse the repository at this point in the history
Co-authored-by: pooya parsa <pyapar@gmail.com>
  • Loading branch information
danielroe and pi0 authored Mar 5, 2021
1 parent 3d27d5e commit e47805d
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 10 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
"dependencies": {
"@vue/composition-api": "1.0.0-rc.3",
"defu": "^3.2.2",
"estree-walker": "^2.0.1",
"magic-string": "^0.25.7",
"ufo": "^0.6.7",
"upath": "^2.0.1"
},
Expand Down Expand Up @@ -122,6 +124,6 @@
}
},
"volta": {
"node": "12.21.0"
"node": "14.16.0"
}
}
26 changes: 17 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import { resolve, join } from 'upath'
import { withTrailingSlash } from 'ufo'
import { readdirSync, copyFileSync, existsSync, mkdirpSync } from 'fs-extra'

import type { Module, NuxtConfig } from '@nuxt/types'

import { name, version } from '../package.json'

import type { Module, NuxtConfig } from '@nuxt/types'
import { compositionApiPlugin } from './vite'

function isFullStatic(options: NuxtConfig) {
return (
Expand Down Expand Up @@ -95,6 +97,20 @@ const compositionApiModule: Module<any> = function compositionApiModule() {
},
})

const entryFile = resolve(this.options.buildDir || '', entryDst)

this.options.build.transpile = this.options.build.transpile || []
this.options.build.transpile.push('@nuxtjs/composition-api')

// Fake alias to prevent shadowing actual node_module
this.options.alias['@nuxtjs/composition-api'] = entryFile

this.nuxt.hook('vite:extend', (ctx: any) => {
ctx.config.plugins.push(compositionApiPlugin())
ctx.config.optimizeDeps.exclude.push('@vue/composition-api')
ctx.config.resolve.alias['~nuxtjs-composition-api'] = entryFile
})

this.options.build = this.options.build || {}
this.options.build.babel = this.options.build.babel || {}

Expand All @@ -107,9 +123,6 @@ const compositionApiModule: Module<any> = function compositionApiModule() {
this.options.build.babel.plugins.push(join(__dirname, 'babel'))
}

this.options.build.transpile = this.options.build.transpile || []
this.options.build.transpile.push(/@nuxtjs[\\/]composition-api/)

const actualPresets = this.options.build.babel.presets

this.options.build.babel.presets = (
Expand All @@ -131,11 +144,6 @@ const compositionApiModule: Module<any> = function compositionApiModule() {
return [[defaultPreset, newOptions]]
}

this.options.alias['@nuxtjs/composition-api'] = resolve(
this.options.buildDir || '',
entryDst
)

this.options.plugins = this.options.plugins || []
this.options.plugins.unshift(resolve(this.options.buildDir || '', pluginDst))
if (
Expand Down
92 changes: 92 additions & 0 deletions src/vite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import crypto from 'crypto'
import MagicString from 'magic-string'
import { walk } from 'estree-walker'
import type { Plugin } from 'rollup'

function createKey(
source: string,
method: crypto.BinaryToTextEncoding = 'base64'
) {
const hash = crypto.createHash('md5')
hash.update(source)
return hash.digest(method).toString()
}

export function compositionApiPlugin(): Plugin & { enforce: 'pre' } {
return {
name: 'nuxt:composition-api',
enforce: 'pre',
transform(code: string, filename: string) {
code = code.replace(
/@nuxtjs[\\/]composition-api/g,
'~nuxtjs-composition-api'
)
const keyedFunctions = /(useStatic|shallowSsrRef|ssrPromise|ssrRef|reqSsrRef|useAsync)/
if (!keyedFunctions.test(code)) {
return {
code,
map: null,
}
}

try {
const { 0: script = code, index: codeIndex = 0 } =
code.match(/(?<=<script[^>]*>)[\S\s.]*?(?=<\/script>)/) || []
const ast = this.parse(script)
const s = new MagicString(code)

walk(ast, {
enter(node) {
const { end } = (node as unknown) as {
end: number
}
const { callee, arguments: args = [] } = node as {
callee?: {
type?: string
name?: string
property?: { type: string; name: string }
}
arguments?: any[]
}
if (
callee?.type === 'Identifier' ||
callee?.property?.type === 'Identifier'
) {
let method: crypto.BinaryToTextEncoding = 'base64'

switch (callee.name || callee.property?.name) {
case 'useStatic':
if (args.length > 2) return
if (args.length === 2) {
s.prependLeft(codeIndex + end - 1, ', undefined')
}
method = 'hex'
break

case 'shallowSsrRef':
case 'ssrPromise':
case 'ssrRef':
case 'reqSsrRef':
case 'useAsync':
if (args.length > 1) return
break

default:
return
}
s.appendLeft(
codeIndex + end - 1,
", '" + createKey(`${filename}-${end}`, method) + "'"
)
}
},
})

return {
code: s.toString(),
map: s.generateMap().toString(),
}
} catch {}
},
}
}

1 comment on commit e47805d

@vercel
Copy link

@vercel vercel bot commented on e47805d Mar 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.