Bring <script setup>
to Vue 2. Works for Vite, Nuxt, Vue CLI, Webpack, esbuild and more, powered by unplugin.
npm i -D unplugin-vue2-script-setup
npm i @vue/composition-api
Install @vue/composition-api
in your App's entry (it enables the setup()
hook):
import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'
Vue.use(VueCompositionAPI)
Vite
// vite.config.ts
import { defineConfig } from 'vite'
import { createVuePlugin as Vue2 } from 'vite-plugin-vue2'
import ScriptSetup from 'unplugin-vue2-script-setup/vite'
export default defineConfig({
plugins: [
Vue2(),
ScriptSetup({ /* options */ }),
],
})
Example: playground/
Nuxt
From v0.28.0 of
@nuxtjs/composition-api
, this plugin is included and enabled out-of-box.
npm i @nuxtjs/composition-api
// nuxt.config.js
export default {
buildModules: [
'@nuxtjs/composition-api/module',
],
scriptSetup: { /* options */ },
}
This module works for both Nuxt 2 and Nuxt Vite
Example: examples/nuxt
Note that <script setup>
could co-exist with <script>
, if you want to define component metadata like layout
or head
for Nuxt, you can do it this way:
<script setup lang="ts">
// your script setup
</script>
<script lang="ts">
// the normal script
export default {
layout: 'user',
// ...other meta
}
</script>
To use TypeScript with Nuxt, install the @nuxtjs/typescript-module
but disable the type check:
npm i -D @nuxt/typescript-build vue-tsc
// nuxt.config.js
export default {
buildModules: [
['@nuxt/typescript-build', { typeCheck: false }],
'@nuxtjs/composition-api/module',
'unplugin-vue2-script-setup/nuxt',
],
}
And then use vue-tsc
to do the type check at build time:
// package.json
{
"scripts": {
"dev": "nuxt",
"build": "vue-tsc --noEmit && nuxt build"
}
}
Vue CLI
// vue.config.js
module.exports = {
parallel: false, // disable thread-loader, which is not compactible with this plugin
configureWebpack: {
plugins: [
require('unplugin-vue2-script-setup/webpack')({ /* options */ }),
],
},
}
Example: examples/vue-cli
To use TypeScript with Vue CLI, install @vue/cli-plugin-typescript
but disable the type check:
npm i -D @vue/cli-plugin-typescript vue-tsc
module.exports = {
parallel: false,
configureWebpack: {
plugins: [
require('unplugin-vue2-script-setup/webpack')({ /* options */ }),
],
},
chainWebpack(config) {
// disable type check and let `vue-tsc` handles it
config.plugins.delete('fork-ts-checker')
},
}
And then use vue-tsc
to do the type check at build time:
// package.json
{
"scripts": {
"dev": "vue-cli-service serve",
"build": "vue-tsc --noEmit && vue-cli-service build"
}
}
Webpack
// webpack.config.js
module.exports = {
/* ... */
plugins: [
require('unplugin-vue2-script-setup/webpack')({ /* options */ }),
]
}
Rollup
// rollup.config.js
import Vue from 'rollup-plugin-vue'
import ScriptSetup from 'unplugin-vue2-script-setup/rollup'
export default {
plugins: [
Vue(),
ScriptSetup({ /* options */ }),
]
}
esbuild
// esbuild.config.js
import { build } from 'esbuild'
build({
/* ... */
plugins: [
require('unplugin-vue2-script-setup/esbuild')({
/* options */
}),
],
})
Jest
npm i -D vue-jest
// jest.config.js
module.exports = {
transform: {
'.*\\.(vue)$': 'unplugin-vue2-script-setup/jest',
},
}
JavaScript API
import { transform } from 'unplugin-vue2-script-setup'
const Vue2SFC = transform(`
<template>
<!-- ... -->
</template>
<script setup>
// ...
</script>
`)
We recommend using VS Code with Volar to get the best experience (You might want to disable Vetur if you have it).
When using Volar, you need to install @vue/runtime-dom
as devDependencies to make it work on Vue 2.
npm i -D @vue/runtime-dom
If the global types are missing for your IDE, update your tsconfig.json
with:
{
"compilerOptions": {
"types": [
"unplugin-vue2-script-setup/types"
]
}
}
Volar preferentially supports Vue 3. Vue 3 and Vue 2 template has some different. You need to set the experimentalCompatMode
option to support Vue 2 template.
{
"compilerOptions": {
...
},
"vueCompilerOptions": {
"experimentalCompatMode": 2
},
}
If you are using ESLint, you might get @typescript-eslint/no-unused-vars
warning with <script setup>
. You can disable it and add noUnusedLocals: true
in your tsconfig.json
, Volar will infer the real missing locals correctly for you.
Ref Sugar (take 2)
In v0.5.x, we shipped the experimental Ref Sugar (take 2) implementation based on Vue 3's @vue/reactivity-transform
package. Notice the syntax is not settled yet and might be changed in the future updates. Use at your own risk!
To enabled it, pass the option:
ScriptSetup({
reactivityTransform: true
})
To get TypeScript support, update your tsconfig.json
with:
{
"compilerOptions": {
"types": [
"unplugin-vue2-script-setup/types",
"unplugin-vue2-script-setup/ref-macros"
]
}
}
If you enjoy using <script setup>
, you might also want to try unplugin-auto-import
to improve the DX even further.
- PoC
- Components registration
- Compile time macros
defineProps
defineEmits
withDefaults
- Global types
- Merge with normal scripts
- Ref Sugar (take 2)
-
<template lang="pug">
support - Vite plugin
- Webpack plugin
- Nuxt module
-
Top-level await(not supported)
👀
It's made possible by transforming the <script setup>
syntax back to normal <script>
and let the Vue 2 SFC compiler handle the rest.
MIT License © 2021 Anthony Fu