这是indexloc提供的服务,不要输入任何密码
Skip to content

fix: ensure compatibility with object keys minification #4036

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

dbl7
Copy link

@dbl7 dbl7 commented Dec 18, 2024

What kind of change does this PR introduce? - Bug fix

Background:

While using advanced JavaScript compilers such as:

  • Google Closure Compiler (Advanced Mode)
  • Terser (with property mangling enabled)
  • Babel Minify (with minify-mangle-names)
  • UglifyJS (with mangle-props option)


The current implementation of the library encounters issues due to direct property access obj.key being transformed during the compilation process. This results in runtime errors because object keys get minified or renamed by the compiler.

Problem Statement:

In most cases, the current approach works well when defining interfaces in TypeScript. Consider the following example:

interface SomeInterface {
  someProperty: string;
}

Advanced JavaScript compilers like Google Closure Compiler or Terser analyze all usages of this interface and minify keys consistently across all instances:

interface SomeInterface {
  someProperty: string;
} 
// After compilation:
interface SomeInterface {
  dO: string; // Minified key
}

However, there are certain edge cases where this behavior causes runtime errors.

Root Cause:

The issue occurs when properties are minified but accessed later using a string literal key:

const foo: SomeInterface = { someProperty: 'prop' };

// After compilation:
console.log(foo);                  // Outputs: { dO: 'prop' }
console.log(foo['someProperty']);  // Outputs: undefined (key is minified)

Since the compiler renames someProperty to dO, any access using the original key foo['someProperty'] will fail because the key no longer exists after minification.

A good example of when defineHiddenProp or hasOwnProperty are used:

export function defineHiddenProp(field: any, prop: string, defaultValue: any) {
  Object.defineProperty(field, prop, { enumerable: false, writable: true, configurable: true });
  field[prop] = defaultValue;
}

if (field.hasOwnProperty('fieldGroup') && !hasKey(field)) {
  defineHiddenProp(field, 'formControl', field.form);
} 

Proposed Solution:

To prevent this, TypeScript’s declare keyword should be used when defining interfaces:

declare interface SomeInterface {
  someProperty: string;
}

Using declare instructs the compiler not to minify properties in this interface, ensuring compatibility with advanced compilers. This change prevents key renaming and resolves potential runtime issues caused by minification.

Please check if the PR fulfills these requirements

By applying this fix, ngx-formly will be more robust, supporting both standard and minified builds without risking property-access issues. Let me know if you need further clarification!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1 participant