mirror of
https://github.com/zhigang1992/esbuild.git
synced 2026-01-12 17:13:19 +08:00
support "useDefineForClassFields" in "tsconfig.json"
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
|
||||
* Add the `--strict:class-fields` option
|
||||
|
||||
This affects the transform for instance and static class fields. In loose mode (the default), class field initialization is transformed to a normal assignment. This is what the TypeScript compiler does by default. However, it doesn't follow the JavaScript specification exactly (e.g. it may call setter methods). Enable `--strict:class-fields` if you need accurate class field initialization.
|
||||
This affects the transform for instance and static class fields. In loose mode (the default), class field initialization is transformed to a normal assignment. This is what the TypeScript compiler does by default. However, it doesn't follow the JavaScript specification exactly (e.g. it may call setter methods). Either enable `--strict:class-fields` or add `useDefineForClassFields` to your `tsconfig.json` file if you need accurate class field initialization.
|
||||
|
||||
Note that you can also just use `--strict` to enable strictness for all transforms instead of using `--strict:...` for each transform.
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ These syntax features are conditionally transformed for older browsers depending
|
||||
}
|
||||
```
|
||||
|
||||
This increases code size and decreases performance, but follows the JavaScript specification more accurately. If you need this accuracy, you should enable the `--strict:class-fields` option.
|
||||
This increases code size and decreases performance, but follows the JavaScript specification more accurately. If you need this accuracy, you should either enable the `--strict:class-fields` option or add the `useDefineForClassFields` flag to your `tsconfig.json` file.
|
||||
|
||||
* **Private member performance**
|
||||
|
||||
|
||||
@@ -47,9 +47,10 @@ type Bundle struct {
|
||||
}
|
||||
|
||||
type parseFlags struct {
|
||||
isEntryPoint bool
|
||||
isDisabled bool
|
||||
ignoreIfUnused bool
|
||||
isEntryPoint bool
|
||||
isDisabled bool
|
||||
ignoreIfUnused bool
|
||||
strictClassFields bool
|
||||
}
|
||||
|
||||
type parseArgs struct {
|
||||
@@ -101,6 +102,11 @@ func parseFile(args parseArgs) {
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the strict class field transform flag to be overridden
|
||||
if args.flags.strictClassFields {
|
||||
args.parseOptions.Strict.ClassFields = true
|
||||
}
|
||||
|
||||
// Get the file extension
|
||||
extension := args.fs.Ext(args.absPath)
|
||||
|
||||
@@ -360,8 +366,9 @@ func ScanBundle(
|
||||
switch resolveResult.Status {
|
||||
case resolver.ResolveEnabled, resolver.ResolveDisabled:
|
||||
flags := parseFlags{
|
||||
isDisabled: resolveResult.Status == resolver.ResolveDisabled,
|
||||
ignoreIfUnused: resolveResult.IgnoreIfUnused,
|
||||
isDisabled: resolveResult.Status == resolver.ResolveDisabled,
|
||||
ignoreIfUnused: resolveResult.IgnoreIfUnused,
|
||||
strictClassFields: resolveResult.StrictClassFields,
|
||||
}
|
||||
prettyPath := res.PrettyPath(resolveResult.AbsolutePath)
|
||||
sourceIndex := maybeParseFile(resolveResult.AbsolutePath, prettyPath, &source, pathRange, flags)
|
||||
|
||||
@@ -2117,3 +2117,67 @@ Foo.s_foo = 123;
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestLowerClassFieldStrictTsconfigJson2020(t *testing.T) {
|
||||
expectBundled(t, bundled{
|
||||
files: map[string]string{
|
||||
"/entry.js": `
|
||||
import loose from './loose'
|
||||
import strict from './strict'
|
||||
console.log(loose, strict)
|
||||
`,
|
||||
"/loose/index.js": `
|
||||
export default class {
|
||||
foo
|
||||
}
|
||||
`,
|
||||
"/loose/tsconfig.json": `
|
||||
{
|
||||
"compilerOptions": {
|
||||
"useDefineForClassFields": false
|
||||
}
|
||||
}
|
||||
`,
|
||||
"/strict/index.js": `
|
||||
export default class {
|
||||
foo
|
||||
}
|
||||
`,
|
||||
"/strict/tsconfig.json": `
|
||||
{
|
||||
"compilerOptions": {
|
||||
"useDefineForClassFields": true
|
||||
}
|
||||
}
|
||||
`,
|
||||
},
|
||||
entryPaths: []string{"/entry.js"},
|
||||
parseOptions: parser.ParseOptions{
|
||||
IsBundling: true,
|
||||
Target: parser.ES2020,
|
||||
},
|
||||
bundleOptions: BundleOptions{
|
||||
IsBundling: true,
|
||||
AbsOutputFile: "/out.js",
|
||||
},
|
||||
expected: map[string]string{
|
||||
"/out.js": `// /loose/index.js
|
||||
class loose_default {
|
||||
constructor() {
|
||||
this.foo = void 0;
|
||||
}
|
||||
}
|
||||
|
||||
// /strict/index.js
|
||||
class strict_default {
|
||||
constructor() {
|
||||
__publicField(this, "foo", void 0);
|
||||
}
|
||||
}
|
||||
|
||||
// /entry.js
|
||||
console.log(loose_default, strict_default);
|
||||
`,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ type ResolveResult struct {
|
||||
// If true, any ES6 imports to this file can be considered to have no side
|
||||
// effects. This means they should be removed if unused.
|
||||
IgnoreIfUnused bool
|
||||
|
||||
// If true, the class field transform should use Object.defineProperty().
|
||||
StrictClassFields bool
|
||||
}
|
||||
|
||||
type Resolver interface {
|
||||
@@ -95,6 +98,15 @@ func (r *resolver) Resolve(sourcePath string, importPath string) (result Resolve
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the "useDefineForClassFields" value from the nearest enclosing
|
||||
// "tsconfig.json" file if present
|
||||
for info := dirInfo; info != nil; info = info.parent {
|
||||
if info.tsConfigJson != nil {
|
||||
result.StrictClassFields = info.tsConfigJson.useDefineForClassFields
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Is this entry itself a symlink?
|
||||
if entry := dirInfo.entries[base]; entry.Symlink != "" {
|
||||
result.AbsolutePath = entry.Symlink
|
||||
@@ -277,6 +289,8 @@ type tsConfigJson struct {
|
||||
// module-style path names and the fallback paths are relative to the
|
||||
// "baseUrl" value in the "tsconfig.json" file.
|
||||
paths map[string][]string
|
||||
|
||||
useDefineForClassFields bool
|
||||
}
|
||||
|
||||
type dirInfo struct {
|
||||
@@ -349,6 +363,13 @@ func (r *resolver) parseJsTsConfig(file string, path string, info *dirInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the "useDefineForClassFields" field
|
||||
if useDefineForClassFieldsJson, _, ok := getProperty(compilerOptionsJson, "useDefineForClassFields"); ok {
|
||||
if useDefineForClassFields, ok := getBool(useDefineForClassFieldsJson); ok {
|
||||
info.tsConfigJson.useDefineForClassFields = useDefineForClassFields
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the "paths" field
|
||||
if pathsJson, pathsKeyLoc, ok := getProperty(compilerOptionsJson, "paths"); ok {
|
||||
if info.tsConfigJson.absPathBaseUrl == nil {
|
||||
|
||||
Reference in New Issue
Block a user