Skip to content

Commit

Permalink
Perf(Pack): Enable TypeScript compilerOptions.incremental on watch
Browse files Browse the repository at this point in the history
  • Loading branch information
1aron committed Jul 4, 2023
1 parent adefee5 commit b53f82f
Show file tree
Hide file tree
Showing 9 changed files with 4,150 additions and 544 deletions.
4,575 changes: 4,055 additions & 520 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/pack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,12 @@
"commander": "^10.0.0",
"cross-import": "",
"esbuild": "^0.18.11",
"esbuild-plugin-d.ts": "^1.1.0",
"explore-config": "",
"fast-glob": "^3.2.12",
"i": "^0.3.7",
"lodash.isequal": "^4.5.0",
"npm": "^9.7.2",
"upath": "^2.0.1"
},
"devDependencies": {
Expand Down
49 changes: 27 additions & 22 deletions packages/pack/src/bin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import { program } from 'commander'
import fg from 'fast-glob'
import { execaCommand } from 'execa'
import { type BuildOptions, context, Metafile, build } from 'esbuild'
import log, { chalk } from '@techor/log'
import path from 'upath'
Expand All @@ -18,6 +17,7 @@ import { removeImportSvelteModuleExtensionPlugin } from '../plugins/esbuild-remo
import extend from '@techor/extend'
import { readFileAsJSON } from '@techor/fs'
import exploreConfig from 'explore-config'
import { execaCommand } from 'execa'

const ext2format = {
'js': 'cjs',
Expand All @@ -41,7 +41,6 @@ program.command('pack [entryPaths...]', { isDefault: true })
.option('-w, --watch', 'Rebuild whenever a file changes', false)
.option('-s, --sourcemap', 'Emit a source map', process.env.NODE_ENV === 'production')
.option('-p, --platform <node,browser,neutral>', 'Platform target', 'browser')
.option('-t, --type', 'Emit typescript declarations', pkg.types)
.option('-o, --outdir <dir>', 'The output directory for the build operation', 'dist')
.option('--serve', 'Serve mode starts a web server that serves your code to your browser on your device', false)
.option('-e, --external <packages...>', 'External packages to exclude from the build', externalDependencies)
Expand All @@ -55,6 +54,7 @@ program.command('pack [entryPaths...]', { isDefault: true })
.option('--srcdir <dir>', 'The source directory', 'src')
.option('--target [targets...]', 'This sets the target environment for the generated JavaScript and/or CSS code.')
.option('--mangle-props', 'Pass a regular expression to esbuild to tell esbuild to automatically rename all properties that match this regular expression', '^_')
.option('--no-declare', 'OFF: Emit typescript declarations', !!pkg.types)
.option('--no-bundle', 'OFF: Inline any imported dependencies into the file itself', true)
.option('--no-minify', 'OFF: Minify the generated code')
.option('--no-clean', 'OFF: Clean up the previous output directory before the build starts')
Expand All @@ -73,7 +73,10 @@ program.command('pack [entryPaths...]', { isDefault: true })
}
const addBuildTask = async (eachEntries: string[], eachOptions: { format: string, softBundle?: boolean, ext?: string, platform?: string, outdir?: string, outFile?: string }) => {
const isCSSTask = eachOptions.format === 'css'
const eachOutext = eachOptions.ext || eachOptions.outFile && path.extname(eachOptions.outFile) || undefined
let eachOutExt = eachOptions.ext || eachOptions.outFile && path.extname(eachOptions.outFile) || undefined
if (!eachOutExt) {
eachOutExt = { cjs: options.cjsExt, esm: options.esmExt, iife: options.iifeExt }[eachOptions.format]
}
const external = [
...options.external,
...options.extraExternal
Expand All @@ -86,11 +89,7 @@ program.command('pack [entryPaths...]', { isDefault: true })
const buildOptions: BuildOptions = extend(options, {
outExtension: isCSSTask
? { '.css': '.css' }
: {
'.js': eachOutext
? eachOutext
: { cjs: options.cjsExt, esm: options.esmExt, iife: options.iifeExt }[eachOptions.format]
},
: { '.js': eachOutExt },
logLevel: 'info',
outdir: eachOutdir,
outbase: options.srcdir,
Expand Down Expand Up @@ -162,7 +161,7 @@ program.command('pack [entryPaths...]', { isDefault: true })
for (const outputFilePath in metafile.outputs) {
const eachOutput = metafile.outputs[outputFilePath]
const outputSize = prettyBytes(eachOutput.bytes).replace(/ /g, '')
const eachOutputFormat = metafile.outputs[outputFilePath]['format'] = eachOptions.format
eachOutput['format'] = buildOptions.format
log``
log.i`**${outputFilePath}** ${outputSize} (${Object.keys(eachOutput.inputs).length} inputs)`
}
Expand Down Expand Up @@ -292,28 +291,34 @@ program.command('pack [entryPaths...]', { isDefault: true })
if (!buildTasks.length) {
options.format.map((eachFormat: string) => addBuildTask([path.join(options.srcdir, 'index.ts')], { format: eachFormat }))
}

let typeBuildTask: any
if (options.type) {
if (options.declare) {
typeBuildTask = {
outFile: 'declarations',
options: {
platform: 'type',
format: 'dts'
},
run: () => new Promise<void>((resolve) => {
const runTsc = () => execaCommand(line`
npx tsc --emitDeclarationOnly --preserveWatchOutput --declaration
--outDir ${options.outdir}
${options.watch && '--watch'}
`, {
stdio: 'inherit',
stripFinalNewline: false,
cwd: process.cwd()
})
.catch((reason) => {
process.exit()
const runTsc = () => {
execaCommand(line`
npx tsc
--emitDeclarationOnly
--preserveWatchOutput
--declaration
--outDir ${options.outdir}
${options.watch && '--watch --incremental'}
`, {
stdio: 'inherit',
stripFinalNewline: false,
cwd: process.cwd()
})
.finally(resolve)
.catch((reason) => {
process.exit()
})
.finally(resolve)
}
if (options.watch) {
setTimeout(runTsc, 100)
} else {
Expand Down
10 changes: 10 additions & 0 deletions packages/pack/tests/type/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions packages/pack/tests/type/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "@techor.tests/type",
"private": true,
"sideEffects": false,
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
]
}
11 changes: 11 additions & 0 deletions packages/pack/tests/type/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default class Person {
constructor(
public readonly name: string,
public readonly age: number,
) { }
sex: string
weight: number
height: number
}

const person = new Person('John', 18)
21 changes: 21 additions & 0 deletions packages/pack/tests/type/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { execSync } from 'node:child_process'
import dedent from 'ts-dedent'
import fs from 'fs'
import path from 'path'

beforeAll(() => {
execSync('tsx ../../src/bin pack', { cwd: __dirname, stdio: 'pipe' })
})

it('generates declarations', () => {
expect(fs.readFileSync(path.join(__dirname, 'dist/index.d.ts')).toString()).toEqual(dedent`
export default class Person {
readonly name: string;
readonly age: number;
constructor(name: string, age: number);
sex: string;
weight: number;
height: number;
}\n
`)
})
11 changes: 11 additions & 0 deletions packages/pack/tests/type/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../../../tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"outDir": "dist"
},
"include": [
"src/**/*.ts",
"src/**/*.d.ts"
]
}
4 changes: 2 additions & 2 deletions packages/pack/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"outDir": "dist",
"outDir": "dist"
},
"include": [
"src/**/*.ts",
Expand All @@ -11,4 +11,4 @@
"exclude": [
"src/**/*.test.ts"
]
}
}

0 comments on commit b53f82f

Please sign in to comment.