]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
build: improve dts rollup output
authorEvan You <yyx990803@gmail.com>
Sat, 4 Feb 2023 03:59:42 +0000 (11:59 +0800)
committerEvan You <yyx990803@gmail.com>
Sat, 4 Feb 2023 03:59:42 +0000 (11:59 +0800)
package.json
pnpm-lock.yaml
rollup.dts.config.js
scripts/const-enum.js

index f4d80ab4e64e804e7b673e4133061f03d28dc9b8..af043f73b5c231972d7d7194e1e5b00089e5d462 100644 (file)
@@ -77,6 +77,7 @@
     "esbuild": "^0.17.4",
     "eslint": "^8.33.0",
     "eslint-plugin-jest": "^27.2.1",
+    "estree-walker": "^2.0.2",
     "execa": "^4.0.2",
     "jsdom": "^21.1.0",
     "lint-staged": "^10.2.10",
index 4d7820f2df431b6eb8d08db382ad5d0166b8b100..f5c2bf38de4cc18de03ea94871f244c4c04c77e5 100644 (file)
@@ -26,6 +26,7 @@ importers:
       esbuild: ^0.17.4
       eslint: ^8.33.0
       eslint-plugin-jest: ^27.2.1
+      estree-walker: ^2.0.2
       execa: ^4.0.2
       jsdom: ^21.1.0
       lint-staged: ^10.2.10
@@ -75,6 +76,7 @@ importers:
       esbuild: 0.17.5
       eslint: 8.33.0
       eslint-plugin-jest: 27.2.1_4vsywjlpuriuw3tl5oq6zy5a64
+      estree-walker: 2.0.2
       execa: 4.1.0
       jsdom: 21.1.0
       lint-staged: 10.5.4
index b245ed210d6b2e8f7fb79255e0e3c86cc0dc35aa..63906c10d17dd1396fc4afeb373b894073458e62 100644 (file)
@@ -1,6 +1,9 @@
 // @ts-check
+import { parse } from '@babel/parser'
 import { existsSync, readdirSync, readFileSync } from 'fs'
+import MagicString from 'magic-string'
 import dts from 'rollup-plugin-dts'
+import { walk } from 'estree-walker'
 
 if (!existsSync('temp/packages')) {
   console.warn(
@@ -31,14 +34,132 @@ export default readdirSync('temp/packages').map(pkg => {
 })
 
 /**
+ * Patch the dts generated by rollup-plugin-dts
+ * 1. remove exports marked as @internal
+ * 2. Convert all types to inline exports
+ *    and remove them from the big export {} declaration
+ *    otherwise it gets weird in vitepress `defineComponent` call with
+ *    "the inferred type cannot be named without a reference"
+ * 3. Append custom agumentations (jsx, macros)
  * @returns {import('rollup').Plugin}
  */
 function patchTypes(pkg) {
   return {
     name: 'patch-types',
     renderChunk(code) {
-      // 1. TODO remove entries marked with @private
-      // 2. append pkg specific types
+      const s = new MagicString(code)
+      const ast = parse(code, {
+        plugins: ['typescript'],
+        sourceType: 'module'
+      })
+
+      /**
+       * @param {import('@babel/types').Node} node
+       * @returns {boolean}
+       */
+      function removeInternal(node) {
+        if (
+          node.leadingComments &&
+          node.leadingComments.some(c => {
+            return c.type === 'CommentBlock' && /@internal\b/.test(c.value)
+          })
+        ) {
+          /** @type {any} */
+          const n = node
+          let id
+          if (n.id && n.id.type === 'Identifier') {
+            id = n.id.name
+          } else if (n.key && n.key.type === 'Identifier') {
+            id = n.key.name
+          }
+          if (id) {
+            s.overwrite(
+              // @ts-ignore
+              node.leadingComments[0].start,
+              node.end,
+              `/* removed internal: ${id} */`
+            )
+          } else {
+            // @ts-ignore
+            s.remove(node.leadingComments[0].start, node.end)
+          }
+          return true
+        }
+        return false
+      }
+
+      const shouldRemoveExport = new Set()
+      // pass 1: remove internals + add exports
+      for (const node of ast.program.body) {
+        if (
+          (node.type === 'TSTypeAliasDeclaration' ||
+            node.type === 'TSInterfaceDeclaration') &&
+          !node.id.name.startsWith(`_`)
+        ) {
+          shouldRemoveExport.add(node.id.name)
+          if (!removeInternal(node)) {
+            // @ts-ignore
+            s.prependLeft(node.start, `export `)
+            // traverse further for internal properties
+            if (node.type === 'TSInterfaceDeclaration') {
+              node.body.body.forEach(removeInternal)
+            } else if (node.type === 'TSTypeAliasDeclaration') {
+              // @ts-ignore
+              walk(node.typeAnnotation, {
+                enter(node) {
+                  // @ts-ignore
+                  if (removeInternal(node)) this.skip()
+                }
+              })
+            }
+          }
+        } else if (removeInternal(node)) {
+          if (node.type === 'VariableDeclaration') {
+            // declare const x
+            for (const decl of node.declarations) {
+              // @ts-ignore
+              shouldRemoveExport.add(decl.id.name)
+            }
+          } else if (
+            node.type === 'TSDeclareFunction' ||
+            node.type === 'TSEnumDeclaration'
+          ) {
+            // declare function
+            // @ts-ignore
+            shouldRemoveExport.add(node.id.name)
+          } else {
+            throw new Error(
+              `unhandled export type marked as @internal: ${node.type}`
+            )
+          }
+        }
+      }
+      // pass 2: remove exports
+      for (const node of ast.program.body) {
+        if (node.type === 'ExportNamedDeclaration' && !node.source) {
+          for (let i = 0; i < node.specifiers.length; i++) {
+            const spec = node.specifiers[i]
+            if (
+              spec.type === 'ExportSpecifier' &&
+              shouldRemoveExport.has(spec.local.name)
+            ) {
+              const next = node.specifiers[i + 1]
+              if (next) {
+                // @ts-ignore
+                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)
+              }
+            }
+          }
+        }
+      }
+      code = s.toString()
+
+      // append pkg specific types
       const additionalTypeDir = `packages/${pkg}/types`
       if (existsSync(additionalTypeDir)) {
         code +=
index b4dbc1770b9733ac83a37890dfcc5f5763643b2b..37924cc64b3922fa6a426ce2f0f82a5a86f50db5 100644 (file)
@@ -192,15 +192,15 @@ export async function constEnum() {
                 spec.exportKind !== 'type' &&
                 knowEnums.has(spec.local.name)
               ) {
-                if (i === 0) {
-                  // first
-                  const next = node.specifiers[i + 1]
+                const next = node.specifiers[i + 1]
+                if (next) {
                   // @ts-ignore
-                  s.remove(spec.start, next ? next.start : spec.end)
+                  s.remove(spec.start, next.start)
                 } else {
-                  // locate the end of prev
+                  // last one
+                  const prev = node.specifiers[i - 1]
                   // @ts-ignore
-                  s.remove(node.specifiers[i - 1].end, spec.end)
+                  s.remove(prev ? prev.end : spec.start, spec.end)
                 }
               }
             }