diff --git a/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap b/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap
index 924038450..8886ce337 100644
--- a/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap
+++ b/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap
@@ -1,5 +1,501 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+exports[`compiler: parse > Edge Cases > invalid html 1`] = `
+{
+ "cached": 0,
+ "children": [
+ {
+ "children": [
+ {
+ "children": [],
+ "codegenNode": undefined,
+ "loc": {
+ "end": {
+ "column": 1,
+ "line": 3,
+ "offset": 13,
+ },
+ "source": "
+",
+ "start": {
+ "column": 1,
+ "line": 2,
+ "offset": 6,
+ },
+ },
+ "ns": 0,
+ "props": [],
+ "tag": "span",
+ "tagType": 0,
+ "type": 1,
+ },
+ ],
+ "codegenNode": undefined,
+ "loc": {
+ "end": {
+ "column": 7,
+ "line": 3,
+ "offset": 19,
+ },
+ "source": "
+
+
",
+ "start": {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": [],
+ "tag": "div",
+ "tagType": 0,
+ "type": 1,
+ },
+ ],
+ "codegenNode": undefined,
+ "components": [],
+ "directives": [],
+ "helpers": Set {},
+ "hoists": [],
+ "imports": [],
+ "loc": {
+ "end": {
+ "column": 8,
+ "line": 4,
+ "offset": 27,
+ },
+ "source": "
+
+
+",
+ "start": {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "source": "
+
+
+",
+ "temps": 0,
+ "type": 0,
+}
+`;
+
+exports[`compiler: parse > Edge Cases > self closing multiple tag 1`] = `
+{
+ "cached": 0,
+ "children": [
+ {
+ "children": [],
+ "codegenNode": undefined,
+ "isSelfClosing": true,
+ "loc": {
+ "end": {
+ "column": 37,
+ "line": 1,
+ "offset": 36,
+ },
+ "source": "",
+ "start": {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": [
+ {
+ "arg": {
+ "constType": 3,
+ "content": "class",
+ "isStatic": true,
+ "loc": {
+ "end": {
+ "column": 12,
+ "line": 1,
+ "offset": 11,
+ },
+ "source": "class",
+ "start": {
+ "column": 7,
+ "line": 1,
+ "offset": 6,
+ },
+ },
+ "type": 4,
+ },
+ "exp": {
+ "constType": 0,
+ "content": "{ some: condition }",
+ "isStatic": false,
+ "loc": {
+ "end": {
+ "column": 33,
+ "line": 1,
+ "offset": 32,
+ },
+ "source": "{ some: condition }",
+ "start": {
+ "column": 14,
+ "line": 1,
+ "offset": 13,
+ },
+ },
+ "type": 4,
+ },
+ "loc": {
+ "end": {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": ":class=\\"{ some: condition }\\"",
+ "start": {
+ "column": 6,
+ "line": 1,
+ "offset": 5,
+ },
+ },
+ "modifiers": [],
+ "name": "bind",
+ "rawName": ":class",
+ "type": 7,
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 1,
+ },
+ {
+ "children": [],
+ "codegenNode": undefined,
+ "isSelfClosing": true,
+ "loc": {
+ "end": {
+ "column": 37,
+ "line": 2,
+ "offset": 73,
+ },
+ "source": "",
+ "start": {
+ "column": 1,
+ "line": 2,
+ "offset": 37,
+ },
+ },
+ "ns": 0,
+ "props": [
+ {
+ "arg": {
+ "constType": 3,
+ "content": "style",
+ "isStatic": true,
+ "loc": {
+ "end": {
+ "column": 16,
+ "line": 2,
+ "offset": 52,
+ },
+ "source": "style",
+ "start": {
+ "column": 11,
+ "line": 2,
+ "offset": 47,
+ },
+ },
+ "type": 4,
+ },
+ "exp": {
+ "constType": 0,
+ "content": "{ color: 'red' }",
+ "isStatic": false,
+ "loc": {
+ "end": {
+ "column": 34,
+ "line": 2,
+ "offset": 70,
+ },
+ "source": "{ color: 'red' }",
+ "start": {
+ "column": 18,
+ "line": 2,
+ "offset": 54,
+ },
+ },
+ "type": 4,
+ },
+ "loc": {
+ "end": {
+ "column": 35,
+ "line": 2,
+ "offset": 71,
+ },
+ "source": "v-bind:style=\\"{ color: 'red' }\\"",
+ "start": {
+ "column": 4,
+ "line": 2,
+ "offset": 40,
+ },
+ },
+ "modifiers": [],
+ "name": "bind",
+ "rawName": "v-bind:style",
+ "type": 7,
+ },
+ ],
+ "tag": "p",
+ "tagType": 0,
+ "type": 1,
+ },
+ ],
+ "codegenNode": undefined,
+ "components": [],
+ "directives": [],
+ "helpers": Set {},
+ "hoists": [],
+ "imports": [],
+ "loc": {
+ "end": {
+ "column": 37,
+ "line": 2,
+ "offset": 73,
+ },
+ "source": "
+",
+ "start": {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "source": "
+",
+ "temps": 0,
+ "type": 0,
+}
+`;
+
+exports[`compiler: parse > Edge Cases > valid html 1`] = `
+{
+ "cached": 0,
+ "children": [
+ {
+ "children": [
+ {
+ "children": [],
+ "codegenNode": undefined,
+ "isSelfClosing": true,
+ "loc": {
+ "end": {
+ "column": 39,
+ "line": 2,
+ "offset": 73,
+ },
+ "source": "",
+ "start": {
+ "column": 3,
+ "line": 2,
+ "offset": 37,
+ },
+ },
+ "ns": 0,
+ "props": [
+ {
+ "arg": {
+ "constType": 3,
+ "content": "style",
+ "isStatic": true,
+ "loc": {
+ "end": {
+ "column": 18,
+ "line": 2,
+ "offset": 52,
+ },
+ "source": "style",
+ "start": {
+ "column": 13,
+ "line": 2,
+ "offset": 47,
+ },
+ },
+ "type": 4,
+ },
+ "exp": {
+ "constType": 0,
+ "content": "{ color: 'red' }",
+ "isStatic": false,
+ "loc": {
+ "end": {
+ "column": 36,
+ "line": 2,
+ "offset": 70,
+ },
+ "source": "{ color: 'red' }",
+ "start": {
+ "column": 20,
+ "line": 2,
+ "offset": 54,
+ },
+ },
+ "type": 4,
+ },
+ "loc": {
+ "end": {
+ "column": 37,
+ "line": 2,
+ "offset": 71,
+ },
+ "source": "v-bind:style=\\"{ color: 'red' }\\"",
+ "start": {
+ "column": 6,
+ "line": 2,
+ "offset": 40,
+ },
+ },
+ "modifiers": [],
+ "name": "bind",
+ "rawName": "v-bind:style",
+ "type": 7,
+ },
+ ],
+ "tag": "p",
+ "tagType": 0,
+ "type": 1,
+ },
+ {
+ "content": " a comment with inside it ",
+ "loc": {
+ "end": {
+ "column": 43,
+ "line": 3,
+ "offset": 116,
+ },
+ "source": "",
+ "start": {
+ "column": 3,
+ "line": 3,
+ "offset": 76,
+ },
+ },
+ "type": 3,
+ },
+ ],
+ "codegenNode": undefined,
+ "loc": {
+ "end": {
+ "column": 7,
+ "line": 4,
+ "offset": 123,
+ },
+ "source": "",
+ "start": {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": [
+ {
+ "arg": {
+ "constType": 3,
+ "content": "class",
+ "isStatic": true,
+ "loc": {
+ "end": {
+ "column": 12,
+ "line": 1,
+ "offset": 11,
+ },
+ "source": "class",
+ "start": {
+ "column": 7,
+ "line": 1,
+ "offset": 6,
+ },
+ },
+ "type": 4,
+ },
+ "exp": {
+ "constType": 0,
+ "content": "{ some: condition }",
+ "isStatic": false,
+ "loc": {
+ "end": {
+ "column": 33,
+ "line": 1,
+ "offset": 32,
+ },
+ "source": "{ some: condition }",
+ "start": {
+ "column": 14,
+ "line": 1,
+ "offset": 13,
+ },
+ },
+ "type": 4,
+ },
+ "loc": {
+ "end": {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": ":class=\\"{ some: condition }\\"",
+ "start": {
+ "column": 6,
+ "line": 1,
+ "offset": 5,
+ },
+ },
+ "modifiers": [],
+ "name": "bind",
+ "rawName": ":class",
+ "type": 7,
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 1,
+ },
+ ],
+ "codegenNode": undefined,
+ "components": [],
+ "directives": [],
+ "helpers": Set {},
+ "hoists": [],
+ "imports": [],
+ "loc": {
+ "end": {
+ "column": 7,
+ "line": 4,
+ "offset": 123,
+ },
+ "source": "",
+ "start": {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "source": "",
+ "temps": 0,
+ "type": 0,
+}
+`;
+
exports[`compiler: parse > Errors > CDATA_IN_HTML_CONTENT > 1`] = `
{
"cached": 0,
@@ -4326,499 +4822,3 @@ exports[`compiler: parse > Errors > X_MISSING_INTERPOLATION_END > {{}} 1`] = `
"type": 0,
}
`;
-
-exports[`compiler: parse > invalid html 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "loc": {
- "end": {
- "column": 1,
- "line": 3,
- "offset": 13,
- },
- "source": "
-",
- "start": {
- "column": 1,
- "line": 2,
- "offset": 6,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "span",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "loc": {
- "end": {
- "column": 7,
- "line": 3,
- "offset": 19,
- },
- "source": "
-
-
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 8,
- "line": 4,
- "offset": 27,
- },
- "source": "
-
-
-",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "source": "
-
-
-",
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse > self closing multiple tag 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": true,
- "loc": {
- "end": {
- "column": 37,
- "line": 1,
- "offset": 36,
- },
- "source": "",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [
- {
- "arg": {
- "constType": 3,
- "content": "class",
- "isStatic": true,
- "loc": {
- "end": {
- "column": 12,
- "line": 1,
- "offset": 11,
- },
- "source": "class",
- "start": {
- "column": 7,
- "line": 1,
- "offset": 6,
- },
- },
- "type": 4,
- },
- "exp": {
- "constType": 0,
- "content": "{ some: condition }",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 33,
- "line": 1,
- "offset": 32,
- },
- "source": "{ some: condition }",
- "start": {
- "column": 14,
- "line": 1,
- "offset": 13,
- },
- },
- "type": 4,
- },
- "loc": {
- "end": {
- "column": 34,
- "line": 1,
- "offset": 33,
- },
- "source": ":class=\\"{ some: condition }\\"",
- "start": {
- "column": 6,
- "line": 1,
- "offset": 5,
- },
- },
- "modifiers": [],
- "name": "bind",
- "rawName": ":class",
- "type": 7,
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": true,
- "loc": {
- "end": {
- "column": 37,
- "line": 2,
- "offset": 73,
- },
- "source": "",
- "start": {
- "column": 1,
- "line": 2,
- "offset": 37,
- },
- },
- "ns": 0,
- "props": [
- {
- "arg": {
- "constType": 3,
- "content": "style",
- "isStatic": true,
- "loc": {
- "end": {
- "column": 16,
- "line": 2,
- "offset": 52,
- },
- "source": "style",
- "start": {
- "column": 11,
- "line": 2,
- "offset": 47,
- },
- },
- "type": 4,
- },
- "exp": {
- "constType": 0,
- "content": "{ color: 'red' }",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 34,
- "line": 2,
- "offset": 70,
- },
- "source": "{ color: 'red' }",
- "start": {
- "column": 18,
- "line": 2,
- "offset": 54,
- },
- },
- "type": 4,
- },
- "loc": {
- "end": {
- "column": 35,
- "line": 2,
- "offset": 71,
- },
- "source": "v-bind:style=\\"{ color: 'red' }\\"",
- "start": {
- "column": 4,
- "line": 2,
- "offset": 40,
- },
- },
- "modifiers": [],
- "name": "bind",
- "rawName": "v-bind:style",
- "type": 7,
- },
- ],
- "tag": "p",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 37,
- "line": 2,
- "offset": 73,
- },
- "source": "
-",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "source": "
-",
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse > valid html 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": true,
- "loc": {
- "end": {
- "column": 39,
- "line": 2,
- "offset": 73,
- },
- "source": "",
- "start": {
- "column": 3,
- "line": 2,
- "offset": 37,
- },
- },
- "ns": 0,
- "props": [
- {
- "arg": {
- "constType": 3,
- "content": "style",
- "isStatic": true,
- "loc": {
- "end": {
- "column": 18,
- "line": 2,
- "offset": 52,
- },
- "source": "style",
- "start": {
- "column": 13,
- "line": 2,
- "offset": 47,
- },
- },
- "type": 4,
- },
- "exp": {
- "constType": 0,
- "content": "{ color: 'red' }",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 36,
- "line": 2,
- "offset": 70,
- },
- "source": "{ color: 'red' }",
- "start": {
- "column": 20,
- "line": 2,
- "offset": 54,
- },
- },
- "type": 4,
- },
- "loc": {
- "end": {
- "column": 37,
- "line": 2,
- "offset": 71,
- },
- "source": "v-bind:style=\\"{ color: 'red' }\\"",
- "start": {
- "column": 6,
- "line": 2,
- "offset": 40,
- },
- },
- "modifiers": [],
- "name": "bind",
- "rawName": "v-bind:style",
- "type": 7,
- },
- ],
- "tag": "p",
- "tagType": 0,
- "type": 1,
- },
- {
- "content": " a comment with inside it ",
- "loc": {
- "end": {
- "column": 43,
- "line": 3,
- "offset": 116,
- },
- "source": "",
- "start": {
- "column": 3,
- "line": 3,
- "offset": 76,
- },
- },
- "type": 3,
- },
- ],
- "codegenNode": undefined,
- "loc": {
- "end": {
- "column": 7,
- "line": 4,
- "offset": 123,
- },
- "source": "",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [
- {
- "arg": {
- "constType": 3,
- "content": "class",
- "isStatic": true,
- "loc": {
- "end": {
- "column": 12,
- "line": 1,
- "offset": 11,
- },
- "source": "class",
- "start": {
- "column": 7,
- "line": 1,
- "offset": 6,
- },
- },
- "type": 4,
- },
- "exp": {
- "constType": 0,
- "content": "{ some: condition }",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 33,
- "line": 1,
- "offset": 32,
- },
- "source": "{ some: condition }",
- "start": {
- "column": 14,
- "line": 1,
- "offset": 13,
- },
- },
- "type": 4,
- },
- "loc": {
- "end": {
- "column": 34,
- "line": 1,
- "offset": 33,
- },
- "source": ":class=\\"{ some: condition }\\"",
- "start": {
- "column": 6,
- "line": 1,
- "offset": 5,
- },
- },
- "modifiers": [],
- "name": "bind",
- "rawName": ":class",
- "type": 7,
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 7,
- "line": 4,
- "offset": 123,
- },
- "source": "",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "source": "",
- "temps": 0,
- "type": 0,
-}
-`;
diff --git a/packages/compiler-core/__tests__/parse.spec.ts b/packages/compiler-core/__tests__/parse.spec.ts
index 4e6c80b38..05a2afcdc 100644
--- a/packages/compiler-core/__tests__/parse.spec.ts
+++ b/packages/compiler-core/__tests__/parse.spec.ts
@@ -1796,166 +1796,167 @@ describe('compiler: parse', () => {
})
})
- test('self closing single tag', () => {
- const ast = baseParse('')
+ describe('Edge Cases', () => {
+ test('self closing single tag', () => {
+ const ast = baseParse('')
- expect(ast.children).toHaveLength(1)
- expect(ast.children[0]).toMatchObject({ tag: 'div' })
- })
-
- test('self closing multiple tag', () => {
- const ast = baseParse(
- `\n` +
- ``
- )
-
- expect(ast).toMatchSnapshot()
-
- expect(ast.children).toHaveLength(2)
- expect(ast.children[0]).toMatchObject({ tag: 'div' })
- expect(ast.children[1]).toMatchObject({ tag: 'p' })
- })
-
- test('valid html', () => {
- const ast = baseParse(
- `\n` +
- `
\n` +
- ` \n` +
- `
`
- )
-
- expect(ast).toMatchSnapshot()
-
- expect(ast.children).toHaveLength(1)
- const el = ast.children[0] as any
- expect(el).toMatchObject({
- tag: 'div'
- })
- expect(el.children).toHaveLength(2)
- expect(el.children[0]).toMatchObject({
- tag: 'p'
- })
- expect(el.children[1]).toMatchObject({
- type: NodeTypes.COMMENT
- })
- })
-
- test('invalid html', () => {
- expect(() => {
- baseParse(`\n\n
\n`)
- }).toThrow('Element is missing end tag.')
-
- const spy = vi.fn()
- const ast = baseParse(`\n\n
\n`, {
- onError: spy
+ expect(ast.children).toHaveLength(1)
+ expect(ast.children[0]).toMatchObject({ tag: 'div' })
})
- expect(spy.mock.calls).toMatchObject([
- [
- {
- code: ErrorCodes.X_MISSING_END_TAG,
- loc: {
- start: {
- offset: 6,
- line: 2,
- column: 1
- }
- }
- }
- ],
- [
- {
- code: ErrorCodes.X_INVALID_END_TAG,
- loc: {
- start: {
- offset: 20,
- line: 4,
- column: 1
- }
- }
- }
- ]
- ])
+ test('self closing multiple tag', () => {
+ const ast = baseParse(
+ `\n` +
+ ``
+ )
- expect(ast).toMatchSnapshot()
- })
+ expect(ast).toMatchSnapshot()
- test('parse with correct location info', () => {
- const fooSrc = `foo
- is `
- const barSrc = `{{ bar }}`
- const butSrc = ` but `
- const bazSrc = `{{ baz }}`
- const [foo, bar, but, baz] = baseParse(
- fooSrc + barSrc + butSrc + bazSrc
- ).children
+ expect(ast.children).toHaveLength(2)
+ expect(ast.children[0]).toMatchObject({ tag: 'div' })
+ expect(ast.children[1]).toMatchObject({ tag: 'p' })
+ })
- let offset = 0
- expect(foo.loc.start).toEqual({ line: 1, column: 1, offset })
- offset += fooSrc.length
- expect(foo.loc.end).toEqual({ line: 2, column: 5, offset })
+ test('valid html', () => {
+ const ast = baseParse(
+ `\n` +
+ `
\n` +
+ ` \n` +
+ `
`
+ )
- expect(bar.loc.start).toEqual({ line: 2, column: 5, offset })
- const barInner = (bar as InterpolationNode).content
- offset += 3
- expect(barInner.loc.start).toEqual({ line: 2, column: 8, offset })
- offset += 3
- expect(barInner.loc.end).toEqual({ line: 2, column: 11, offset })
- offset += 3
- expect(bar.loc.end).toEqual({ line: 2, column: 14, offset })
+ expect(ast).toMatchSnapshot()
- expect(but.loc.start).toEqual({ line: 2, column: 14, offset })
- offset += butSrc.length
- expect(but.loc.end).toEqual({ line: 2, column: 19, offset })
+ expect(ast.children).toHaveLength(1)
+ const el = ast.children[0] as any
+ expect(el).toMatchObject({
+ tag: 'div'
+ })
+ expect(el.children).toHaveLength(2)
+ expect(el.children[0]).toMatchObject({
+ tag: 'p'
+ })
+ expect(el.children[1]).toMatchObject({
+ type: NodeTypes.COMMENT
+ })
+ })
- expect(baz.loc.start).toEqual({ line: 2, column: 19, offset })
- const bazInner = (baz as InterpolationNode).content
- offset += 3
- expect(bazInner.loc.start).toEqual({ line: 2, column: 22, offset })
- offset += 3
- expect(bazInner.loc.end).toEqual({ line: 2, column: 25, offset })
- offset += 3
- expect(baz.loc.end).toEqual({ line: 2, column: 28, offset })
- })
+ test('invalid html', () => {
+ expect(() => {
+ baseParse(`\n\n
\n`)
+ }).toThrow('Element is missing end tag.')
- // With standard HTML parsing, the following input would ignore the slash
- // and treat "<" and "template" as attributes on the open tag of "Hello",
- // causing `` to fail to close, and ``,
- {
+ const spy = vi.fn()
+ const ast = baseParse(`\n\n
\n`, {
onError: spy
- }
- )
- //
- expect(ast.children.length).toBe(2)
- expect(ast.children[1]).toMatchObject({
- type: NodeTypes.ELEMENT,
- tag: 'script'
- })
- })
+ })
- test('arg should be undefined on shorthand dirs with no arg', () => {
- const ast = baseParse(``)
- const el = ast.children[0] as ElementNode
- expect(el.props[0]).toMatchObject({
- type: NodeTypes.DIRECTIVE,
- name: 'slot',
- exp: undefined,
- arg: undefined
- })
- })
+ expect(spy.mock.calls).toMatchObject([
+ [
+ {
+ code: ErrorCodes.X_MISSING_END_TAG,
+ loc: {
+ start: {
+ offset: 6,
+ line: 2,
+ column: 1
+ }
+ }
+ }
+ ],
+ [
+ {
+ code: ErrorCodes.X_INVALID_END_TAG,
+ loc: {
+ start: {
+ offset: 20,
+ line: 4,
+ column: 1
+ }
+ }
+ }
+ ]
+ ])
- // edge case found in vue-macros where the input is TS or JSX
- test('should reset inRCDATA state', () => {
- baseParse(``, { parseMode: 'sfc', onError() {} })
- expect(() => baseParse(`{ foo }`)).not.toThrow()
+ expect(ast).toMatchSnapshot()
+ })
+
+ test('parse with correct location info', () => {
+ const fooSrc = `foo\n is `
+ const barSrc = `{{ bar }}`
+ const butSrc = ` but `
+ const bazSrc = `{{ baz }}`
+ const [foo, bar, but, baz] = baseParse(
+ fooSrc + barSrc + butSrc + bazSrc
+ ).children
+
+ let offset = 0
+ expect(foo.loc.start).toEqual({ line: 1, column: 1, offset })
+ offset += fooSrc.length
+ expect(foo.loc.end).toEqual({ line: 2, column: 5, offset })
+
+ expect(bar.loc.start).toEqual({ line: 2, column: 5, offset })
+ const barInner = (bar as InterpolationNode).content
+ offset += 3
+ expect(barInner.loc.start).toEqual({ line: 2, column: 8, offset })
+ offset += 3
+ expect(barInner.loc.end).toEqual({ line: 2, column: 11, offset })
+ offset += 3
+ expect(bar.loc.end).toEqual({ line: 2, column: 14, offset })
+
+ expect(but.loc.start).toEqual({ line: 2, column: 14, offset })
+ offset += butSrc.length
+ expect(but.loc.end).toEqual({ line: 2, column: 19, offset })
+
+ expect(baz.loc.start).toEqual({ line: 2, column: 19, offset })
+ const bazInner = (baz as InterpolationNode).content
+ offset += 3
+ expect(bazInner.loc.start).toEqual({ line: 2, column: 22, offset })
+ offset += 3
+ expect(bazInner.loc.end).toEqual({ line: 2, column: 25, offset })
+ offset += 3
+ expect(baz.loc.end).toEqual({ line: 2, column: 28, offset })
+ })
+
+ // With standard HTML parsing, the following input would ignore the slash
+ // and treat "<" and "template" as attributes on the open tag of "Hello",
+ // causing `` to fail to close, and ``,
+ {
+ onError: spy
+ }
+ )
+ //
+ expect(ast.children.length).toBe(2)
+ expect(ast.children[1]).toMatchObject({
+ type: NodeTypes.ELEMENT,
+ tag: 'script'
+ })
+ })
+
+ test('arg should be undefined on shorthand dirs with no arg', () => {
+ const ast = baseParse(``)
+ const el = ast.children[0] as ElementNode
+ expect(el.props[0]).toMatchObject({
+ type: NodeTypes.DIRECTIVE,
+ name: 'slot',
+ exp: undefined,
+ arg: undefined
+ })
+ })
+
+ // edge case found in vue-macros where the input is TS or JSX
+ test('should reset inRCDATA state', () => {
+ baseParse(``, { parseMode: 'sfc', onError() {} })
+ expect(() => baseParse(`{ foo }`)).not.toThrow()
+ })
})
describe('decodeEntities option', () => {
diff --git a/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts
index 0d18c1beb..a9697930c 100644
--- a/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts
@@ -161,6 +161,14 @@ describe('compiler: expression transform', () => {
type: NodeTypes.COMPOUND_EXPRESSION,
children: [{ content: `Math` }, `.`, { content: `max` }, `(1, 2)`]
})
+
+ expect(
+ (parseWithExpressionTransform(`{{ new Error() }}`) as InterpolationNode)
+ .content
+ ).toMatchObject({
+ type: NodeTypes.COMPOUND_EXPRESSION,
+ children: ['new ', { content: 'Error' }, '()']
+ })
})
test('should not prefix reserved literals', () => {
diff --git a/packages/compiler-sfc/package.json b/packages/compiler-sfc/package.json
index ff6224c7c..e1563d86f 100644
--- a/packages/compiler-sfc/package.json
+++ b/packages/compiler-sfc/package.json
@@ -49,7 +49,7 @@
"lru-cache": "^10.1.0",
"merge-source-map": "^1.1.0",
"minimatch": "^9.0.3",
- "postcss-modules": "^4.3.1",
+ "postcss-modules": "^6.0.0",
"postcss-selector-parser": "^6.0.13",
"pug": "^3.0.2",
"sass": "^1.69.5"
diff --git a/packages/shared/src/globalsAllowList.ts b/packages/shared/src/globalsAllowList.ts
index 4af518c22..210650e3e 100644
--- a/packages/shared/src/globalsAllowList.ts
+++ b/packages/shared/src/globalsAllowList.ts
@@ -3,7 +3,7 @@ import { makeMap } from './makeMap'
const GLOBALS_ALLOWED =
'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' +
'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' +
- 'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt,console'
+ 'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt,console,Error'
export const isGloballyAllowed = /*#__PURE__*/ makeMap(GLOBALS_ALLOWED)
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 51569cfb7..4a1779f4e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -245,8 +245,8 @@ importers:
specifier: ^9.0.3
version: 9.0.3
postcss-modules:
- specifier: ^4.3.1
- version: 4.3.1(postcss@8.4.31)
+ specifier: ^6.0.0
+ version: 6.0.0(postcss@8.4.31)
postcss-selector-parser:
specifier: ^6.0.13
version: 6.0.13
@@ -3689,10 +3689,6 @@ packages:
safer-buffer: 2.1.2
dev: true
- /icss-replace-symbols@1.1.0:
- resolution: {integrity: sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==}
- dev: true
-
/icss-utils@5.1.0(postcss@8.4.31):
resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==}
engines: {node: ^10 || ^12 || >= 14}
@@ -4917,13 +4913,13 @@ packages:
postcss: 8.4.31
dev: true
- /postcss-modules@4.3.1(postcss@8.4.31):
- resolution: {integrity: sha512-ItUhSUxBBdNamkT3KzIZwYNNRFKmkJrofvC2nWab3CPKhYBQ1f27XXh1PAPE27Psx58jeelPsxWB/+og+KEH0Q==}
+ /postcss-modules@6.0.0(postcss@8.4.31):
+ resolution: {integrity: sha512-7DGfnlyi/ju82BRzTIjWS5C4Tafmzl3R79YP/PASiocj+aa6yYphHhhKUOEoXQToId5rgyFgJ88+ccOUydjBXQ==}
peerDependencies:
postcss: ^8.0.0
dependencies:
generic-names: 4.0.0
- icss-replace-symbols: 1.1.0
+ icss-utils: 5.1.0(postcss@8.4.31)
lodash.camelcase: 4.3.0
postcss: 8.4.31
postcss-modules-extract-imports: 3.0.0(postcss@8.4.31)
diff --git a/rollup.config.js b/rollup.config.js
index 59e6924da..eb1902234 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -1,4 +1,5 @@
// @ts-check
+import assert from 'node:assert/strict'
import { createRequire } from 'node:module'
import { fileURLToPath } from 'node:url'
import path from 'node:path'
@@ -14,6 +15,14 @@ import alias from '@rollup/plugin-alias'
import { entries } from './scripts/aliases.js'
import { inlineEnums } from './scripts/inline-enums.js'
+/**
+ * @template T
+ * @template {keyof T} K
+ * @typedef { Omit & Required> } MarkRequired
+ */
+/** @typedef {'cjs' | 'esm-bundler' | 'global' | 'global-runtime' | 'esm-browser' | 'esm-bundler-runtime' | 'esm-browser-runtime'} PackageFormat */
+/** @typedef {MarkRequired} OutputOptions */
+
if (!process.env.TARGET) {
throw new Error('TARGET package must be specified via --environment flag.')
}
@@ -27,45 +36,35 @@ const consolidatePkg = require('@vue/consolidate/package.json')
const packagesDir = path.resolve(__dirname, 'packages')
const packageDir = path.resolve(packagesDir, process.env.TARGET)
-/** @param {string} p */
-const resolve = p => path.resolve(packageDir, p)
+const resolve = (/** @type {string} */ p) => path.resolve(packageDir, p)
const pkg = require(resolve(`package.json`))
const packageOptions = pkg.buildOptions || {}
const name = packageOptions.filename || path.basename(packageDir)
const [enumPlugin, enumDefines] = inlineEnums()
-/**
- * @typedef { Omit & Required> } MarkRequired
- * @template T
- * @template {keyof T} K
- */
-
-/** @typedef {import('rollup').ModuleFormat} Format */
-/** @typedef {MarkRequired} Output */
-
-/** @type {Record} */
+/** @type {Record} */
const outputConfigs = {
'esm-bundler': {
file: resolve(`dist/${name}.esm-bundler.js`),
- format: `es`
+ format: 'es'
},
'esm-browser': {
file: resolve(`dist/${name}.esm-browser.js`),
- format: `es`
+ format: 'es'
},
cjs: {
file: resolve(`dist/${name}.cjs.js`),
- format: `cjs`
+ format: 'cjs'
},
global: {
file: resolve(`dist/${name}.global.js`),
- format: `iife`
+ format: 'iife'
},
// runtime-only builds, for main "vue" package only
'esm-bundler-runtime': {
file: resolve(`dist/${name}.runtime.esm-bundler.js`),
- format: `es`
+ format: 'es'
},
'esm-browser-runtime': {
file: resolve(`dist/${name}.runtime.esm-browser.js`),
@@ -77,40 +76,39 @@ const outputConfigs = {
}
}
+/** @type {ReadonlyArray} */
const defaultFormats = ['esm-bundler', 'cjs']
-const inlineFormats = process.env.FORMATS && process.env.FORMATS.split(',')
+/** @type {ReadonlyArray} */
+const inlineFormats = /** @type {any} */ (
+ process.env.FORMATS && process.env.FORMATS.split(',')
+)
+/** @type {ReadonlyArray} */
const packageFormats = inlineFormats || packageOptions.formats || defaultFormats
const packageConfigs = process.env.PROD_ONLY
? []
- : packageFormats.map(
- /** @param {Format} format */
- format => createConfig(format, outputConfigs[format])
- )
+ : packageFormats.map(format => createConfig(format, outputConfigs[format]))
if (process.env.NODE_ENV === 'production') {
- packageFormats.forEach(
- /** @param {Format} format */
- format => {
- if (packageOptions.prod === false) {
- return
- }
- if (format === 'cjs') {
- packageConfigs.push(createProductionConfig(format))
- }
- if (/^(global|esm-browser)(-runtime)?/.test(format)) {
- packageConfigs.push(createMinifiedConfig(format))
- }
+ packageFormats.forEach(format => {
+ if (packageOptions.prod === false) {
+ return
}
- )
+ if (format === 'cjs') {
+ packageConfigs.push(createProductionConfig(format))
+ }
+ if (/^(global|esm-browser)(-runtime)?/.test(format)) {
+ packageConfigs.push(createMinifiedConfig(format))
+ }
+ })
}
export default packageConfigs
/**
*
- * @param {Format} format
- * @param {Output} output
- * @param {import('rollup').Plugin[]} plugins
+ * @param {PackageFormat} format
+ * @param {OutputOptions} output
+ * @param {ReadonlyArray} plugins
* @returns {import('rollup').RollupOptions}
*/
function createConfig(format, output, plugins = []) {
@@ -180,7 +178,7 @@ function createConfig(format, output, plugins = []) {
],
output,
onwarn(msg, warn) {
- if (!/Circular/.test(msg.message)) {
+ if (msg.code !== 'CIRCULAR_DEPENDENCY') {
warn(msg)
}
},
@@ -221,7 +219,6 @@ function createConfig(format, output, plugins = []) {
if (!isBundlerESMBuild) {
// hard coded dev/prod builds
- // @ts-ignore
replacements.__DEV__ = String(!isProductionBuild)
}
@@ -229,7 +226,9 @@ function createConfig(format, output, plugins = []) {
//__RUNTIME_COMPILE__=true pnpm build runtime-core
Object.keys(replacements).forEach(key => {
if (key in process.env) {
- replacements[key] = /** @type {string} */ (process.env[key])
+ const value = process.env[key]
+ assert(typeof value === 'string')
+ replacements[key] = value
}
})
return replacements
@@ -266,7 +265,6 @@ function createConfig(format, output, plugins = []) {
}
if (Object.keys(replacements).length) {
- // @ts-ignore
return [replace({ values: replacements, preventAssignment: true })]
} else {
return []
@@ -304,7 +302,7 @@ function createConfig(format, output, plugins = []) {
function resolveNodePlugins() {
// we are bundling forked consolidate.js in compiler-sfc which dynamically
// requires a ton of template engines which should be ignored.
- /** @type { string[] } */
+ /** @type {ReadonlyArray} */
let cjsIgnores = []
if (
pkg.name === '@vue/compiler-sfc' ||
@@ -339,20 +337,14 @@ function createConfig(format, output, plugins = []) {
}
}
-/**
- * @param {Format} format
- */
-function createProductionConfig(format) {
+function createProductionConfig(/** @type {PackageFormat} */ format) {
return createConfig(format, {
...outputConfigs[format],
file: resolve(`dist/${name}.${format}.prod.js`)
})
}
-/**
- * @param {Format} format
- */
-function createMinifiedConfig(format) {
+function createMinifiedConfig(/** @type {PackageFormat} */ format) {
return createConfig(
format,
{
diff --git a/rollup.dts.config.js b/rollup.dts.config.js
index 3e45167bc..a9b3a0cda 100644
--- a/rollup.dts.config.js
+++ b/rollup.dts.config.js
@@ -1,6 +1,7 @@
// @ts-check
+import assert from 'node:assert/strict'
import { parse } from '@babel/parser'
-import { existsSync, readdirSync, readFileSync, writeFileSync } from 'fs'
+import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs'
import MagicString from 'magic-string'
import dts from 'rollup-plugin-dts'
@@ -70,15 +71,16 @@ function patchTypes(pkg) {
if (!node.id) {
return
}
- // @ts-ignore
+ assert(node.id.type === 'Identifier')
const name = node.id.name
if (name.startsWith('_')) {
return
}
shouldRemoveExport.add(name)
if (isExported.has(name)) {
- // @ts-ignore
- s.prependLeft((parentDecl || node).start, `export `)
+ const start = (parentDecl || node).start
+ assert(typeof start === 'number')
+ s.prependLeft(start, `export `)
}
}
@@ -102,9 +104,10 @@ function patchTypes(pkg) {
if (node.type === 'VariableDeclaration') {
processDeclaration(node.declarations[0], node)
if (node.declarations.length > 1) {
+ assert(typeof node.start === 'number')
+ assert(typeof node.end === 'number')
throw new Error(
`unhandled declare const with more than one declarators:\n${code.slice(
- // @ts-ignore
node.start,
node.end
)}`
@@ -131,7 +134,7 @@ function patchTypes(pkg) {
spec.type === 'ExportSpecifier' &&
shouldRemoveExport.has(spec.local.name)
) {
- // @ts-ignore
+ assert(spec.exported.type === 'Identifier')
const exported = spec.exported.name
if (exported !== spec.local.name) {
// this only happens if we have something like
@@ -141,19 +144,27 @@ function patchTypes(pkg) {
}
const next = node.specifiers[i + 1]
if (next) {
- // @ts-ignore
+ assert(typeof spec.start === 'number')
+ assert(typeof next.start === 'number')
s.remove(spec.start, next.start)
} else {
// last one
const prev = node.specifiers[i - 1]
- // @ts-ignore
- s.remove(prev ? prev.end : spec.start, spec.end)
+ assert(typeof spec.start === 'number')
+ assert(typeof spec.end === 'number')
+ s.remove(
+ prev
+ ? (assert(typeof prev.end === 'number'), prev.end)
+ : spec.start,
+ spec.end
+ )
}
removed++
}
}
if (removed === node.specifiers.length) {
- // @ts-ignore
+ assert(typeof node.start === 'number')
+ assert(typeof node.end === 'number')
s.remove(node.start, node.end)
}
}
@@ -186,11 +197,8 @@ function copyMts() {
return {
name: 'copy-vue-mts',
writeBundle(_, bundle) {
- writeFileSync(
- 'packages/vue/dist/vue.d.mts',
- // @ts-ignore
- bundle['vue.d.ts'].code
- )
+ assert('code' in bundle['vue.d.ts'])
+ writeFileSync('packages/vue/dist/vue.d.mts', bundle['vue.d.ts'].code)
}
}
}
diff --git a/scripts/aliases.js b/scripts/aliases.js
index 34a7c6435..907196745 100644
--- a/scripts/aliases.js
+++ b/scripts/aliases.js
@@ -4,7 +4,7 @@ import { readdirSync, statSync } from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
-const resolveEntryForPkg = p =>
+const resolveEntryForPkg = (/** @type {string} */ p) =>
path.resolve(
fileURLToPath(import.meta.url),
`../../packages/${p}/src/index.ts`
@@ -12,6 +12,7 @@ const resolveEntryForPkg = p =>
const dirs = readdirSync(new URL('../packages', import.meta.url))
+/** @type {Record} */
const entries = {
vue: resolveEntryForPkg('vue'),
'vue/compiler-sfc': resolveEntryForPkg('compiler-sfc'),
diff --git a/scripts/build.js b/scripts/build.js
index b96e576ca..aa56a1327 100644
--- a/scripts/build.js
+++ b/scripts/build.js
@@ -38,6 +38,7 @@ const prodOnly = !devOnly && (args.prodOnly || args.p)
const buildTypes = args.withTypes || args.t
const sourceMap = args.sourcemap || args.s
const isRelease = args.release
+/** @type {boolean | undefined} */
const buildAllMatching = args.all || args.a
const writeSize = args.size
const commit = execaSync('git', ['rev-parse', '--short=7', 'HEAD']).stdout
@@ -102,7 +103,9 @@ async function runParallel(maxConcurrency, source, iteratorFn) {
ret.push(p)
if (maxConcurrency <= source.length) {
- const e = p.then(() => executing.splice(executing.indexOf(e), 1))
+ const e = p.then(() => {
+ executing.splice(executing.indexOf(e), 1)
+ })
executing.push(e)
if (executing.length >= maxConcurrency) {
await Promise.race(executing)
diff --git a/scripts/release.js b/scripts/release.js
index a9484ff5f..fddf4ca67 100644
--- a/scripts/release.js
+++ b/scripts/release.js
@@ -9,6 +9,15 @@ import { execa } from 'execa'
import { createRequire } from 'node:module'
import { fileURLToPath } from 'node:url'
+/**
+ * @typedef {{
+ * name: string
+ * version: string
+ * dependencies?: { [dependenciesPackageName: string]: string }
+ * peerDependencies?: { [peerDependenciesPackageName: string]: string }
+ * }} Package
+ */
+
let versionUpdated = false
const { prompt } = enquirer
@@ -25,6 +34,7 @@ const args = minimist(process.argv.slice(2), {
const preId = args.preid || semver.prerelease(currentVersion)?.[0]
const isDryRun = args.dry
+/** @type {boolean | undefined} */
let skipTests = args.skipTests
const skipBuild = args.skipBuild
const isCanary = args.canary
@@ -43,7 +53,7 @@ const packages = fs
}
})
-const isCorePackage = pkgName => {
+const isCorePackage = (/** @type {string} */ pkgName) => {
if (!pkgName) return
if (pkgName === 'vue' || pkgName === '@vue/compat') {
@@ -56,7 +66,7 @@ const isCorePackage = pkgName => {
)
}
-const renamePackageToCanary = pkgName => {
+const renamePackageToCanary = (/** @type {string} */ pkgName) => {
if (pkgName === 'vue') {
return '@vue/canary'
}
@@ -68,25 +78,37 @@ const renamePackageToCanary = pkgName => {
return pkgName
}
-const keepThePackageName = pkgName => pkgName
+const keepThePackageName = (/** @type {string} */ pkgName) => pkgName
+/** @type {string[]} */
const skippedPackages = []
+/** @type {ReadonlyArray} */
const versionIncrements = [
'patch',
'minor',
'major',
- ...(preId ? ['prepatch', 'preminor', 'premajor', 'prerelease'] : [])
+ ...(preId
+ ? /** @type {const} */ (['prepatch', 'preminor', 'premajor', 'prerelease'])
+ : [])
]
-const inc = i => semver.inc(currentVersion, i, preId)
-const run = (bin, args, opts = {}) =>
- execa(bin, args, { stdio: 'inherit', ...opts })
-const dryRun = (bin, args, opts = {}) =>
- console.log(pico.blue(`[dryrun] ${bin} ${args.join(' ')}`), opts)
+const inc = (/** @type {import('semver').ReleaseType} */ i) =>
+ semver.inc(currentVersion, i, preId)
+const run = async (
+ /** @type {string} */ bin,
+ /** @type {ReadonlyArray} */ args,
+ /** @type {import('execa').Options} */ opts = {}
+) => execa(bin, args, { stdio: 'inherit', ...opts })
+const dryRun = async (
+ /** @type {string} */ bin,
+ /** @type {ReadonlyArray} */ args,
+ /** @type {import('execa').Options} */ opts = {}
+) => console.log(pico.blue(`[dryrun] ${bin} ${args.join(' ')}`), opts)
const runIfNotDry = isDryRun ? dryRun : run
-const getPkgRoot = pkg => path.resolve(__dirname, '../packages/' + pkg)
-const step = msg => console.log(pico.cyan(msg))
+const getPkgRoot = (/** @type {string} */ pkg) =>
+ path.resolve(__dirname, '../packages/' + pkg)
+const step = (/** @type {string} */ msg) => console.log(pico.cyan(msg))
async function main() {
if (!(await isInSyncWithRemote())) {
@@ -137,7 +159,7 @@ async function main() {
semver.inc(latestSameDayPatch, 'prerelease', args.tag)
)
}
- } catch (e) {
+ } catch (/** @type {any} */ e) {
if (/E404/.test(e.message)) {
// the first patch version on that day
} else {
@@ -150,7 +172,7 @@ async function main() {
if (!targetVersion) {
// no explicit version, offer suggestions
- // @ts-ignore
+ /** @type {{ release: string }} */
const { release } = await prompt({
type: 'select',
name: 'release',
@@ -159,16 +181,16 @@ async function main() {
})
if (release === 'custom') {
+ /** @type {{ version: string }} */
const result = await prompt({
type: 'input',
name: 'version',
message: 'Input custom version',
initial: currentVersion
})
- // @ts-ignore
targetVersion = result.version
} else {
- targetVersion = release.match(/\((.*)\)/)[1]
+ targetVersion = release.match(/\((.*)\)/)?.[1] ?? ''
}
}
@@ -183,7 +205,7 @@ async function main() {
: `Releasing v${targetVersion}...`
)
} else {
- // @ts-ignore
+ /** @type {{ yes: boolean }} */
const { yes: confirmRelease } = await prompt({
type: 'confirm',
name: 'yes',
@@ -201,7 +223,7 @@ async function main() {
skipTests ||= isCIPassed
if (isCIPassed && !skipPrompts) {
- // @ts-ignore
+ /** @type {{ yes: boolean }} */
const { yes: promptSkipTests } = await prompt({
type: 'confirm',
name: 'yes',
@@ -246,7 +268,7 @@ async function main() {
await run(`pnpm`, ['run', 'changelog'])
if (!skipPrompts) {
- // @ts-ignore
+ /** @type {{ yes: boolean }} */
const { yes: changelogOk } = await prompt({
type: 'confirm',
name: 'yes',
@@ -346,7 +368,7 @@ async function isInSyncWithRemote() {
if (data.sha === (await getSha())) {
return true
} else {
- // @ts-ignore
+ /** @type {{ yes: boolean }} */
const { yes } = await prompt({
type: 'confirm',
name: 'yes',
@@ -372,6 +394,10 @@ async function getBranch() {
return (await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'])).stdout
}
+/**
+ * @param {string} version
+ * @param {(pkgName: string) => string} getNewPackageName
+ */
function updateVersions(version, getNewPackageName = keepThePackageName) {
// 1. update root package.json
updatePackage(path.resolve(__dirname, '..'), version, getNewPackageName)
@@ -381,8 +407,14 @@ function updateVersions(version, getNewPackageName = keepThePackageName) {
)
}
+/**
+ * @param {string} pkgRoot
+ * @param {string} version
+ * @param {(pkgName: string) => string} getNewPackageName
+ */
function updatePackage(pkgRoot, version, getNewPackageName) {
const pkgPath = path.resolve(pkgRoot, 'package.json')
+ /** @type {Package} */
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))
pkg.name = getNewPackageName(pkg.name)
pkg.version = version
@@ -393,6 +425,12 @@ function updatePackage(pkgRoot, version, getNewPackageName) {
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n')
}
+/**
+ * @param {Package} pkg
+ * @param {'dependencies' | 'peerDependencies'} depType
+ * @param {string} version
+ * @param {(pkgName: string) => string} getNewPackageName
+ */
function updateDeps(pkg, depType, version, getNewPackageName) {
const deps = pkg[depType]
if (!deps) return
@@ -408,6 +446,11 @@ function updateDeps(pkg, depType, version, getNewPackageName) {
})
}
+/**
+ * @param {string} pkgName
+ * @param {string} version
+ * @param {ReadonlyArray} additionalFlags
+ */
async function publishPackage(pkgName, version, additionalFlags) {
if (skippedPackages.includes(pkgName)) {
return
@@ -443,7 +486,7 @@ async function publishPackage(pkgName, version, additionalFlags) {
}
)
console.log(pico.green(`Successfully published ${pkgName}@${version}`))
- } catch (e) {
+ } catch (/** @type {any} */ e) {
if (e.stderr.match(/previously published/)) {
console.log(pico.red(`Skipping already published: ${pkgName}`))
} else {
diff --git a/scripts/utils.js b/scripts/utils.js
index 9429074d7..789e1bcf6 100644
--- a/scripts/utils.js
+++ b/scripts/utils.js
@@ -16,7 +16,13 @@ export const targets = fs.readdirSync('packages').filter(f => {
return true
})
+/**
+ *
+ * @param {ReadonlyArray} partialTargets
+ * @param {boolean | undefined} includeAllMatching
+ */
export function fuzzyMatchTarget(partialTargets, includeAllMatching) {
+ /** @type {Array} */
const matched = []
partialTargets.forEach(partialTarget => {
for (const target of targets) {
@@ -34,7 +40,7 @@ export function fuzzyMatchTarget(partialTargets, includeAllMatching) {
console.log()
console.error(
` ${pico.white(pico.bgRed(' ERROR '))} ${pico.red(
- `Target ${pico.underline(partialTargets)} not found!`
+ `Target ${pico.underline(partialTargets.toString())} not found!`
)}`
)
console.log()
diff --git a/tsconfig.build.json b/tsconfig.build.json
index 43161f91f..c3be79156 100644
--- a/tsconfig.build.json
+++ b/tsconfig.build.json
@@ -11,8 +11,6 @@
"packages/template-explorer",
"packages/sfc-playground",
"packages/dts-test",
- "rollup.config.js",
- "scripts/*",
"playground"
]
}
diff --git a/tsconfig.json b/tsconfig.json
index 931831bda..ced7bbc1e 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -35,8 +35,8 @@
"packages/*/__tests__",
"packages/dts-test",
"packages/vue/jsx-runtime",
+ "scripts/*",
"rollup.*.js",
"playground"
- ],
- "exclude": ["rollup.config.js"]
+ ]
}