Skip to content

Expose UglifyJs's mangle property / capability when using aot, optimization, and buildOptimizer. #12028

@christo8989

Description

@christo8989

Bug Report or Feature Request (mark with an x)

- [ ] bug report -> please search issues before submitting
- [x] feature request

Command (mark with an x)

- [ ] new
- [x] build
- [ ] serve
- [ ] test
- [ ] e2e
- [ ] generate
- [ ] add
- [ ] update
- [ ] lint
- [ ] xi18n
- [ ] run
- [ ] config
- [ ] help
- [ ] version
- [ ] doc

Versions

Angular CLI: 6.1.5
Node: 9.11.1
OS: win32 x64
Angular: 6.0.6
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.6.8
@angular-devkit/build-angular     0.6.8
@angular-devkit/build-optimizer   0.6.8
@angular-devkit/core              0.6.8
@angular-devkit/schematics        0.7.5 (cli-only)
@angular/cli                      6.1.5
@ngtools/webpack                  6.0.8
@schematics/angular               0.7.5 (cli-only)
@schematics/update                0.7.5 (cli-only)
rxjs                              6.2.2
typescript                        2.7.2
webpack                           4.8.3

Repro steps

We created an automapper that takes in a string and class name.
When we map, we use the constructor of the class name to create the object.
The production build strips the class names from the code and therefor breaks our automapper.

class Test1 { }
class Test2 { }

let automapper = {}; // dictionary

const addToAutomapper = (from: string, to: Type): void => {
  const key = getKey(from, to);
  if (automapper[key] != null) {
    throw new Error("This mapping already exists");
  }
  
  automapper[key] = new Mapper(); // something like this
}

const getMapper(from: string, to: Type): Mapper => {
  const key = getKey(from, to);
  return automapper[key];
}

const getKey = (from: string, to: Type): void => {
  return from + "[]" + to.constructor.name;
}

addToAutomapper("default", Test1);
addToAutomapper("default", Test2); // error gets thrown due to minification (ng build --prod)

The log given by the failure

The error message is a custom message. It's part of a dictionary class that will throw an error if the key already exists in the dictionary.

core.js:1524 ERROR Error: Uncaught (in promise): Error: The key 'default[]n' already exists. Did you mean to use the method 'put'.
Error: The key 'default[]n' already exists. Did you mean to use the method 'put'.
    at n.add (dictionary.ts:21)
    at n.createMap (automapper.service.ts:23)
    at menu-item.mappings.ts:13
    at S (mappings.ts:25)
    at new n (automapper.service.ts:18)
    at factory (automapper.service.ts.pre-build-optimizer.js:92)
    at core.js:8039
    at To (core.js:7997)
    at ko (core.js:7972)
    at e.get (core.js:8669)
    at n.add (dictionary.ts:21)
    at n.createMap (automapper.service.ts:23)
    at menu-item.mappings.ts:13
    at S (mappings.ts:25)
    at new n (automapper.service.ts:18)
    at factory (automapper.service.ts.pre-build-optimizer.js:92)
    at core.js:8039
    at To (core.js:7997)
    at ko (core.js:7972)
    at e.get (core.js:8669)
    at O (zone.js:814)
    at O (zone.js:771)
    at zone.js:873
    at t.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:3628)
    at t.invokeTask (zone.js:420)
    at e.runTask (zone.js:188)
    at v (zone.js:595)

Desired functionality

I don't care if the names get minified but I would like to be able to use the class name as reference. In my research, that means telling UglifyJs to maintain class names. I notice that's how people are working around it but that's just not acceptable. I can't rely on a manual modification of the (unexposed) build configuration prior to every release or build.

I noticed the same issue here: #5168

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions