Skip to content

Commit

Permalink
fix #226: custom tsconfig.json paths
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Jul 11, 2020
1 parent e2a341c commit 9ac27fa
Show file tree
Hide file tree
Showing 11 changed files with 53 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
A `tsconfig.json` file can inherit configurations from another file using the `extends` property. Before this release, esbuild didn't support this property and any inherited settings were missing. Now esbuild should include these inherited settings.
* Allow manually overriding `tsconfig.json` ([#226](https://github.com/evanw/esbuild/issues/226))
Normally esbuild finds the appropriate `tsconfig.json` file by walking up the directory tree. This release adds the `--tsconfig=...` flag which lets you disable this feature and force esbuild to use the provided configuration file instead. This corresponds to the TypeScript compiler's `--project` flag.
## 0.6.0
* Output directory may now contain nested directories ([#224](https://github.com/evanw/esbuild/issues/224))
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ Advanced options:
--metafile=... Write metadata about the build to a JSON file
--strict Transforms handle edge cases but have more overhead
--pure=N Mark the name N as a pure function for tree shaking
--tsconfig=... Use this tsconfig.json file instead of other ones
Examples:
# Produces dist/entry_point.js and dist/entry_point.js.map
Expand Down
1 change: 1 addition & 0 deletions cmd/esbuild/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Advanced options:
--metafile=... Write metadata about the build to a JSON file
--strict Transforms handle edge cases but have more overhead
--pure=N Mark the name N as a pure function for tree shaking
--tsconfig=... Use this tsconfig.json file instead of other ones
Examples:
# Produces dist/entry_point.js and dist/entry_point.js.map
Expand Down
1 change: 1 addition & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ type Options struct {
AbsOutputFile string
AbsOutputDir string
ModuleName string
TsConfigOverride string
ExtensionToLoader map[string]Loader
OutputFormat Format

Expand Down
15 changes: 10 additions & 5 deletions internal/resolver/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,11 +591,16 @@ func (r *resolver) dirInfoUncached(path string) *dirInfo {
}
}

// Record if this directory has a tsconfig.json or jsconfig.json file
if entries["tsconfig.json"].Kind == fs.FileEntry {
info.tsConfigJson, _ = r.parseJsTsConfig(r.fs.Join(path, "tsconfig.json"), path, make(map[string]bool))
} else if entries["jsconfig.json"].Kind == fs.FileEntry {
info.tsConfigJson, _ = r.parseJsTsConfig(r.fs.Join(path, "jsconfig.json"), path, make(map[string]bool))
if forceTsConfig := r.options.TsConfigOverride; forceTsConfig == "" {
// Record if this directory has a tsconfig.json or jsconfig.json file
if entries["tsconfig.json"].Kind == fs.FileEntry {
info.tsConfigJson, _ = r.parseJsTsConfig(r.fs.Join(path, "tsconfig.json"), path, make(map[string]bool))
} else if entries["jsconfig.json"].Kind == fs.FileEntry {
info.tsConfigJson, _ = r.parseJsTsConfig(r.fs.Join(path, "jsconfig.json"), path, make(map[string]bool))
}
} else if parentInfo == nil {
// If there is a tsconfig.json override, mount it at the root directory
info.tsConfigJson, _ = r.parseJsTsConfig(forceTsConfig, r.fs.Dir(forceTsConfig), make(map[string]bool))
}

// Is the "main" field from "package.json" missing?
Expand Down
1 change: 1 addition & 0 deletions lib/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ function flagsForBuildOptions(options: types.BuildOptions, isTTY: boolean): [str
if (options.outdir) flags.push(`--outdir=${options.outdir}`);
if (options.platform) flags.push(`--platform=${options.platform}`);
if (options.format) flags.push(`--format=${options.format}`);
if (options.tsconfig) flags.push(`--tsconfig=${options.tsconfig}`);
if (options.resolveExtensions) flags.push(`--resolve-extensions=${options.resolveExtensions.join(',')}`);
if (options.external) for (let name of options.external) flags.push(`--external:${name}`);
if (options.loader) for (let ext in options.loader) flags.push(`--loader:${ext}=${options.loader[ext]}`);
Expand Down
1 change: 1 addition & 0 deletions lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export interface BuildOptions extends CommonOptions {
loader?: { [ext: string]: Loader };
resolveExtensions?: string[];
write?: boolean;
tsconfig?: string;

entryPoints?: string[];
stdin?: StdinOptions;
Expand Down
1 change: 1 addition & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ type BuildOptions struct {
Externals []string
Loaders map[string]Loader
ResolveExtensions []string
Tsconfig string

EntryPoints []string
Stdin *StdinOptions
Expand Down
1 change: 1 addition & 0 deletions pkg/api/api_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ func buildImpl(buildOpts BuildOptions) BuildResult {
ExtensionToLoader: validateLoaders(log, buildOpts.Loaders),
ExtensionOrder: validateResolveExtensions(log, buildOpts.ResolveExtensions),
ExternalModules: validateExternals(log, realFS, buildOpts.Externals),
TsConfigOverride: validatePath(log, realFS, buildOpts.Tsconfig),
}
entryPaths := make([]string, len(buildOpts.EntryPoints))
for i, entryPoint := range buildOpts.EntryPoints {
Expand Down
3 changes: 3 additions & 0 deletions pkg/cli/cli_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ func parseOptionsImpl(osArgs []string, buildOpts *api.BuildOptions, transformOpt
case strings.HasPrefix(arg, "--outdir=") && buildOpts != nil:
buildOpts.Outdir = arg[len("--outdir="):]

case strings.HasPrefix(arg, "--tsconfig=") && buildOpts != nil:
buildOpts.Tsconfig = arg[len("--tsconfig="):]

case strings.HasPrefix(arg, "--define:"):
value := arg[len("--define:"):]
equals := strings.IndexByte(value, '=')
Expand Down
29 changes: 29 additions & 0 deletions scripts/js-api-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,35 @@ export {
const stdinResult = require(path.join(outdir, path.basename('stdin.js')))
assert.strictEqual(stdinResult.fromStdin, 123)
},

async forceTsConfig({ esbuild, testDir }) {
// ./tsconfig.json
// ./a/forced-config.json
// ./a/b/test-impl.js
// ./a/b/c/in.js
const aDir = path.join(testDir, 'a')
const bDir = path.join(aDir, 'b')
const cDir = path.join(bDir, 'c')
await mkdirAsync(aDir).catch(x => x)
await mkdirAsync(bDir).catch(x => x)
await mkdirAsync(cDir).catch(x => x)
const input = path.join(cDir, 'in.js')
const forced = path.join(bDir, 'test-impl.js')
const tsconfigIgnore = path.join(testDir, 'tsconfig.json')
const tsconfigForced = path.join(aDir, 'forced-config.json')
const output = path.join(testDir, 'out.js')
await writeFileAsync(input, 'import "test"')
await writeFileAsync(forced, 'console.log("success")')
await writeFileAsync(tsconfigIgnore, '{"compilerOptions": {"baseUrl": "./a", "paths": {"test": ["./ignore.js"]}}}')
await writeFileAsync(tsconfigForced, '{"compilerOptions": {"baseUrl": "./b", "paths": {"test": ["./test-impl.js"]}}}')
await esbuild.build({ entryPoints: [input], bundle: true, outfile: output, tsconfig: tsconfigForced, format: 'esm' })
const result = await readFileAsync(output, 'utf8')
assert.strictEqual(result, `// scripts/.js-api-tests/forceTsConfig/a/b/test-impl.js
console.log("success");
// scripts/.js-api-tests/forceTsConfig/a/b/c/in.js
`)
},
}

async function futureSyntax(service, js, targetBelow, targetAbove) {
Expand Down

0 comments on commit 9ac27fa

Please sign in to comment.