]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
build: reuse const enum data between concurrent rollup builds
authorEvan You <yyx990803@gmail.com>
Mon, 6 Feb 2023 01:35:08 +0000 (09:35 +0800)
committerEvan You <yyx990803@gmail.com>
Mon, 6 Feb 2023 01:35:08 +0000 (09:35 +0800)
rollup.config.js
scripts/build.js
scripts/const-enum.js

index f6ca48dd2669fb7edc69ff6aea97d065c5f41d2d..34a5ac62a3da6ad8d5cced97a847ecc6ea54f644 100644 (file)
@@ -32,7 +32,7 @@ const pkg = require(resolve(`package.json`))
 const packageOptions = pkg.buildOptions || {}
 const name = packageOptions.filename || path.basename(packageDir)
 
-const [enumPlugin, enumDefines] = await constEnum()
+const [enumPlugin, enumDefines] = constEnum()
 
 const outputConfigs = {
   'esm-bundler': {
index 6951c396175c8cfd1883340a4b5e5d46d33d6060..5272c49c388d78abc41d3dfa69ae38546f9faaba 100644 (file)
@@ -17,7 +17,7 @@ nr build core --formats cjs
 */
 
 import fs from 'node:fs/promises'
-import { existsSync, readFileSync } from 'node:fs'
+import { existsSync, readFileSync, rmSync } from 'node:fs'
 import path from 'node:path'
 import minimist from 'minimist'
 import { gzipSync } from 'node:zlib'
@@ -27,6 +27,7 @@ import execa from 'execa'
 import { cpus } from 'node:os'
 import { createRequire } from 'node:module'
 import { targets as allTargets, fuzzyMatchTarget } from './utils.js'
+import { scanEnums } from './const-enum.js'
 
 const require = createRequire(import.meta.url)
 const args = minimist(process.argv.slice(2))
@@ -42,12 +43,17 @@ const commit = execa.sync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7)
 run()
 
 async function run() {
-  if (!targets.length) {
-    await buildAll(allTargets)
-    checkAllSizes(allTargets)
-  } else {
-    await buildAll(fuzzyMatchTarget(targets, buildAllMatching))
-    checkAllSizes(fuzzyMatchTarget(targets, buildAllMatching))
+  const removeCache = scanEnums()
+  try {
+    if (!targets.length) {
+      await buildAll(allTargets)
+      checkAllSizes(allTargets)
+    } else {
+      await buildAll(fuzzyMatchTarget(targets, buildAllMatching))
+      checkAllSizes(fuzzyMatchTarget(targets, buildAllMatching))
+    }
+  } finally {
+    removeCache()
   }
 }
 
index 37924cc64b3922fa6a426ce2f0f82a5a86f50db5..7cac217b7b1d03c90151a956e02f6c647a8d83ba 100644 (file)
  */
 
 import execa from 'execa'
-import { readFileSync } from 'node:fs'
+import {
+  existsSync,
+  readFileSync,
+  rmSync,
+  writeFile,
+  writeFileSync
+} from 'node:fs'
 import { parse } from '@babel/parser'
 import path from 'node:path'
 import MagicString from 'magic-string'
 
+const ENUM_CACHE_PATH = 'temp/enum.json'
+
 function evaluate(exp) {
   return new Function(`return ${exp}`)()
 }
 
-/**
- * @returns {Promise<[import('rollup').Plugin, Record<string, string>]>}
- */
-export async function constEnum() {
+// this is called in the build script entry once
+// so the data can be shared across concurrent Rollup processes
+export function scanEnums() {
   /**
-   * @type {{ ranges: Record<string, [number, number][]>, defines: Record<string, string> }}
+   * @type {{ ranges: Record<string, [number, number][]>, defines: Record<string, string>, ids: string[] }}
    */
   const enumData = {
     ranges: {},
-    defines: {}
+    defines: {},
+    ids: []
   }
 
-  const knowEnums = new Set()
-
   // 1. grep for files with exported const enum
-  const { stdout } = await execa('git', ['grep', `export const enum`])
+  const { stdout } = execa.sync('git', ['grep', `export const enum`])
   const files = [...new Set(stdout.split('\n').map(line => line.split(':')[0]))]
 
   // 2. parse matched files to collect enum info
@@ -70,7 +76,9 @@ export async function constEnum() {
         for (let i = 0; i < decl.members.length; i++) {
           const e = decl.members[i]
           const id = decl.id.name
-          knowEnums.add(id)
+          if (!enumData.ids.includes(id)) {
+            enumData.ids.push(id)
+          }
           const key = e.id.type === 'Identifier' ? e.id.name : e.id.value
           const fullKey = `${id}.${key}`
           const init = e.initializer
@@ -149,9 +157,29 @@ export async function constEnum() {
     }
   }
 
+  // 3. save cache
+  writeFileSync(ENUM_CACHE_PATH, JSON.stringify(enumData))
+
+  return () => {
+    rmSync(ENUM_CACHE_PATH, { force: true })
+  }
+}
+
+/**
+ * @returns {[import('rollup').Plugin, Record<string, string>]}
+ */
+export function constEnum() {
+  if (!existsSync(ENUM_CACHE_PATH)) {
+    throw new Error('enum cache needs to be initialized before creating plugin')
+  }
+  /**
+   * @type {{ ranges: Record<string, [number, number][]>, defines: Record<string, string>, ids: string[] }}
+   */
+  const enumData = JSON.parse(readFileSync(ENUM_CACHE_PATH, 'utf-8'))
+
   // construct a regex for matching re-exports of known const enums
   const reExportsRE = new RegExp(
-    `export {[^}]*?\\b(${[...knowEnums].join('|')})\\b[^]*?}`
+    `export {[^}]*?\\b(${enumData.ids.join('|')})\\b[^]*?}`
   )
 
   // 3. during transform:
@@ -190,7 +218,7 @@ export async function constEnum() {
               if (
                 spec.type === 'ExportSpecifier' &&
                 spec.exportKind !== 'type' &&
-                knowEnums.has(spec.local.name)
+                enumData.ids.includes(spec.local.name)
               ) {
                 const next = node.specifiers[i + 1]
                 if (next) {