-
-
Notifications
You must be signed in to change notification settings - Fork 147
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(kit): stub Vue runtime API (#456)
- Loading branch information
1 parent
382402e
commit 993982a
Showing
14 changed files
with
1,063 additions
and
190 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { Linter } from 'eslint' | ||
import noVueRuntime from './rules/no-vue-runtime-import' | ||
|
||
export default { | ||
rules: { | ||
'no-vue-runtime-import': noVueRuntime, | ||
}, | ||
} satisfies Linter.FlatConfig<{ | ||
'no-vue-runtime-import': any | ||
}> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { createRule, isTypeImport } from '../../utils' | ||
|
||
export default createRule<'no-vue-runtime-import', [{ prefer: string }]>({ | ||
meta: { | ||
type: 'problem', | ||
messages: { | ||
'no-vue-runtime-import': 'Please consider import runtime APIs from {{prefer}}.', | ||
}, | ||
schema: [ | ||
{ | ||
type: 'object', | ||
properties: { | ||
prefer: { | ||
type: 'string', | ||
}, | ||
}, | ||
}, | ||
], | ||
}, | ||
create(context) { | ||
const options = context.options[0] | ||
|
||
return { | ||
ImportDeclaration(node) { | ||
const importSource = node.source.value | ||
|
||
const shouldSkip = isTypeImport(node) || importSource !== 'vue' | ||
|
||
if (shouldSkip) | ||
return | ||
|
||
context.report({ | ||
node: node.source, | ||
messageId: 'no-vue-runtime-import', | ||
data: { | ||
prefer: options?.prefer ?? '<set prefer in your eslint config>', | ||
}, | ||
}) | ||
}, | ||
} | ||
}, | ||
}) |
32 changes: 32 additions & 0 deletions
32
eslint-plugins/rules/no-vue-runtime-import/no-vue-runtime-import.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { run } from '../../test-utils' | ||
import rule from '.' | ||
|
||
run({ | ||
name: 'no-vue-runtime-import', | ||
rule, | ||
|
||
valid: [ | ||
'import Vue from "abc"', | ||
'import type { Vue } from "vue"', | ||
'import { type bar, type baz } from "vue"', | ||
], | ||
|
||
invalid: [ | ||
{ | ||
code: 'import Vue from "vue"', | ||
errors: [{ messageId: 'no-vue-runtime-import' }], | ||
}, | ||
{ | ||
code: 'import { abc } from "vue"', | ||
errors: [{ messageId: 'no-vue-runtime-import' }], | ||
}, | ||
{ | ||
code: 'import * as Vue from "vue"', | ||
errors: [{ messageId: 'no-vue-runtime-import' }], | ||
}, | ||
{ | ||
code: 'import { foo, type bar } from "vue"', | ||
errors: [{ messageId: 'no-vue-runtime-import' }], | ||
}, | ||
], | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import tsParser from '@typescript-eslint/parser' | ||
|
||
import type { RuleTesterInitOptions, TestCasesOptions } from 'eslint-vitest-rule-tester' | ||
import { run as _run } from 'eslint-vitest-rule-tester' | ||
|
||
export * from 'eslint-vitest-rule-tester' | ||
|
||
export { unindent as $ } from 'eslint-vitest-rule-tester' | ||
|
||
export interface ExtendedRuleTesterOptions extends RuleTesterInitOptions, TestCasesOptions { | ||
lang?: 'js' | 'ts' | ||
} | ||
|
||
export function run(options: ExtendedRuleTesterOptions) { | ||
return _run({ | ||
recursive: false, | ||
verifyAfterFix: false, | ||
...(options.lang === 'js' ? {} : { parser: tsParser as any }), | ||
...options, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import type { TSESLint, TSESTree } from '@typescript-eslint/utils' | ||
import type { Rule } from 'eslint' | ||
|
||
export function createRule<MessageIds extends string, RuleOptions extends any[]>( | ||
rule: Omit<TSESLint.RuleModule<MessageIds, RuleOptions>, 'defaultOptions'>, | ||
) { | ||
return rule as unknown as Rule.RuleModule | ||
} | ||
|
||
export function isTypeImport(node: TSESTree.ImportDeclaration) { | ||
return node.importKind === 'type' | ||
|| node.specifiers.filter((s) => { | ||
if (s.type !== 'ImportSpecifier') | ||
return true | ||
if (s.importKind !== 'type') | ||
return true | ||
return false | ||
}).length === 0 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -80,6 +80,8 @@ | |
"@types/degit": "^2.8.6", | ||
"@types/fs-extra": "^11.0.4", | ||
"@types/node": "^20.14.5", | ||
"@typescript-eslint/parser": "^7.13.1", | ||
"@typescript-eslint/utils": "^7.13.1", | ||
"@unocss/eslint-plugin": "^0.61.0", | ||
"@vue/devtools-core": "workspace:^", | ||
"@vue/devtools-kit": "workspace:^", | ||
|
@@ -91,6 +93,7 @@ | |
"eslint": "npm:[email protected]", | ||
"eslint-plugin-format": "^0.1.2", | ||
"eslint-ts-patch": "8.57.0-0", | ||
"eslint-vitest-rule-tester": "^0.3.2", | ||
"execa": "^8.0.1", | ||
"fast-glob": "^3.3.2", | ||
"fs-extra": "^11.2.0", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/** | ||
* Only import vue types | ||
*/ | ||
import type { Ref, VNodeProps } from 'vue' | ||
|
||
/** | ||
* To prevent include a **HUGE** vue package in the final bundle of chrome ext / electron | ||
* we stub the necessary vue module. | ||
* This implementation is based on the 1c3327a0fa5983aa9078e3f7bb2330f572435425 commit | ||
*/ | ||
|
||
/** | ||
* @from [@vue/reactivity](https://github.com/vuejs/core/blob/1c3327a0fa5983aa9078e3f7bb2330f572435425/packages/reactivity/src/constants.ts#L17-L23) | ||
*/ | ||
export enum ReactiveFlags { | ||
SKIP = '__v_skip', | ||
IS_REACTIVE = '__v_isReactive', | ||
IS_READONLY = '__v_isReadonly', | ||
IS_SHALLOW = '__v_isShallow', | ||
RAW = '__v_raw', | ||
} | ||
|
||
/** | ||
* @from [@vue/reactivity](https://github.com/vuejs/core/blob/1c3327a0fa5983aa9078e3f7bb2330f572435425/packages/reactivity/src/reactive.ts#L18-L24) | ||
*/ | ||
export interface Target { | ||
[ReactiveFlags.SKIP]?: boolean | ||
[ReactiveFlags.IS_REACTIVE]?: boolean | ||
[ReactiveFlags.IS_READONLY]?: boolean | ||
[ReactiveFlags.IS_SHALLOW]?: boolean | ||
[ReactiveFlags.RAW]?: any | ||
} | ||
|
||
/** | ||
* @from [@vue/reactivity](https://github.com/vuejs/core/blob/1c3327a0fa5983aa9078e3f7bb2330f572435425/packages/reactivity/src/reactive.ts#L330-L332) | ||
*/ | ||
export function isReadonly(value: unknown): boolean { | ||
return !!(value && (value as Target)[ReactiveFlags.IS_READONLY]) | ||
} | ||
|
||
/** | ||
* @from [@vue/reactivity](https://github.com/vuejs/core/blob/1c3327a0fa5983aa9078e3f7bb2330f572435425/packages/reactivity/src/reactive.ts#L312-L317) | ||
*/ | ||
export function isReactive(value: unknown): boolean { | ||
if (isReadonly(value)) { | ||
return isReactive((value as Target)[ReactiveFlags.RAW]) | ||
} | ||
return !!(value && (value as Target)[ReactiveFlags.IS_REACTIVE]) | ||
} | ||
|
||
/** | ||
* @from [@vue/reactivity](https://github.com/vuejs/core/blob/1c3327a0fa5983aa9078e3f7bb2330f572435425/packages/reactivity/src/ref.ts#L99-L102) | ||
*/ | ||
export function isRef<T>(r: Ref<T> | unknown): r is Ref<T> | ||
export function isRef(r: any): r is Ref { | ||
return !!(r && r.__v_isRef === true) | ||
} | ||
|
||
/** | ||
* @from [@vue/reactivity](https://github.com/vuejs/core/blob/1c3327a0fa5983aa9078e3f7bb2330f572435425/packages/reactivity/src/reactive.ts#L372-L375) | ||
*/ | ||
export function toRaw<T>(observed: T): T { | ||
const raw = observed && (observed as Target)[ReactiveFlags.RAW] | ||
return raw ? toRaw(raw) : observed | ||
} | ||
|
||
/** | ||
* @from [@vue/runtime-core](https://github.com/vuejs/core/blob/1c3327a0fa5983aa9078e3f7bb2330f572435425/packages/runtime-core/src/vnode.ts#L63-L68) | ||
*/ | ||
export const Fragment = Symbol.for('v-fgt') as any as { | ||
__isFragment: true | ||
new (): { | ||
$props: VNodeProps | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.