Skip to content
This repository has been archived by the owner on Dec 5, 2024. It is now read-only.

feat: experimental vite support #387

Merged
merged 21 commits into from
Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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) {
danielroe marked this conversation as resolved.
Show resolved Hide resolved
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>)/) || []
danielroe marked this conversation as resolved.
Show resolved Hide resolved
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 {}
},
}
}