unplugin / unplugin-vue2-script-setup Goto Github PK
View Code? Open in Web Editor NEW💡 Bring `<script setup>` to Vue 2.
License: MIT License
💡 Bring `<script setup>` to Vue 2.
License: MIT License
<template>
<div>{{ b + c }}</div>
</template>
<script setup lang="ts">
import { ref } from "@vue/composition-api";
const b = ref(5);
</script>
<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
@Component({})
export default class extends Vue {
c = "abc";
}
</script>
<style></style>
Hello, how would someone deal with unused vars?
buildModules: [
'@nuxt/typescript-build',
'@nuxtjs/vuetify',
'@nuxtjs/composition-api/module',
'nuxt-typed-vuex',
'vue2-script-setup-transform/nuxt',
],
Already restarted vs code and I'm using volar extension
tsconfig.json is same as the example
Hi!
version: plugin v0.5.6 - nuxt 2.15.8
When use typescript in project i usually use enum
as safe way to store config values. With composition api setup function we can do like this without issue:
When use script setup , editor still accept write enum and pass to template, but in runtime it not actually foward enum to template :
can we update this part to accept enum as normal static plain object in template.
Thank you!
Hi!
I'm using plugin v0.5.4 in Nuxt. with simple component use both defineProps
and defineEmits
i see type checking report error:
normal, when only use defineProps
component checking ok:
when add defineEmis
, all props reference in template lost:
This error only happend with type checking, runtime still work.
Thankyou!
Thank you for bringing refSugar take2 support
I'm having some problems after upgrading to 0.5.0
Only after upgrading the version I get this error
Uncaught ReferenceError: defineProps is not defined
After using refTransform: true
and the $ref
syntax, I get this error
Uncaught ReferenceError: $ref is not defined
at Object.../../node_modules/babel-loader/lib/index.js??clonedRuleSet-1[0].rules[0].use[0]!../../node_modules/vue-loader/lib/index.js??vue-loader-options!../../node_modules/unplugin/dist/webpack/loaders/transform.cjs??ruleSet[1].rules[11].use[0]!./src/js/components/new.vue?vue&type=script&lang=js&
error in ./src/js/components/new.vue?vue&type=script&lang=js&
Module Error (from ../../node_modules/unplugin/dist/webpack/loaders/transform.cjs):
This experimental syntax requires enabling one of the following parser plugin(s): 'jsx, flow, typescript' (1:0)
import Vue from 'vue';
import App from './App';
import VueCompositionAPI from '@vue/composition-api'
Vue.use(VueCompositionAPI)
new Vue({
el: '#app',
render: (h) => h(App),
});
<template>
<div @click="click">{{ message }} {{prop}}</div>
</template>
<script setup>
// import { ref } from '@vue/composition-api';
//
// const props = defineProps({
// prop: {
// type: String,
// default: 'defaultProp'
// }
// })
let message = $ref('新的方式编写组件');
const click = () => {
console.log('新的方式编写组件事件')
}
</script>
<style scoped>
</style>
// 使用 webpack-chain
compiler.context.chain
.plugin('Vue2ScriptSetup')
.after('DefinePlugin')
.use(Vue2ScriptSetupPlugin({
refTransform: true,
}))
.end();
This does not work:
<script setup lang="ts">
const HelloWorld = () => import('./HelloWorld.vue')
</script>
unplugin-vue2-script-setup
does not hoist async import up and you get runtime error Uncaught ReferenceError: HelloWorld is not defined
.
Possible solutions:
const Component = () => import()
defineAsyncComponent
macrounplugin-auto-import
)script-setup
for example) that exports defineAsyncComponent
@antfu, what solution do you prefer? I'm not sure if 3 or 4 is better.
https://github.com/Demivan/unplugin-vue2-script-setup here I created basic implementation of solution 4.
This may be a duplication of #53 but when using the typescript variation of defineProps both vscode/volar and Vue's prop validation seem to have issues.
Steps to reproduce:
name
prop to nameTest
since it seems name is a reserved variable of some kind.Note that everything runs ok still, Volar just seems to complain along with the Vue console errors.
If you change the defineProps
syntax back to javascript things all work as expected.
因为现在设置name需要在写好几行代码,有没有办法可以直接在script 上加个name属性
Hi!
To day i tried implement plugin (v.0.5.4) into my nuxt project. i found a bug:
Follow plugin's readme instruction we had support defineProps
.
Follow Vue 3 script setup frc about typescript user, we can define props in component like:
const props = defineProps<{
foo: string
bar?: number
}>()
This example work with plugin , but when i try define prop with custom type:
// custom type
export interface DocVersion {
version: number
}
// component
<script lang="ts" setup>
import { DocVersion } from '~/lib/doc/Doc'
const props = defineProps<{ version?: DocVersion }>()
</script>
<template>
<div>
{{ version }}
</div>
</template>
i got error message on runtime:
[Vue warn]: Invalid prop type: "null" is not a constructor
After research vue3 rfc's document above i found that:
"In dev mode, the compiler will try to infer corresponding runtime validation from the types. For example here foo: String is inferred from the foo: string type. If the type is a reference to an imported type, the inferred result will be foo: null (equal to any type) since the compiler does not have information of external files."
In vue 2 env, { typeName: { type: null } }
is not a valid format. Component still working on runtime but error thown out.
Can we have any workaround for now?
Many thank for your plugin!
Trung.
Update:
I think for now, before smart authors update a fix, we can workaround by:
set Vue.config.silent = true to disable all warning. This will disable warning about type:null is not a constructor. Component still working ok in runtime.
My suggest to fix plugin is:
Plugin should compile defienProps + custom type to type:Null
or type: Object
. this will more correct and avoid mismatch.
update 2
Look like we also can bypass error like this:
const props = defineProps<{ version?: {} & DocVersion }>()
Thankyou!
When there is a problem in code, the webpack dev server will directly report an error and exit.
node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:798
const err = new SyntaxError(message);
^
SyntaxError: Unexpected token (1:5)
at Parser._raise (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:798:17)
at Parser.raiseWithData (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:791:17)
at Parser.raise (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:752:17)
at Parser.unexpected (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:3257:16)
at Parser.parseIdentifierName (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:12362:18)
at Parser.parseIdentifier (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:12340:23)
at Parser.parseMember (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:11140:103)
at Parser.parseSubscript (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:11127:19)
at Parser.parseSubscripts (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:11098:19)
at Parser.parseExprSubscripts (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:11087:17)
at Parser.parseUpdate (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:11061:21)
at Parser.parseMaybeUnary (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:11039:23)
at Parser.parseExprOps (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:10882:23)
at Parser.parseMaybeConditional (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:10856:23)
at Parser.parseMaybeAssign (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:10814:21)
at node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:10776:39 {
loc: Position { line: 1, column: 5 },
pos: 5,
code: 'BABEL_PARSER_SYNTAX_ERROR',
reasonCode: 'UnexpectedToken'
}
ERROR Command failed with exit code 1.
// vue.config.js
const ScriptSetup = require("vue2-script-setup-transform/webpack-plugin").default;
/**
* @type {import('@vue/cli-service').ProjectOptions}
*/
module.exports = {
configureWebpack: {
plugins: [ScriptSetup()],
},
};
Error:
****/node_modules/unplugin/dist/webpack/loaders/transform.cjs:7
const plugin = (_a = this._compiler) == null ? void 0 : _a.$unpluginContext[unpluginName];
^
TypeError: Cannot read property 'vue2-script-setup-transform' of undefined
at Object.transform (****/node_modules/unplugin/dist/webpack/loaders/transform.cjs:7:78)
at LOADER_EXECUTION (****/node_modules/loader-runner/lib/LoaderRunner.js:132:14)
at runSyncOrAsync (****/node_modules/loader-runner/lib/LoaderRunner.js:133:4)
at iterateNormalLoaders (****/node_modules/loader-runner/lib/LoaderRunner.js:250:2)
at ****/node_modules/loader-runner/lib/LoaderRunner.js:223:4
at ****/node_modules/webpack/lib/NormalModule.js:797:16
at Hook.eval [as callAsync] (eval at create (****/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:16:1)
at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (****/node_modules/tapable/lib/Hook.js:18:14)
at Object.processResource (****/node_modules/webpack/lib/NormalModule.js:792:9)
at processResource (****/node_modules/loader-runner/lib/LoaderRunner.js:220:11)
at iteratePitchingLoaders (****/node_modules/loader-runner/lib/LoaderRunner.js:171:10)
at iteratePitchingLoaders (****/node_modules/loader-runner/lib/LoaderRunner.js:178:10)
at ****/node_modules/loader-runner/lib/LoaderRunner.js:189:18
at handleResult (****/node_modules/loader-runner/lib/loadLoader.js:53:2)
at loadLoader (****/node_modules/loader-runner/lib/loadLoader.js:35:10)
at iteratePitchingLoaders (****/node_modules/loader-runner/lib/LoaderRunner.js:182:2)
不是使用vue-cli,而是用webpack5搭建的,单独使用composition-api是没有问题的,引入
unplugin-vue2-script-setup之后,就无法正常使用了。
If possible: please provide example in README.md
Otherwise: how can we support it?
I like this plugin, great idea!!!
Here are my doubts:
if script don't has attribute lang="js"
then get an error
[plugin:vue2-script-setup-transform] Unsupported script language: undefined
add to fix it, is something miss in document or just a bug?
The point of the error code:
if (lang === 'ts')
plugins.push('typescript')
else if (lang === 'jsx')
plugins.push('jsx')
else if (lang === 'tsx')
plugins.push('typescript', 'jsx')
else if (lang !== 'js')
throw new SyntaxError(`Unsupported script language: ${lang}`)
source code:
<template>
<div>
<h1>{{ msg }}</h1>
</div>
</template>
<script setup>
import { ref } from "@vue/composition-api";
const msg = ref("bar")
</script>
<style></style>
Wouldn't it be easy to parse the macro and add the ObjectProperties to the return value of the setup function? Or would that be different from Vue 3 in some way?
<template>
<div></div>
</template>
<script lang="ts" setup>
import { PropType } from '@vue/composition-api'
const props = defineProps({
value: {
type: Object as PropType<Record<string, boolean>>,
},
})
type Value = typeof props.value
// type Value = {
// type: PropType<Record<string, boolean>>;
// } | undefined
console.log(props.any)
// 类型“Readonly<{ value?: unknown; } & {} & { value?: { type: PropType<Record<string, boolean>>; } | undefined; }>”上不存在属性“any”。ts(2339)
</script>
it's my vue.config.js code:
when i start my project
but get a Error: TypeError: SetupPlugin is not a function
const SetupPlugin = require('vue2-script-setup-transform')
module.exports = {
configureWebpack: {
plugins: [
SetupPlugin()
]
}
}
<Page
@on-Change="(value) => {queryCurrentFunc(value, query)}"
:total="pages.total"
:page-size="pages.limit"
:page-size-opts="[10, 20, 50]"
@on-page-size-change="(value) => {queryLimitFunc(value, query)}"
:current="pages.current"
placement="top"
show-total show-sizer />
this callback('queryCurrentFunc', 'queryLimitFunc') is undefined but I defined it; callback can't compile
Options like {refTransform: true}
do not get passed through in Nuxt.
The fix is something like:
export default function(this: any, moduleOptions: any) { // added moduleOptions here
// install webpack plugin
this.extendBuild((config: any) => {
config.plugins = config.plugins || []
config.plugins.unshift(unplugin.webpack(moduleOptions))
})
// install vite plugin
this.nuxt.hook('vite:extend', async(vite: any) => {
vite.config.plugins = vite.config.plugins || []
vite.config.plugins.push(unplugin.vite(moduleOptions))
})
}
I got the ref sugar option working locally on my own project by manually editing node_modules/unplugin-vue2-script-setup/dist/nuxt.js
with something corresponding to the above. So I know the above solution is roughly in the right area!
I'd submit a PR here to fix this, but I couldn't get the nuxt example running correctly with npm -C examples/nuxt run dev
so I couldn't properly test out any changes - I get the error: export 'default' (imported as 'mod') was not found
.
Hope the above is enough to help!
I directly enabled the project in the examples>vue-cli directory, but found that ScriptSetup is not a function. I installed [email protected].
vue.config.js
/* eslint-disable @typescript-eslint/no-var-requires */
const ScriptSetup = require('unplugin-vue2-script-setup/webpack').default
/**
* @type {import('@vue/cli-service').ProjectOptions}
*/
module.exports = {
configureWebpack: {
plugins: [
ScriptSetup({
refTransform: true,
}),
],
},
chainWebpack(config) {
// disable type check and let `vue-tsc` handles it
config.plugins.delete('fork-ts-checker')
// disable cache for testing, you should remove this in production
config.module.rule('vue').uses.delete('cache-loader')
config.module.rule('js').uses.delete('cache-loader')
config.module.rule('ts').uses.delete('cache-loader')
config.module.rule('tsx').uses.delete('cache-loader')
},
}
vue.config.js
/* eslint-disable @typescript-eslint/no-var-requires */
const ScriptSetup = require('unplugin-vue2-script-setup/webpack');
/**
* @type {import('@vue/cli-service').ProjectOptions}
*/
module.exports = {
configureWebpack: {
plugins: [
ScriptSetup({
refTransform: true,
}),
],
},
chainWebpack(config) {
// disable type check and let `vue-tsc` handles it
config.plugins.delete('fork-ts-checker')
// disable cache for testing, you should remove this in production
config.module.rule('vue').uses.delete('cache-loader')
config.module.rule('js').uses.delete('cache-loader')
config.module.rule('ts').uses.delete('cache-loader')
config.module.rule('tsx').uses.delete('cache-loader')
},
}
Yes, I simply delete a default.
This plugin is great, but I get some errors when use eslint.
11:78 error Extra semicolon semi
12:7 error Identifier '__sfc_main' is not in camel case camelcase
12:22 error Extra semicolon semi
15:12 error Extra semicolon semi
16:2 error Extra semicolon semi
20:26 error Extra semicolon semi
21:16 error Identifier '__sfc_main' is not in camel case camelcase
21:26 error Extra semicolon semi
✖ 8 problems (8 errors, 0 warnings)
6 errors and 0 warnings potentially fixable with the `--fix` option.
I found that extend @vue/standard
will cause these errors, but I need its rules, such as no semi, camelcase naming, etc.
Is there any good suggestion to solve it?
This is my .eslintrc.js
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/essential',
'@vue/standard',
'@vue/typescript'
],
plugins: [
'vue'
],
rules: {
'import/prefer-default-export': 'off',
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
// 超过两个属性以上的元素必须换行
'vue/max-attributes-per-line': ['error', {
'singleline': 2,
'multiline': {
'max': 1,
'allowFirstLine': false
}
}],
// html 2空格缩进
'vue/html-indent': ['error', 2, {
'attribute': 1,
'baseIndent': 1,
'closeBracket': 0,
'alignAttributesVertically': true,
'ignores': []
}],
// 禁止注册模板内未使用的组件
'vue/no-unused-components': ['error', {
'ignoreWhenBindingPresent': true
}],
// computed必须有返回值
'vue/return-in-computed-property': ['error', {
'treatUndefinedAsUnspecified': true
}],
// 强制在Vue模板中的自定义组件上使用带连字符'-'的属性名称
'vue/attribute-hyphenation': ['error', 'always', {
'ignore': []
}],
// 不允许'>'单独成行
'vue/html-closing-bracket-newline': ['error', {
'singleline': 'never',
'multiline': 'never'
}],
// 闭标签之前有一个空格
'vue/html-closing-bracket-spacing': ['error', {
'startTag': 'never',
'endTag': 'never',
'selfClosingTag': 'always'
}],
// HTML属性强制为双引号
'vue/html-quotes': ['error', 'double'],
// 标签中间没有内容使用闭标签
'vue/html-self-closing': ['error', {
'html': {
'void': 'never',
'normal': 'always',
'component': 'always'
},
'svg': 'always',
'math': 'always'
}],
// 双括号与表达式之间有且只有一个空格
'vue/mustache-interpolation-spacing': ['error', 'always'],
// 组件name、定义必须为PascalCase(全驼峰)
'vue/name-property-casing': ['error', 'PascalCase'],
// 组件内属性强制使用驼峰命名
'vue/prop-name-casing': ['error', 'camelCase'],
// 强制使用:而不是v-bing
'vue/v-bind-style': ['error', 'shorthand'],
// 强制使用@ 而不是v-on
'vue/v-on-style': ['error', 'shorthand'],
// 支持可选链(?.)操作符
'vue/no-parsing-error': [2, { 'x-invalid-end-tag': false }],
'no-use-before-define': 0,
'vue/script-setup-uses-vars': 'error'
},
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaVersion: 2020
},
globals: {
defineProps: 'readonly',
defineEmits: 'readonly',
defineExpose: 'readonly',
withDefaults: 'readonly'
}
}
My package.json
"dependencies": {
"@vueuse/core": "^4.11.0",
"apexcharts": "^3.26.1",
"axios": "^0.19.0",
"core-js": "^3.4.3",
"echarts": "^4.7.0",
"element-ui": "^2.13.2",
"js-cookie": "^2.2.1",
"nunjucks": "^3.2.3",
"sortablejs": "^1.12.0",
"vcrontab": "^0.3.5",
"vue": "^2.6.10",
"vue-apexcharts": "^1.6.1",
"vue-class-component": "^7.0.2",
"vue-clipboard2": "^0.3.1",
"vue-codemirror": "^4.0.6",
"vue-echarts": "^5.0.0-beta.0",
"vue-property-decorator": "^8.3.0",
"vue-router": "^3.1.3",
"vuex": "^3.1.2",
"vuex-class": "^0.3.2"
},
"devDependencies": {
"@babel/plugin-proposal-optional-chaining": "^7.14.2",
"@commitlint/cli": "^8.2.0",
"@commitlint/config-conventional": "^8.2.0",
"@types/jest": "23.3.1",
"@types/lodash": "^4.14.149",
"@types/nunjucks": "^3.1.4",
"@types/qs": "^6.9.0",
"@typescript-eslint/eslint-plugin": "^4.22.0",
"@typescript-eslint/parser": "^4.22.0",
"@vue/cli-plugin-babel": "^4.1.0",
"@vue/cli-plugin-eslint": "^4.1.0",
"@vue/cli-plugin-typescript": "^4.1.0",
"@vue/cli-service": "^4.1.0",
"@vue/composition-api": "^1.1.4",
"@vue/eslint-config-standard": "^4.0.0",
"@vue/eslint-config-typescript": "^4.0.0",
"@vue/test-utils": "1.0.0-beta.24",
"babel-preset-env": "1.7.0",
"commitizen": "^4.0.3",
"cross-env": "^6.0.3",
"cz-conventional-changelog": "^3.0.2",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^7.17.0",
"jest": "23.5.0",
"lint-staged": "^9.4.3",
"lodash": "^4.17.15",
"node-sass": "^4.12.0",
"qs": "^6.9.1",
"sass-loader": "^8.0.0",
"stylelint": "^12.0.0",
"stylelint-config-standard": "^19.0.0",
"stylelint-webpack-plugin": "^1.1.2",
"ts-jest": "23.1.3",
"typescript": "^3.7.7",
"unplugin-vue2-script-setup": "^0.5.8",
"vue-jest": "2.6.0",
"vue-template-compiler": "^2.6.10"
},
In <script setup> declare a variable, if not initialization can cause compilation exceptions,
**Module Error (from ./node_modules/unplugin-vue2-script-setup/node_modules/unplugin/dist/webpack/loaders/transform.js):
Cannot read property 'callee' of null
**
`<script setup>
defineProps(["msg"]);
let s;
// let s = 2;
</script>`
unplugin-vue2-script-setup": 0.6.7
@vue/composition-api: 1.1.0,
vue: ^2.6.14
webpack": "^5.50.0
Hi!
In plugin's readme for now we missing note about setup compact mode for project to merge type checking template.
For now, after setup plugin and volar (vscode ext). when write template tag + v-for, it force to put key on same template tag:
This because volar checking follow Vue3 guide. In Vue2 key must apply to all child tags of <template />
tag, not itself.
To avoid this issue in Volar's document they has compact mode:
// tsconfig.json
{
"compilerOptions": {
...
},
"vueCompilerOptions": {
"experimentalCompatMode": 2
},
}
Im has not experience to creating PR on git, what i can do is raise issue and count of you guys :) . Hope my info i usefull.
Thank for plugin!
In version v0.6.2 default exports stopped working in Webpack. Most likely in other tools too.
This does not work now:
// webpack.config.js
module.exports = {
/* ... */
plugins: [
require('unplugin-vue2-script-setup/webpack')({ /* options */ }),
]
}
You need to write:
// webpack.config.js
module.exports = {
/* ... */
plugins: [
require('unplugin-vue2-script-setup/webpack').default({ /* options */ }),
]
}
It is related to tsup
update to version 5.0.0
tsup
does not code-split cjs format now. And scripts/postbuild.ts
performs an incorrect transformation as output files after build are different.
Before I start using this interesting module - do I have to rewrite all of my components to composition api ?
Or can I have just some components with composition api and leave some components with their existing v2 options api ?
And if I go for Typescript for my new components - can my old components still use .js even in the same application ?
I am using vue-cli by the way.
BR.
When running:
# nuxt build
$ npm run build
On my project (with node v16.11.0) I'm getting the following error:
ERROR Cannot find module '@antfu/utils' 18:29:49
Require stack:
- /Users/naquiroz/Documents/project/node_modules/unplugin-vue2-script-setup/dist/chunk-54VX22Y6.js
Package log
{
"name": "classified",
"private": true,
"version": "0.1.0",
"license": "UNLICENSED",
"scripts": {
"build": "nuxt build",
"cypress": "cypress open",
"dev": "nuxt",
"generate": "nuxt generate",
"start": "nuxt start",
"test": "cypress run -b chrome --headless",
"getversion": "node -p \"require('./package.json').version\""
},
"dependencies": {
"@auth0/auth0-spa-js": "^1.18.0",
"@vue/composition-api": "^1.2.2",
"cookie-universal-nuxt": "^2.1.5",
"graphql": "^15.6.0",
"graphql-request": "^3.5.0",
"jsonwebtoken": "^8.5.1",
"nuxt": "^2.14.12"
},
"devDependencies": {
"@antfu/utils": "^0.3.0",
"@cypress/code-coverage": "^3.9.2",
"@nuxtjs/composition-api": "^0.29.2",
"@nuxtjs/eslint-config": "^6.0.1",
"@nuxtjs/eslint-module": "^3.0.2",
"@nuxtjs/svg": "^0.3.0",
"@nuxtjs/vuetify": "^1.11.3",
"babel-eslint": "^10.1.0",
"babel-plugin-istanbul": "^6.0.0",
"cypress": "^8.5.0",
"cypress-file-upload": "^5.0.8",
"eslint": "^7.20.0",
"eslint-plugin-cypress": "^2.11.2",
"eslint-plugin-nuxt": "^2.0.0",
"eslint-plugin-vue": "^7.19.1",
"stylelint": "^13.13.1",
"stylelint-config-standard": "^22.0.0"
},
"repository": {
"type": "git",
"url": "classified"
},
"publishConfig": {
"access": "restricted"
},
"release": {
"branches": [
"stable",
{
"name": "main",
"prerelease": true
}
]
},
"nyc": {
"reporter": [
"html"
]
}
}
when i use this plugin in vue-cli, it will throw some warnings like
- example.vue
warning Replace `;` with `cr` prettier/prettier
this means plugin compiles before eslint, so there are lots of unexpected warnings.
is there any solution can fix this ?
<template>
- <div>
+ <div :style="{ 'text-align': 'right' }">
<hello-world name="Vue 2" @update="onUpdate" />
</div>
</template>
<script setup lang="ts">
import HelloWorld from './HelloWorld.vue'
function onUpdate(e: any) {
console.log(e)
}
</script>
Error:
● transform › App.vue
SyntaxError: Missing semicolon. (1:14)
at Parser._raise (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/error.js:134:45)
at Parser.raiseWithData (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/error.js:129:17)
at Parser.raise (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/error.js:78:17)
at Parser.semicolon (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/util.js:137:10)
at Parser.parseExpressionStatement (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.js:891:10)
at Parser.parseStatementContent (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.js:375:19)
at Parser.parseStatement (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.js:230:17)
at Parser.parseBlockOrModuleBlockBody (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.js:966:25)
at Parser.parseBlockBody (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.js:942:10)
at Parser.parseBlock (node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.js:912:10)
reproduce repo: https://github.com/sxzz/vue2-script-setup-issue
Issues checking in progress...
ERROR in src/main.ts:3:8
TS1192: Module '"/Users/kevin/projects/vue2-lab/src/App.vue"' has no default export.
1 | import Vue from "vue";
2 | import VueCompositionAPI from "@vue/composition-api";
> 3 | import App from "./App.vue";
| ^^^
4 |
5 | Vue.config.productionTip = false;
6 |
https://github.com/JaxXu/sugartake2try
ERROR Failed to compile with 1 error 7:28:01 PM
error in ./src/js/App.vue?vue&type=script&lang=js&
Syntax Error: Identifier '__sfc_main' has already been declared. (19:6)
17 | Old
18 | }, __sfc_main.components);
> 19 | const __sfc_main = __sfc_main;
| ^
20 | export default __sfc_main;
21 |
This bug recurs when placing the Vue2ScriptSetupPlugin
plugin in front of the VueLoaderPlugin
, Maybe some additional documentation is needed
But the above case is not a percentage recurrence, you remove the /* unlock comment */
from App.vue and the error will not be reported. Is this also a bug? As far as I can see, when transformScriptSetup is processed, the problem is that the ParsedSFC object does not contain scriptSetup but script
=============== ↓ ↓ ↓ ↓ ↓ ↓ ↓ transformScriptSetup.sfc ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ==================
{
id: '/Users/xuyihao/Documents/GitHub.nosync/webpack5/packages/dev/src/js/App.vue?vue&type=script&lang=js&',
template: {
components: Set(2) { 'New', 'Old' },
identifiers: Set(2) { 'readersNumber', 'add' }
},
scriptSetup: {
start: 0,
end: 0,
contentStart: 0,
contentEnd: 0,
content: '',
attrs: {},
found: false,
ast: Node {
type: 'Program',
start: 0,
end: 0,
loc: [SourceLocation],
sourceType: 'module',
interpreter: null,
body: [],
directives: []
}
},
script: {
start: 273,
end: 644,
contentStart: 282,
contentEnd: 635,
content: '\n' +
"import New from './components/new';\n" +
"import Old from './components/old'; // let readersNumber = $ref(0);\n" +
'//\n' +
'// const add = () => {\n' +
'// readersNumber += 1;\n' +
'// }\n' +
'\n' +
'const __sfc_main = {};\n' +
'\n' +
'__sfc_main.setup = (__props, __ctx) => {\n' +
' return {};\n' +
'};\n' +
'\n' +
'__sfc_main.components = Object.assign({\n' +
' New,\n' +
' Old\n' +
'}, __sfc_main.components);\n' +
'export default __sfc_main;\n',
attrs: {},
found: true,
ast: Node {
type: 'Program',
start: 0,
end: 353,
loc: [SourceLocation],
sourceType: 'module',
interpreter: null,
body: [Array],
directives: []
}
},
parserOptions: { sourceType: 'module', plugins: [] },
extraDeclarations: []
}
=============== ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ generate(ast).code ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ==================
import New from './components/new';
import Old from './components/old'; // let readersNumber = $ref(0);
//
// const add = () => {
// readersNumber += 1;
// }
const __sfc_main = {};
__sfc_main.setup = (__props, __ctx) => {
return {};
};
__sfc_main.components = Object.assign({
New,
Old
}, __sfc_main.components);
const __sfc_main = __sfc_main;
export default __sfc_main;
=============== ↓ ↓ ↓ ↓ ↓ ↓ ↓ transformScriptSetup.sfc ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ==================
{
id: '/Users/xuyihao/Documents/GitHub.nosync/webpack5/packages/dev/src/js/App.vue?vue&type=script&lang=js&',
template: {
components: Set(2) { 'New', 'Old' },
identifiers: Set(2) { 'readersNumber', 'add' }
},
scriptSetup: {
start: 273,
end: 460,
contentStart: 287,
contentEnd: 451,
content: '\n' +
"import New from './components/new';\n" +
"import Old from './components/old';\n" +
'\n' +
'// let readersNumber = $ref(0);\n' +
'//\n' +
'// const add = () => {\n' +
'// readersNumber += 1;\n' +
'// }\n',
attrs: { setup: '' },
found: true,
ast: Node {
type: 'Program',
start: 0,
end: 164,
loc: [SourceLocation],
sourceType: 'module',
interpreter: null,
body: [Array],
directives: []
}
},
script: {
start: 0,
end: 0,
contentStart: 0,
contentEnd: 0,
content: '',
attrs: {},
found: false,
ast: Node {
type: 'Program',
start: 0,
end: 0,
loc: [SourceLocation],
sourceType: 'module',
interpreter: null,
body: [],
directives: []
}
},
parserOptions: { sourceType: 'module', plugins: [] },
extraDeclarations: []
}
=============== ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ generate(ast).code ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ==================
import New from './components/new';
import Old from './components/old'; // let readersNumber = $ref(0);
//
// const add = () => {
// readersNumber += 1;
// }
const __sfc_main = {};
__sfc_main.setup = (__props, __ctx) => {
return {};
};
__sfc_main.components = Object.assign({
New,
Old
}, __sfc_main.components);
export default __sfc_main;
============
Hi, I've just setup script setup in vue2 using this package. I'm noticing Typescript doesn't unpack the setup defined refs in the template, giving my this error:
The code works fine even with the error. Did I forgot to do something?
I followed all the steps in the README. I am using Volar and this is my current tsconfig.json:
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"noUnusedLocals": true,
"types": ["vite/client", "vuetify"],
"typeRoots": [
"./node_modules/@types",
"./node_modules/vuetify/types",
"./node_modules/vite/types",
"./node_modules/unplugin-vue2-script-setup/types"
],
},
"vueCompilerOptions": {
"experimentalCompatMode": 2
},
"include": [
"resources/vue/src/**/*.ts",
"resources/vue/src/**/*.d.ts",
"resources/vue/src/**/*.tsx",
"resources/vue/src/**/*.vue"
]
}
The nuxt.config.js
file in the Nuxt example adds 'unplugin-vue2-script-setup/nuxt'
in the modules:
This should not be necessary because it is automatically added:
// vue.config.js
module.exports = {
configureWebpack: {
plugins: [
require('unplugin-vue2-script-setup/webpack')({ /* options */ }),
],
},
}
linux => npm run build:sit
Error: Cannot find module 'unplugin-vue2-script-setup/webpack'
Looking through the code, I found these both lines:
I think we can rewrite them to only loop once through everything, potentially resulting in a little performance boost 🤔
const imports = []
const nodes = []
scriptSetupAst.program.body.forEach(n => {
if (n.type === 'ImportDeclaration') {
imports.push(n)
} else {
nodes.push(n)
}
})
Hello, I encountered a problem when using Vue-cli to package into the production environment: Cannot set properties of undefined (setting'render').
The following are my few file configurations:
package.json
{
"name": "vue-cli",
"private": true,
"scripts": {
"dev": "vue-cli-service serve",
"build": "vue-tsc --noEmit && vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@vue/composition-api": "^1.2.4",
"core-js": "^3.16.4",
"vue": "^2.6.11"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.5.13",
"@vue/cli-plugin-typescript": "^4.5.13",
"@vue/cli-service": "^4.5.13",
"typescript": "^4.4.2",
"unplugin-vue2-script-setup": "workspace:*",
"vue-template-compiler": "^2.6.14",
"vue-tsc": "^0.3.0"
}
}
vue.config.js
/* eslint-disable @typescript-eslint/no-var-requires */
const ScriptSetup = require('unplugin-vue2-script-setup/webpack')
/**
* @type {import('@vue/cli-service').ProjectOptions}
*/
module.exports = {
configureWebpack: {
plugins: [
ScriptSetup({
refTransform: true,
}),
],
},
chainWebpack(config) {
// disable type check and let `vue-tsc` handles it
config.plugins.delete('fork-ts-checker')
// disable cache for testing, you should remove this in production
config.module.rule('vue').uses.delete('cache-loader')
config.module.rule('js').uses.delete('cache-loader')
config.module.rule('ts').uses.delete('cache-loader')
config.module.rule('tsx').uses.delete('cache-loader')
},
}
First of all--thank you SO much. I've been hoping one of the core Vue members would backport script setup to Vue 2.
The only adoption concern I have left after reading the readme is whether this will break my jest tests. I guess it wouldn't be too hard for me to write a basic jest transform using the JavaScript API. But I wasn't sure whether that would play nicely with vue-jest
. Any thoughts on this.
In my project I have a computed property, let's say x
which is an integer.
When I bind it inside a style in the template, like this
<template>
<div :style="{ left: `${x}px` }">Hello</div>
</template>
the style tag is blank on the rendered output.
But if I use it inside moustache syntax, like this
<template>
<div :style="{ left: `${x}px` }">{{ x }}</div>
</template>
it works. The style is populated and the content is also displayed.
Is there some specific edge case that only affects the style
attribute?
As you probably know, in @nuxtjs/composition-api
you must add an empty head: {}
to use the useMeta
composition function.
Maybe it's going over my head but, is there any way at the moment to do this with <script setup>
?
Created a project with @vue/cli 4.5.12
, and then import this plugin followed by the readme.
after everything has been done, I run npm run serve
, and shows the following error.
vue.runtime.esm.js?2b0e:619 [Vue warn]: Property or method "counter" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
found in
---> <Home> at src/views/Home.vue
<App> at src/App.vue
<Root>
warn @ vue.runtime.esm.js?2b0e:619
warnNonPresent @ vue.runtime.esm.js?2b0e:2024
get @ vue.runtime.esm.js?2b0e:2079
render @ Home.vue?b723:5
eval @ vue-composition-api.esm.js?a6f4:1810
activateCurrentInstance @ vue-composition-api.esm.js?a6f4:1765
$options.render @ vue-composition-api.esm.js?a6f4:1809
Vue._render @ vue.runtime.esm.js?2b0e:3569
updateComponent @ vue.runtime.esm.js?2b0e:4081
get @ vue.runtime.esm.js?2b0e:4495
Watcher @ vue.runtime.esm.js?2b0e:4484
mountComponent @ vue.runtime.esm.js?2b0e:4088
Vue.$mount @ vue.runtime.esm.js?2b0e:8459
init @ vue.runtime.esm.js?2b0e:3137
merged @ vue.runtime.esm.js?2b0e:3322
createComponent @ vue.runtime.esm.js?2b0e:6022
createElm @ vue.runtime.esm.js?2b0e:5969
createChildren @ vue.runtime.esm.js?2b0e:6097
createElm @ vue.runtime.esm.js?2b0e:5998
patch @ vue.runtime.esm.js?2b0e:6521
Vue._update @ vue.runtime.esm.js?2b0e:3960
updateComponent @ vue.runtime.esm.js?2b0e:4081
get @ vue.runtime.esm.js?2b0e:4495
Watcher @ vue.runtime.esm.js?2b0e:4484
mountComponent @ vue.runtime.esm.js?2b0e:4088
Vue.$mount @ vue.runtime.esm.js?2b0e:8459
init @ vue.runtime.esm.js?2b0e:3137
createComponent @ vue.runtime.esm.js?2b0e:6022
createElm @ vue.runtime.esm.js?2b0e:5969
patch @ vue.runtime.esm.js?2b0e:6560
Vue._update @ vue.runtime.esm.js?2b0e:3960
updateComponent @ vue.runtime.esm.js?2b0e:4081
get @ vue.runtime.esm.js?2b0e:4495
Watcher @ vue.runtime.esm.js?2b0e:4484
mountComponent @ vue.runtime.esm.js?2b0e:4088
Vue.$mount @ vue.runtime.esm.js?2b0e:8459
eval @ main.ts?b26f:12
./src/main.ts @ app.js:1078
__webpack_require__ @ app.js:854
fn @ app.js:151
1 @ app.js:1151
__webpack_require__ @ app.js:854
checkDeferredModules @ app.js:46
(anonymous) @ app.js:994
(anonymous) @ app.js:997
Show 15 more frames
vue.runtime.esm.js?2b0e:619
[Vue warn]: Property or method "count" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
found in
---> <Home> at src/views/Home.vue
<App> at src/App.vue
<Root>
warn @ vue.runtime.esm.js?2b0e:619
warnNonPresent @ vue.runtime.esm.js?2b0e:2024
get @ vue.runtime.esm.js?2b0e:2079
render @ Home.vue?b723:6
eval @ vue-composition-api.esm.js?a6f4:1810
activateCurrentInstance @ vue-composition-api.esm.js?a6f4:1765
$options.render @ vue-composition-api.esm.js?a6f4:1809
Vue._render @ vue.runtime.esm.js?2b0e:3569
updateComponent @ vue.runtime.esm.js?2b0e:4081
get @ vue.runtime.esm.js?2b0e:4495
Watcher @ vue.runtime.esm.js?2b0e:4484
mountComponent @ vue.runtime.esm.js?2b0e:4088
Vue.$mount @ vue.runtime.esm.js?2b0e:8459
init @ vue.runtime.esm.js?2b0e:3137
merged @ vue.runtime.esm.js?2b0e:3322
createComponent @ vue.runtime.esm.js?2b0e:6022
createElm @ vue.runtime.esm.js?2b0e:5969
createChildren @ vue.runtime.esm.js?2b0e:6097
createElm @ vue.runtime.esm.js?2b0e:5998
patch @ vue.runtime.esm.js?2b0e:6521
Vue._update @ vue.runtime.esm.js?2b0e:3960
updateComponent @ vue.runtime.esm.js?2b0e:4081
get @ vue.runtime.esm.js?2b0e:4495
Watcher @ vue.runtime.esm.js?2b0e:4484
mountComponent @ vue.runtime.esm.js?2b0e:4088
Vue.$mount @ vue.runtime.esm.js?2b0e:8459
init @ vue.runtime.esm.js?2b0e:3137
createComponent @ vue.runtime.esm.js?2b0e:6022
createElm @ vue.runtime.esm.js?2b0e:5969
patch @ vue.runtime.esm.js?2b0e:6560
Vue._update @ vue.runtime.esm.js?2b0e:3960
updateComponent @ vue.runtime.esm.js?2b0e:4081
get @ vue.runtime.esm.js?2b0e:4495
Watcher @ vue.runtime.esm.js?2b0e:4484
mountComponent @ vue.runtime.esm.js?2b0e:4088
Vue.$mount @ vue.runtime.esm.js?2b0e:8459
eval @ main.ts?b26f:12
./src/main.ts @ app.js:1078
__webpack_require__ @ app.js:854
fn @ app.js:151
1 @ app.js:1151
__webpack_require__ @ app.js:854
checkDeferredModules @ app.js:46
(anonymous) @ app.js:994
(anonymous) @ app.js:997
Show 15 more frames
vue.runtime.esm.js?2b0e:619
[Vue warn]: Invalid handler for event "click": got undefined
found in
---> <Home> at src/views/Home.vue
<App> at src/App.vue
<Root>
Home.vue
<template>
<div @click="counter">{{ msg }}: {{ count }}</div>
</template>
<script lang="ts" setup>
let count = 0
function counter() {
count = count + 1
}
</script>
<script lang="ts">
export default {
data() {
return {
msg: 'hello'
}
}
}
</script>
Hey i have the weirdest issue:
here's the component:
<script setup name="OnThisVoyage">
import { useOrganisationIdProp } from '../../composables/useRouteHelpers.js';
import { provideBaseCardState } from '../../features/useBaseCardState.js';
import Service from '../../classes/Service.js';
import CargoRow from './CargoRow.vue';
const props = defineProps({
...useOrganisationIdProp(),
shipmentId: {
type: [Number, String],
required: true,
},
});
const {
setStateLoading,
setStateIdle,
setStateError,
setStateNoData,
} = provideBaseCardState();
const cargoes = ref([]);
const fetchCargoes = () => {
Service.organisation(props.organisationId)
.shipment(props.shipmentId)
.voyage()
.index()
.onStart(setStateLoading)
.onSuccess(({ data }) => {
cargoes.value = data.filter(
(cargo) => cargo.shipping_id !== props.shipmentId
);
setStateIdle();
})
.onNoData(setStateNoData)
.onError(setStateError);
};
onMounted(() => {
fetchCargoes();
});
</script>
<template>
<BaseCardWithState
title="On this voyage"
no-data-title="No other cargoes on this voyage."
@retry="fetchCargoes"
>
<CargoRow
v-for="{ cargo_key, shipping_id, commodity } in cargoes"
:key="cargo_key"
:shipment-id="shipping_id"
:commodity="commodity"
:organisation-id="organisationId"
/>
</BaseCardWithState>
</template>
When trying to render this component vite throws an error:
[plugin:unplugin-vue2-script-setup] Unexpected token, expected "," (1:16)
/Users/mykolas/Documents/Projects/myg2-frontend/src/components/OrganisationShipments/OnThisVoyage.vue:1:16
1 | <script setup name="OnThisVoyage">
| ^
2 | import { useOrganisationIdProp } from '../../composables/useRouteHelpers.js';
3 | import { provideBaseCardState } from '../../features/useBaseCardState.js';
Hi!
Today when i upgrade vscode (which ship with typescript v4.4.2) and plugin v0.5.6. I found that all component start losing type checking in almost case object.
This is when use typescript lib v4.4.2. It happend in both vscode's built-in or project lib typescript.
Type hint working again when switch back to 4.3.5
I'm not sure where is the reason. Early today when i try switch between 4.4.2 built-in to 4.4.2 local project, it keep return output failed in vscode, but somehow i can not reproceduce it. If i can see it again i will update this issue.
Thank you!
seem like losing type hint reason because Volar has bug with latest typescript v4.4.2. It reported here :
Volar's issue.
I think nothing to do with plugin because bug not from plugin :) . Just small note about statuation for now:
Before we no see issue because before Vscode v1.60 it built-in typescript 4.3.5, default when creating nuxt project we alwyas point to use buillt-in typescript version while nuxt when compile use 4.2.4. 4.3.5 support Volar working, and 4.2.4 support Nuxt compile file, so no error show up.
Error when point Vscode use local project typescript v 4.2.4. Error outut keep print at every key pressed.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.