From 1e86d6d2dde89751b13fb4cc6e44c4dfc2945945 Mon Sep 17 00:00:00 2001 From: Matyas Forian-Szabo Date: Tue, 26 May 2026 15:21:31 +0200 Subject: [PATCH] build: use TSGo (TS 7.0 dev) to speed up building types Also simplify and put timers into the bootstrap script --- package.json | 5 +- packages/__docs__/globals.ts | 3 - .../src/Table/__tests__/Table.test.tsx | 3 +- pnpm-lock.yaml | 113 ++++++++++++++--- regression-test/package-lock.json | 10 +- scripts/bootstrap.js | 120 +++++++++--------- scripts/clean.js | 12 +- 7 files changed, 173 insertions(+), 93 deletions(-) diff --git a/package.json b/package.json index 28168475db..15e51d83ab 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,6 @@ "packages/*" ], "scripts": { - "build:themes": "ui-scripts build-themes", "prestart": "pnpm run bootstrap", "start": "pnpm --filter docs-app start", "start:watch": "pnpm --filter docs-app start:watch", @@ -30,8 +29,9 @@ "build": "pnpm -r --stream build", "build:watch": "pnpm -r --stream build:watch", "build:docs": "pnpm --filter docs-app bundle", + "build:themes": "ui-scripts build-themes", "build:tokens": "ui-scripts generate-all-tokens", - "build:types": "tsc -b tsconfig.references.json", + "build:types": "tsgo -b tsconfig.references.json", "build:ts": "pnpm --filter @instructure/ui-icons prepare-build && pnpm run build:types", "clean": "node scripts/clean.js", "clean-node": "node scripts/clean.js --nuke_node", @@ -76,6 +76,7 @@ "@types/node": "^22", "@types/react": "18.3.26", "@types/react-dom": "18.3.1", + "@typescript/native-preview": "7.0.0-dev.20260526.1", "@vitejs/plugin-react": "^4.5.1", "@vitest/eslint-plugin": "^1.6.14", "babel-plugin-add-import-extension": "^1.6.0", diff --git a/packages/__docs__/globals.ts b/packages/__docs__/globals.ts index 2c74bb5ed6..119ed348fb 100644 --- a/packages/__docs__/globals.ts +++ b/packages/__docs__/globals.ts @@ -34,11 +34,8 @@ import ReactDOM from 'react-dom' import { LoremIpsum } from 'lorem-ipsum' import moment from 'moment' -// @ts-expect-error no type declarations for moment locales side-effect import import 'moment/min/locales' - import { mirrorHorizontalPlacement } from '@instructure/ui-position' - import { getComponentsForVersion } from './versioned-components' import { dark, light } from '@instructure/ui-themes' import { debounce } from '@instructure/debounce' diff --git a/packages/ui-table/src/Table/__tests__/Table.test.tsx b/packages/ui-table/src/Table/__tests__/Table.test.tsx index b853812400..625a66138c 100644 --- a/packages/ui-table/src/Table/__tests__/Table.test.tsx +++ b/packages/ui-table/src/Table/__tests__/Table.test.tsx @@ -209,10 +209,11 @@ describe('', async () => { test test - {/* @ts-ignore error is normal here */} + {/* @ts-expect-error error is normal here */} test test + {/* @ts-expect-error error is normal here */} Foo test test diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e8429b3949..1d8d699633 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -68,6 +68,9 @@ importers: '@types/react-dom': specifier: 18.3.1 version: 18.3.1 + '@typescript/native-preview': + specifier: 7.0.0-dev.20260526.1 + version: 7.0.0-dev.20260526.1 '@vitejs/plugin-react': specifier: ^4.5.1 version: 4.7.0(vite@7.3.1(@types/node@22.19.15)(jiti@2.6.1)(terser@5.48.0)(yaml@2.8.3)) @@ -3703,7 +3706,7 @@ importers: version: link:../command-utils '@instructure/instructure-design-tokens': specifier: github:instructure/instructure-design-tokens - version: https://codeload.github.com/instructure/instructure-design-tokens/tar.gz/9916a91be6b27a8c2d15136d2865e6f69a2d1c08 + version: https://codeload.github.com/instructure/instructure-design-tokens/tar.gz/6085eab6b704bbcaf27a1bf6626ae8d092fce4df '@instructure/pkg-utils': specifier: workspace:* version: link:../pkg-utils @@ -6711,8 +6714,8 @@ packages: '@types/node': optional: true - '@instructure/instructure-design-tokens@https://codeload.github.com/instructure/instructure-design-tokens/tar.gz/9916a91be6b27a8c2d15136d2865e6f69a2d1c08': - resolution: {tarball: https://codeload.github.com/instructure/instructure-design-tokens/tar.gz/9916a91be6b27a8c2d15136d2865e6f69a2d1c08} + '@instructure/instructure-design-tokens@https://codeload.github.com/instructure/instructure-design-tokens/tar.gz/6085eab6b704bbcaf27a1bf6626ae8d092fce4df': + resolution: {tarball: https://codeload.github.com/instructure/instructure-design-tokens/tar.gz/6085eab6b704bbcaf27a1bf6626ae8d092fce4df} version: 1.0.0 '@isaacs/cliui@8.0.2': @@ -7713,6 +7716,53 @@ packages: resolution: {integrity: sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260526.1': + resolution: {integrity: sha512-7kxHwV+zjANOeDn236ob/2nZy72slfid0ukGd0ApVRmDfG3iob4YEO8TuDet1RxNClis+k9l6zaPBJkujczzkA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260526.1': + resolution: {integrity: sha512-V2RY5nKkNyBQMK39lCdG//VvCVwKhibQBhuelIm8TR4P2EduhJHB42ftr6lEVgZjW03qlrAEE/FWwTV6Wku2vA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260526.1': + resolution: {integrity: sha512-IVDSXjEyKgfa1SvwWux77cdb6W4ReycvLM9hYiJv42vzDJRt3g+H4LmaI6Ng+0Lq5syylzpVhJe4nh3logUsag==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/native-preview-linux-arm@7.0.0-dev.20260526.1': + resolution: {integrity: sha512-gEctrS100iZEwZgrJYuVN4pPW922CcozDneNwJkQld3zmFfSeGRLzj9oXCzP1JbMLq2np+DYrIkJ5ErPF1mwlA==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/native-preview-linux-x64@7.0.0-dev.20260526.1': + resolution: {integrity: sha512-3t4r52PTZgRh+dO0me8o4GCPj3PEixtIEC1vqmQxR/JjDunLn4YOFwfDLyNWEflOxauPRKV5pWkSpd6HiBsZfw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260526.1': + resolution: {integrity: sha512-0uR0M92lNwpgOyGBk+eZAAFuCsa3lc2l3IkvGWMo3fkD+eIBb8NwaqIhKpQ9VGvr6xfjJ3uf210j0Vxhl4HcLQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/native-preview-win32-x64@7.0.0-dev.20260526.1': + resolution: {integrity: sha512-UvwEPV9tDgV8GAWkp5Kmq2LRKUlhwtrl0PUpMDOKInaXAndMtUCOQ+aFqd015jPmfNPKs84BRQoQYXyeaHVJDw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + + '@typescript/native-preview@7.0.0-dev.20260526.1': + resolution: {integrity: sha512-ys/rYFNEVb4LZ7zUFxWZ6iv5gnIW29WRv3L9+hJKfAF3d/ekI76B4Ej4dU7odNCFiX85sCotljzq8N0QyruuoA==} + engines: {node: '>=16.20.0'} + hasBin: true + '@vitejs/plugin-react@4.7.0': resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} engines: {node: ^14.18.0 || >=16.0.0} @@ -7812,7 +7862,7 @@ packages: '@xmldom/xmldom@0.7.13': resolution: {integrity: sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==} engines: {node: '>=10.0.0'} - deprecated: this version is no longer supported, please update to at least 0.8.* + deprecated: this version has critical issues, please update to the latest version '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -9205,8 +9255,8 @@ packages: resolution: {integrity: sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==} engines: {node: '>=10.13.0'} - enhanced-resolve@5.22.0: - resolution: {integrity: sha512-xYcDWrpELkFzz9SpZ3PlI6Eu6eD93Yf0WLDRxikGhWJ3MAir2SNZTIVCVZqZ/NUyx8AdMc2gT9C0gPiw18kG+A==} + enhanced-resolve@5.22.1: + resolution: {integrity: sha512-6QEuw3zoX1SJQc7b87aBXke/no+mG2bTBgw29gWMQonLmpEkWoCAVkl+M49e48AZlWzxiDzDZzYdp6kobcyLww==} engines: {node: '>=10.13.0'} enquirer@2.3.6: @@ -12922,8 +12972,8 @@ packages: uglify-js: optional: true - terser-webpack-plugin@5.6.0: - resolution: {integrity: sha512-Eum+5ajkaOhf5KbM26osvv21kLD7BaGqQ1UA4Ami4arYwylmGUQTgHFpHDdmJod1q4QXa66p0to/FBKID+J1vA==} + terser-webpack-plugin@5.6.1: + resolution: {integrity: sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ==} engines: {node: '>= 10.13.0'} peerDependencies: '@minify-html/node': '*' @@ -15459,7 +15509,7 @@ snapshots: optionalDependencies: '@types/node': 22.19.15 - '@instructure/instructure-design-tokens@https://codeload.github.com/instructure/instructure-design-tokens/tar.gz/9916a91be6b27a8c2d15136d2865e6f69a2d1c08': + '@instructure/instructure-design-tokens@https://codeload.github.com/instructure/instructure-design-tokens/tar.gz/6085eab6b704bbcaf27a1bf6626ae8d092fce4df': dependencies: glob: 13.0.6 @@ -16643,6 +16693,37 @@ snapshots: '@typescript-eslint/types': 8.59.2 eslint-visitor-keys: 5.0.1 + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260526.1': + optional: true + + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260526.1': + optional: true + + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260526.1': + optional: true + + '@typescript/native-preview-linux-arm@7.0.0-dev.20260526.1': + optional: true + + '@typescript/native-preview-linux-x64@7.0.0-dev.20260526.1': + optional: true + + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260526.1': + optional: true + + '@typescript/native-preview-win32-x64@7.0.0-dev.20260526.1': + optional: true + + '@typescript/native-preview@7.0.0-dev.20260526.1': + optionalDependencies: + '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20260526.1 + '@typescript/native-preview-darwin-x64': 7.0.0-dev.20260526.1 + '@typescript/native-preview-linux-arm': 7.0.0-dev.20260526.1 + '@typescript/native-preview-linux-arm64': 7.0.0-dev.20260526.1 + '@typescript/native-preview-linux-x64': 7.0.0-dev.20260526.1 + '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260526.1 + '@typescript/native-preview-win32-x64': 7.0.0-dev.20260526.1 + '@vitejs/plugin-react@4.7.0(vite@7.3.1(@types/node@22.19.15)(jiti@2.6.1)(terser@5.48.0)(yaml@2.8.3))': dependencies: '@babel/core': 7.29.0 @@ -18328,7 +18409,7 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.3.3 - enhanced-resolve@5.22.0: + enhanced-resolve@5.22.1: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 @@ -22912,7 +22993,7 @@ snapshots: optionalDependencies: esbuild: 0.28.0 - terser-webpack-plugin@5.6.0(esbuild@0.28.0)(webpack@5.107.2(esbuild@0.28.0)): + terser-webpack-plugin@5.6.1(esbuild@0.28.0)(webpack@5.107.2(esbuild@0.28.0)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 @@ -22922,7 +23003,7 @@ snapshots: optionalDependencies: esbuild: 0.28.0 - terser-webpack-plugin@5.6.0(esbuild@0.28.0)(webpack@5.107.2): + terser-webpack-plugin@5.6.1(esbuild@0.28.0)(webpack@5.107.2): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 @@ -23553,7 +23634,7 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.22.0 + enhanced-resolve: 5.22.1 es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -23564,7 +23645,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 - terser-webpack-plugin: 5.6.0(esbuild@0.28.0)(webpack@5.107.2(esbuild@0.28.0)) + terser-webpack-plugin: 5.6.1(esbuild@0.28.0)(webpack@5.107.2(esbuild@0.28.0)) watchpack: 2.5.1 webpack-sources: 3.5.0 transitivePeerDependencies: @@ -23592,7 +23673,7 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.22.0 + enhanced-resolve: 5.22.1 es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -23603,7 +23684,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 - terser-webpack-plugin: 5.6.0(esbuild@0.28.0)(webpack@5.107.2) + terser-webpack-plugin: 5.6.1(esbuild@0.28.0)(webpack@5.107.2) watchpack: 2.5.1 webpack-sources: 3.5.0 optionalDependencies: diff --git a/regression-test/package-lock.json b/regression-test/package-lock.json index 7ada967bc6..a6181e298a 100644 --- a/regression-test/package-lock.json +++ b/regression-test/package-lock.json @@ -30,13 +30,13 @@ }, "../packages/browserslist-config-instui": { "name": "@instructure/browserslist-config-instui", - "version": "11.7.2", + "version": "11.7.3", "dev": true, "license": "MIT" }, "../packages/ui": { "name": "@instructure/ui", - "version": "11.7.2", + "version": "11.7.3", "license": "MIT", "dependencies": { "@babel/runtime": "^7.29.2", @@ -124,7 +124,7 @@ }, "../packages/ui-icons": { "name": "@instructure/ui-icons", - "version": "11.7.2", + "version": "11.7.3", "license": "MIT", "dependencies": { "@babel/runtime": "^7.29.2", @@ -146,7 +146,7 @@ }, "../packages/ui-scripts": { "name": "@instructure/ui-scripts", - "version": "11.7.2", + "version": "11.7.3", "license": "MIT", "dependencies": { "@babel/cli": "^7.27.2", @@ -3534,7 +3534,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -4207,7 +4206,6 @@ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js index f0fff85c5d..b5e1fb7c54 100755 --- a/scripts/bootstrap.js +++ b/scripts/bootstrap.js @@ -23,71 +23,75 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -const { execSync, fork } = require('child_process') +const { execSync } = require('child_process') const path = require('path') const opts = { stdio: 'inherit' } -function buildProject() { - console.info('Fetching design tokens...') - try { - execSync( - 'pnpm --filter @instructure/ui-scripts update @instructure/instructure-design-tokens', - opts - ) - } catch (error) { - console.error( - "'pnpm --filter @instructure/ui-scripts update @instructure/instructure-design-tokens' failed", - error - ) - process.exit(1) - } - console.info('Building themes...') - try { - execSync('pnpm run build:themes', opts) - } catch (error) { - console.error("'pnpm run build:themes' failed", error) - process.exit(1) - } +function format(ms) { + return `${(ms / 1000).toFixed(1)}s` +} - execSync('pnpm --filter @instructure/ui-icons prepare-build', opts) - - // Executes a ui-codemods script to generate a versioned components list - // from the ui metapackage's latest re-export file. This is required for - // the updateInstUIImportVersions codemod's diagnose mode. - execSync( - 'pnpm --filter @instructure/ui-codemods generate:versioned-exports', - opts - ) - - console.info('Building packages with Babel...') - try { - execSync('pnpm run build', opts) - } catch (error) { - console.error("'pnpm run build' failed", error) - process.exit(1) +function mark(name) { + console.log(`\n================================================`) + console.log(`${name}...`) + if (steps.length) { + steps[steps.length - 1].duration = + Date.now() - steps[steps.length - 1].start } + steps.push({ name, start: Date.now(), duration: 0 }) +} - console.info('Generating tokens...') - try { - execSync('pnpm run build:tokens', opts) - } catch (error) { - console.error("'pnpm run build:tokens' failed", error) - process.exit(1) - } +const steps = [] +const bootstrapStart = Date.now() - console.info('Building TypeScript declarations...') - try { - execSync('pnpm run build:types', opts) - } catch (error) { - console.error("'pnpm run build:types' failed", error) - process.exit(1) - } -} +mark('Deleting build artifacts') +execSync(path.resolve('scripts/clean.js'), opts) -function bootstrap() { - execSync(path.resolve('scripts/clean.js'), opts) - buildProject() -} +mark('Fetching design tokens') +execSync( + 'pnpm --filter @instructure/ui-scripts update @instructure/instructure-design-tokens', + opts +) + +mark('Building themes') +execSync('pnpm run build:themes', opts) -bootstrap() +mark('Preparing icons') +execSync('pnpm --filter @instructure/ui-icons prepare-build', opts) + +mark('Generating package list for codemods') +execSync( + 'pnpm --filter @instructure/ui-codemods generate:versioned-exports', + opts +) + +mark('Building packages with Babel') +execSync('pnpm run build', opts) + +mark('Generating design tokens') +execSync('pnpm run build:tokens', opts) + +mark('Building TypeScript declarations') +execSync('pnpm run build:types', opts) + +// Log build time summary. Assumes that the build is not parallel +steps[steps.length - 1].duration = Date.now() - steps[steps.length - 1].start + +const total = Date.now() - bootstrapStart +const nameW = Math.max(...steps.map((s) => s.name.length)) +const durW = Math.max( + ...steps.map((s) => format(s.duration).length), + format(total).length +) +const tableWidth = nameW + durW + 7 + +console.log('\n' + '='.repeat(tableWidth)) +console.log(' Bootstrap Summary') +console.log('='.repeat(tableWidth)) +for (const s of steps) { + console.log(` ${s.name.padEnd(nameW)} ${format(s.duration).padStart(durW)}`) +} +console.log('-'.repeat(tableWidth)) +console.log(` ${'Total'.padEnd(nameW)} ${format(total).padStart(durW)}`) +console.log('='.repeat(tableWidth)) diff --git a/scripts/clean.js b/scripts/clean.js index 62da14da4e..d32ef0dd78 100755 --- a/scripts/clean.js +++ b/scripts/clean.js @@ -28,12 +28,10 @@ const path = require('path') const { execSync } = require('child_process') const NODE_PACKAGES = [ - 'ui-icons-build', 'ui-babel-preset', 'ui-codemods', 'ui-scripts', 'command-utils', - 'instui-cli', 'babel-plugin-transform-imports', 'pkg-utils' ] @@ -61,7 +59,7 @@ async function deleteDirs(dirs = []) { ) } -// deletes built files from tooling packages (NODE_PACKAGES const) +// deletes build artifacts from all packages async function clean() { const packagesPath = path.resolve('./packages') const packageDirs = await fs.readdir(packagesPath, { withFileTypes: true }) @@ -88,7 +86,7 @@ async function clean() { function removeNodeModules() { try { // Use native find command - 10-100x faster than Node.js recursive scan - console.error('Finding node_modules directories...') + console.info('Finding node_modules directories...') execSync( 'find . -name "node_modules" -type d -prune -exec rm -rf {} + 2>/dev/null || true', { stdio: 'inherit' } @@ -100,17 +98,17 @@ function removeNodeModules() { } async function main() { - console.error('Deleting built files from tooling packages...') + console.info('Deleting build artifacts...') await clean() const args = process.argv.slice(2) if (args.length > 0 && args[0] === '--nuke_node') { - console.error('Deleting node_modules recursively...') + console.info('Deleting node_modules recursively...') removeNodeModules() } } main().catch((error) => { - console.error('Clean script failed:', error) + console.info('clean.js failed:', error) process.exit(1) })