Skip to content
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

Unused classes in export remain in bundle even after tree-shaking #2899

Closed
blacksonic opened this Issue Aug 21, 2016 · 36 comments

Comments

Projects
@blacksonic
Copy link

blacksonic commented Aug 21, 2016

I'm submitting a bug report

Webpack version:
2.1.0-beta.21

Please tell us about your environment:
Linux

Current behavior:

I have a class named Car in the file car.ts and two other classes for the engines in another file engine.ts.
car.ts

import { V8Engine, Engine } from './engine';

class SportsCar {
  constructor(private engine: Engine) {}

  toString() {
    return this.engine.toString() + ' Sports Car';
  }
}

engine.ts

export interface Engine {
  toString(): string;
}

export class V6Engine implements Engine {
  toString() {
    return 'V6';
  }
}

export class V8Engine implements Engine {
  toString() {
    return 'V8';
  }
}

export function getVersion() {
  return '1.0';
}

console.log(new SportsCar(new V8Engine()).toString());

The car.ts file only imports the V8Engine class, but the V6Engine class also appears even in the minified file. The unused function i export from engine.ts is stripped.

When running Webpack without UglifyJS plugin, the V6Engine class is marked with /* unused harmony export V6Engine */ as expected.
But after adding the plugin i get this warning message from UglifyJS:

    WARNING in car.prod.bundle.js from UglifyJs
    Dropping unused function getVersion [car.prod.bundle.js:89,9]
    Side effects in initialization of unused variable V6Engine [car.prod.bundle.js:73,132]

I have created a repository where the problem can be reproduced.
Cloning, installing and running npm run webpack and npm run webpack-prod reproduces the issue.

Don't know if this is a bug with the Typescript transpilation, UglifyJS or the orchestration of these tools.
I'm using Typescript with es2015 modules and Webpack 2.

Expected/desired behavior:

The unused class should be removed in the minified file.

  • What is the motivation / use case for changing the behavior?
  • Browser: all
  • Language: TypeScript 2.0-dev
@blacksonic

This comment has been minimized.

Copy link
Author

blacksonic commented Aug 21, 2016

can be caused by also mishoo/UglifyJS2#1261

@TheLarkInn

This comment has been minimized.

Copy link
Member

TheLarkInn commented Aug 21, 2016

I left @mishoo a message asking if he needs any help. This is pretty important to us and there is a large Typescript/Angular2 userbase.

@Jessidhia

This comment has been minimized.

Copy link
Member

Jessidhia commented Aug 22, 2016

If typescript uses an IIFE for initializing the variable, uglify won't know enough to tell it can exclude the function... :/

@TheLarkInn

This comment has been minimized.

Copy link
Member

TheLarkInn commented Aug 22, 2016

@Kovensky I think it is safe to say we should speak with the TS team about this. CC @mhegazy @DanielRosenwasser

@TheLarkInn

This comment has been minimized.

Copy link
Member

TheLarkInn commented Aug 22, 2016

Hey @blacksonic it's not an ideal workaround but would you consider trying to see if you can do ts transpile es6=>es6 and then babel es2015(modules:false) and see if this works. Maybe the way babel transpiles the classes down will yield a more 'removable' result.

@blacksonic

This comment has been minimized.

Copy link
Author

blacksonic commented Aug 22, 2016

@TheLarkInn bad news, it doesnt work with babel either
example repo

@blacksonic

This comment has been minimized.

Copy link
Author

blacksonic commented Aug 22, 2016

Created also a ticket on the Babel repository to let them know this issue exists not only with Typescript.
https://phabricator.babeljs.io/T7566

@Jessidhia

This comment has been minimized.

Copy link
Member

Jessidhia commented Aug 23, 2016

Probably the simplest fix is to have webpack comment out the declaration itself, instead of just marking with unused harmony export, and hoping for the best that the user really did not write something like export const foo = (() => { console.log('exporting foo') })(). That would, however, cause problems if the exported declaration, despite not being used by other modules, was still used internally.

@Jessidhia

This comment has been minimized.

Copy link
Member

Jessidhia commented Aug 23, 2016

Another possible complication is with static class fields that are initialized with a function call.

class Foo {
  static bar = (() => { console.log('side-effect :(') })()
}

Removing the declaration of Foo will also remove the side-effect of the declaration.

Currently, this is transpiled to defining a property in the constructor, so even with "perfect ES6 support" removing the class, the IIFE still runs, but this (and class decorators) might become a problem in the future...

@blacksonic

This comment has been minimized.

Copy link
Author

blacksonic commented Aug 26, 2016

We have a new kid on the block: Babili, it can strip unused classes after bundling.
See example here.
For now i only tried it with ES6 code, but it works. Only drawback it doesnt strip comments, but there is a ticket for that.
babel/minify#67

We might just need a Webpack plugin for Babili.

@blacksonic

This comment has been minimized.

Copy link
Author

blacksonic commented Aug 26, 2016

@lbialy

This comment has been minimized.

Copy link

lbialy commented Dec 26, 2016

Any updates on this guys'n'gals?

@TheLarkInn TheLarkInn added this to the webpack 2.4 Feature release milestone Dec 29, 2016

filipesilva added a commit to filipesilva/angular-cli that referenced this issue Jul 31, 2017

fiX(@ANgular/cli): use 3 uglify passes with build-optimizer
PURE comments work best with 3 passes.
See webpack/webpack#2899 (comment) for context and an example.

Thanks to @kzc for highlighting this.

filipesilva added a commit to filipesilva/angular-cli that referenced this issue Jul 31, 2017

fix(@angular/cli): use 3 uglify passes with build-optimizer
PURE comments work best with 3 passes.
See webpack/webpack#2899 (comment) for context and an example.

Thanks to @kzc for highlighting this.

filipesilva added a commit to angular/angular-cli that referenced this issue Jul 31, 2017

fix(@angular/cli): use 3 uglify passes with build-optimizer
PURE comments work best with 3 passes.
See webpack/webpack#2899 (comment) for context and an example.

Thanks to @kzc for highlighting this.

hansl added a commit to angular/angular-cli that referenced this issue Aug 3, 2017

fix(@angular/cli): use 3 uglify passes with build-optimizer
PURE comments work best with 3 passes.
See webpack/webpack#2899 (comment) for context and an example.

Thanks to @kzc for highlighting this.
@morlay

This comment has been minimized.

Copy link

morlay commented Aug 4, 2017

we can use babel-plugin to force annotate #__PURE__ for call expression in variable declarator.

I feel, call expression in variable declarator should not have side effects.

Maybe we can enable the feature in webpack by default.

@morlay

This comment has been minimized.

Copy link

morlay commented Aug 4, 2017

Btw,
For now webpack@3.4.1 will transform

import { querystring } from "querystring"
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_querystring__ = __webpack_require__(247);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_querystring___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_querystring__);

This will may require unused package, I think we should annotate #__PURE__ to __webpack_require__ in variable declarator

and just ignore

import  "xxx.styl" 

svallory added a commit to cashfarm/angular-advanced-cli that referenced this issue Aug 10, 2017

[v1.3.0] Squashed commit of the following:
commit 346e1f0
Author: Saulo Vallory <me@saulovallory.com>
Date:   Thu Aug 10 11:44:29 2017 -0300

    Fix package name and urls and add yarn lock

commit 36cfa66
Author: Saulo Vallory <me@saulovallory.com>
Date:   Mon Jul 31 18:28:23 2017 -0300

    Update package name and dependency check

commit c98c27c
Author: Saulo Vallory <me@saulovallory.com>
Date:   Mon Jul 31 16:08:26 2017 -0300

    Update README and package info

    # Conflicts:
    #	package.json

commit e8e0330
Author: Saulo Vallory <me@saulovallory.com>
Date:   Fri Jul 28 01:54:54 2017 -0300

    Remove console.log calls and fix file check

commit 23789e8
Author: Saulo Vallory <me@saulovallory.com>
Date:   Fri Jul 28 00:27:48 2017 -0300

    Allow partially overriding webpack config

    If a webpack.config.js file is found in the project root, it's loaded after all other configs so configuration can be overriden.

commit 5b9eb08
Author: Hans Larsen <hans@hansl.ca>
Date:   Wed Aug 9 16:32:30 2017 -0700

    release: v1.3.0

commit 3271ac0
Author: Hans Larsen <hans@hansl.ca>
Date:   Wed Aug 9 15:43:38 2017 -0700

    fix(@angular/cli): update build-optimizer to latest

    Also fixes linting errors. Seems like tslint was updated.

commit f454eb2
Author: Hans Larsen <hans@hansl.ca>
Date:   Wed Aug 2 14:59:14 2017 -0700

    feat(@ngtools/webpack): fix paths mapping support

    This is a similar version of angular#5033. Reverted in angular#6463 because of issue angular#6451.

    This is a feature because we do not want it in 1.3.0

commit c475cf4
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Sat Aug 5 15:32:42 2017 +0100

    fix(@ngtools/webpack): show TS error message when there is no file

commit 349aae8
Author: kevinphelps <KevinPhelps11@gmail.com>
Date:   Thu Aug 3 12:52:35 2017 -0500

    fix(@angular/cli): use correct property names for build config defaults

commit af2d957
Author: Mike Brocchi <mbrocchi@gmail.com>
Date:   Thu Aug 3 18:24:49 2017 -0400

    fix(@angular/cli): Update @angular-devkit/build-optimizer

commit d69d797
Author: Robin Dijkhof <tardijkhof@gmail.com>
Date:   Wed Jul 12 14:25:30 2017 +0200

    fix(@angular/cli): prevent unicode character compression

commit 80dfb0d
Author: S K (xz64) <xz64.xyz@gmail.com>
Date:   Mon Jul 31 20:21:16 2017 -0700

    fix(@angular/cli): fix empty 3rdpartylicenses.txt

    Upgrades license-webpack-plugin from 0.4.x to 0.5.x.

    Closes angular#6921

commit 25a228d
Author: Hans Larsen <hans@hansl.ca>
Date:   Thu Aug 3 12:16:03 2017 -0700

    release: 1.3.0-rc.5

commit 94b11f7
Author: Hans Larsen <hans@hansl.ca>
Date:   Thu Aug 3 11:22:22 2017 -0700

    release: 1.3.0-rc.4

commit fe8b7be
Author: Hans Larsen <hans@hansl.ca>
Date:   Thu Aug 3 11:11:26 2017 -0700

    fix(@angular/cli): update package-lock for build-optimizer

commit 38c064c
Author: Hans <hans@hansl.ca>
Date:   Thu Aug 3 10:25:58 2017 -0700

    fix(@angular/cli): update build-optimizer to latest

commit 2486bf9
Author: sendilkumarn <sendilkumarn@live.com>
Date:   Wed Aug 2 19:02:00 2017 +0800

    fix(@angular/cli): baseHref to accept empty string via cli

commit d0cf4a2
Author: Josh Iverson <jiverson222@gmail.com>
Date:   Wed Aug 2 23:52:54 2017 -0700

    docs: add NamedChunks to dev/prod defaults table

commit 323cd97
Author: Charles Lyding <charles@thunderpos.com>
Date:   Thu Aug 3 11:10:02 2017 -0400

    fix(@angular/cli): sync webpack stats file content options

commit 580deaa
Author: Josh Iverson <jiverson222@gmail.com>
Date:   Thu Aug 3 00:07:02 2017 -0700

    docs: fix material install

commit aa0a59b
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Thu Aug 3 18:01:54 2017 +0100

    fix(@angular/cli): update build-optimizer

    Fix angular#7114
    Fix angular#7110
    Fix angular#7093

commit 555c110
Author: Hans Larsen <hans@hansl.ca>
Date:   Wed Aug 2 13:33:12 2017 -0700

    build: use the tar files for dependencies for e2e

    This adds a new flag to the build script that sets the tar files path as dependencies inside the package.json before tarring the files.

commit 3aecfa7
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Tue Aug 1 19:26:59 2017 +0100

    fix(@angular/cli): remove -bo alias for --build-optimizer

    /cc @StephenFluin

commit 9d56c85
Author: Hans Larsen <hans@hansl.ca>
Date:   Thu Jul 13 11:26:51 2017 -0700

    docs: add more badges

commit 14f9bf6
Author: Justin Grayston <justingrayston@gmail.com>
Date:   Mon Jul 31 15:01:36 2017 +0100

    docs: fix universal dep save flag

    Closes angular#7211

commit 50b5059
Author: Rakhat Jabagin <neilhem@hotmail.com>
Date:   Sat Jul 22 17:59:37 2017 +0600

    docs: add other possible cases to generate in project readme

commit fd88158
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Thu Jul 20 11:00:19 2017 +0100

    build: use npm5 instead of yarn

commit 64a7ca4
Author: Charles Lyding <charles@thunderpos.com>
Date:   Mon Jul 31 23:47:11 2017 -0400

    refactor(@angular/cli): update TS type dependencies

commit 6cfa7c3
Author: christian.scharr <christian.scharr@gmail.com>
Date:   Mon Jul 31 10:03:14 2017 -0400

    fix(@angular/cli): exclude node_modules while take account for os specific path separators (angular#6870)

commit 542f2bd
Author: Christian Scharr <christian.scharr@gmail.com>
Date:   Wed Jul 26 20:45:09 2017 +0200

    fix(@angular/cli): use relative path instead of regex to exclude node_modules (angular#6870)

commit ca98b2b
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Mon Jul 31 15:25:58 2017 +0100

    fix(@angular/cli): show warnings on serve

    Errors and warnings neet to be printed separately.

    Followup to angular#6989
    Fix angular#7213

commit 90a14d5
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Fri Jul 21 14:01:35 2017 +0100

    docs: add SUPPORT.md

    Just contains the `Got a Question or Problem?` section of `CONTRIBUTING.md`.

    See https://github.com/blog/2400-support-file-support for github support.

    Didn't add it to `.github` folder because it's more visible outside, like `CONTRIBUTING.md`.

commit df6d331
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Wed Jul 26 15:51:55 2017 +0100

    fix(@angular/cli): use 3 uglify passes with build-optimizer

    PURE comments work best with 3 passes.
    See webpack/webpack#2899 (comment) for context and an example.

    Thanks to @kzc for highlighting this.

commit a8d3806
Author: yokots <hd.wang1993@gmail.com>
Date:   Fri Jul 28 16:29:10 2017 +0800

    docs: apps[0].lintFix => defaults.lintFix

commit 8257149
Author: cexbrayat <cedric@ninja-squad.com>
Date:   Thu Jul 27 07:14:48 2017 +0200

    fix(@angular/cli): change blog link to blog.angular.io

commit 983b470
Author: Aliaksei Kuncevic <kncvch@gmail.com>
Date:   Thu Jul 27 10:02:58 2017 +1000

    fix(@angular/cli): ignore yarn-error.log directory

commit 8e008e8
Author: Mike Brocchi <mbrocchi@gmail.com>
Date:   Fri Jul 21 16:29:21 2017 -0400

    fix(@angular/cli): Include missing dependency when ejecting

commit a6ac43a
Author: Charles Lyding <charles@thunderpos.com>
Date:   Sun Jul 30 23:14:05 2017 -0400

    fix(@angular/cli): standardize output path behavior

commit 29a7e3f
Author: Kristofer Karlsson <karlsson.kristofer@gmail.com>
Date:   Thu Jul 27 23:10:12 2017 +0200

    docs: Fixed typo in universal story

commit 1d9e07e
Author: AntoineC <aecz@users.noreply.github.com>
Date:   Mon Jul 31 12:45:54 2017 +0200

    fix(@angular/cli): add explicit source-map-support dependency (angular#7191)

    karma plugin relies on source-map-support being a dependency of karma-source-map-support and npm 3+ flat dependency tree.

    pnpm/pnpm#863

commit 27fd95d
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Thu Jul 27 17:14:22 2017 +0100

    release: 1.3.0-rc.3

commit 20c7b2a
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Thu Jul 27 16:53:04 2017 +0100

    Support enhanced resolve (angular#7169)

    * fix(@ngtools/webpack): support enhanced-resolve@3.4.0

    Followup to angular#7123

    * fix(@angular/cli): unpin webpack 3.3.0

    Followup to angular#7130

commit 453f75f
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Wed Jul 26 22:01:40 2017 +0100

    release: 1.3.0-rc.2

commit 0edd99d
Author: Juri Strumpflohner <juri.strumpflohner@gmail.com>
Date:   Fri Jun 23 14:42:28 2017 +0200

    fix(@angular/cli): change blog link to international one

commit 64d4138
Author: Charles Lyding <charles@thunderpos.com>
Date:   Sat Jul 22 13:36:08 2017 -0400

    fix(@angular/cli): prevent .cur file inlining

    IE does not support data URI cursors.

commit 1a6aa53
Author: Charles Lyding <charles@thunderpos.com>
Date:   Sat Jul 22 13:27:53 2017 -0400

    fix(@angular/cli): remove deprecated json-loader

commit dea46c7
Author: Charles Lyding <charles@thunderpos.com>
Date:   Sun Jul 23 10:13:00 2017 -0400

    refactor(@angular/cli): remove magic-string console message

commit 0b86640
Author: Jason Jean <jasonjean1993@gmail.com>
Date:   Wed Jul 26 15:47:49 2017 -0400

    fix(@ngtools/webpack): fix duplicate LAZY_ROUTE_MAP exports (angular#7107)

commit 53ec7d4
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Tue Jul 25 10:50:44 2017 +0100

    docs: add universal rendering

    Add doc file for https://github.com/angular/angular-cli/wiki/stories-universal-rendering

    /cc @alxhub

commit a674b0c
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Tue Jul 25 10:25:32 2017 +0100

    fix(@angular/cli): pin webpack to 3.3.0

    Webpack is updating to `enhanced-resolve@3.4.0` (webpack/webpack@16bf0b6) but the CLI cannot do so yet (see angular#7123).

    This PR pins `webpack@3.3.0` until we are able to update to `enhanced-resolve@^3.4.0`.

commit 38f2135
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Mon Jul 24 19:38:31 2017 +0100

    release: 1.3.0-rc.1

commit 97c7cfb
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Mon Jul 24 19:12:38 2017 +0100

    fix(@ngtools/webpack): pin enhanced-resolve

    See angular#7113 and webpack/enhanced-resolve#98 for context.

    This should be unpinned when a real fix is found.

commit 3da774e
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Fri Jul 21 15:45:07 2017 +0100

    ci: use headless chrome on travis

commit 1c04fd5
Author: Filipe Silva <filipematossilva@gmail.com>
Date:   Fri Jul 21 15:31:51 2017 +0100

    ci: use chrome on travis

commit 260db50
Author: Charles Lyding <charles@thunderpos.com>
Date:   Fri Jul 21 21:03:21 2017 -0400

    refactor: general dependency update

commit 7c2cff8
Author: Hans Larsen <hans@hansl.ca>
Date:   Fri Jul 21 15:17:39 2017 -0700

    release: v1.3.0-rc.0

@sokra sokra modified the milestones: webpack 4, webpack 3 Aug 11, 2017

@sokra

This comment has been minimized.

Copy link
Member

sokra commented Dec 23, 2017

Regarding unused classes: Transpiles (typescript, babel) need to annotate these transpiled class and minimizers need to handle this. webpack isn't involved in this process (we already remove our reference to the export).

This will may require unused package, I think we should annotate #PURE to webpack_require in variable declarator

The spec says side effects in this package need to be evaluated. Annotating it with PURE would be incorrect according to the spec. But webpack 4 allows to opt-in into more aggressive optimization, which will do that. It will remove the module from the bundle.

@sokra sokra closed this Dec 23, 2017

@mhegazy

This comment has been minimized.

Copy link

mhegazy commented Jan 2, 2018

TypeScript 2.5 and later emits an @class comment on classes to inform minifiers that there are transpiled from an ES6 class. See Microsoft/TypeScript#13721 for more details.
It is also worth nothing that to use this with uglify a string-replace plugin is needed to convert to /** @class */ to /*@__PURE__*/. see mishoo/UglifyJS2#2279 for more details.

@kzc

This comment has been minimized.

Copy link

kzc commented Jan 2, 2018

Also worth noting that Babel 7 will emit /*@__PURE__*/ annotations for class IIFEs.

https://babeljs.io/blog/2017/09/12/planning-for-7.0#pure-annotation-in-specific-transforms-for-minifiers

dond2clouds added a commit to d2clouds/speedray-cli that referenced this issue Apr 23, 2018

fix(@angular/cli): use 3 uglify passes with build-optimizer
PURE comments work best with 3 passes.
See webpack/webpack#2899 (comment) for context and an example.

Thanks to @kzc for highlighting this.
@kimamula

This comment has been minimized.

Copy link

kimamula commented May 21, 2018

@kzc I found that if I build @blacksonic's example with webpack 4 using awesome-typescript-loader and plugins: [new UglifyJsPlugin({ uglifyOptions: { compress: { passes: 3 } } })], unused classes can be tree-shaked.

Is this an expected behavior?

If yes, does this mean one does not need to use a string-replace plugin to tree-shake unused classes from TypeScript code as @mhegazy noted if they specify { compress: { passes: 3 } }?

@kzc

This comment has been minimized.

Copy link

kzc commented May 21, 2018

@kimamula If a /*@__PURE__*/ annotation is already emitted for the class IIFE (via Babel 7 or other means) then a string replace step is not required.

@kimamula

This comment has been minimized.

Copy link

kimamula commented May 21, 2018

No, a /*@__PURE__*/ annotation is not emitted.

To reproduce the behavior, uglify the following code (input.js)

/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 646);
/******/ })
/************************************************************************/
/******/ ({

/***/ 646:
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__export_class__ = __webpack_require__(73);

var SportsCar = /** @class */ (function () {
    function SportsCar(engine) {
        this.engine = engine;
    }
    SportsCar.prototype.toString = function () {
        return this.engine.toString() + ' Sports Car';
    };
    return SportsCar;
}());
console.log(new SportsCar(new __WEBPACK_IMPORTED_MODULE_0__export_class__["a" /* V8Engine */]()).toString());


/***/ }),

/***/ 73:
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* unused harmony export V6Engine */
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return V8Engine; });
/* unused harmony export getVersion */
var V6Engine = /** @class */ (function () {
    function V6Engine() {
    }
    V6Engine.prototype.toString = function () {
        return 'V6';
    };
    return V6Engine;
}());

var V8Engine = /** @class */ (function () {
    function V8Engine() {
    }
    V8Engine.prototype.toString = function () {
        return 'V8';
    };
    return V8Engine;
}());

function getVersion() {
    return '1.0';
}


/***/ })

/******/ });

with

$ npx uglifyjs -c passes=3 -- ./input.js

and

$ npx uglifyjs -- ./input.js

and compare the results (I am using uglify-es 3.3.9).
You can find V6Engine in the output of the latter but not in that of the former.

@kimamula

This comment has been minimized.

Copy link

kimamula commented May 22, 2018

@kzc I found your comment mentioning this behavior.

Replacing /** @class */ in JS code transpiled from TS with /*@__PURE__*/ is still required for an effective tree shaking?

@kzc

This comment has been minimized.

Copy link

kzc commented May 22, 2018

uglify-js and uglify-es only recognize /*@__PURE__*/ annotations for IIFEs. Babel 7 emits such annotations.

I don't know how to replace comments in Webpack, but here's an example in Rollup:

rollup/rollup#1763 (comment)

As for Webpack, google for "webpack string replace loader or plugin" to find some equivalent.

@kimamula

This comment has been minimized.

Copy link

kimamula commented May 22, 2018

Well, it seems I'm confusing you. Sorry for my bad English.

I know how to replace comments in webpack. It's not difficult.
What I want to know is whether it's really necessary.
As you described in your comment, it is likely that uglify-js can drop unused side-effect-free class IIFEs even if they are not annotated with /*@__PURE__*/.

@kzc

This comment has been minimized.

Copy link

kzc commented May 22, 2018

it is likely that uglify-js can drop unused side-effect-free class IIFEs even if they are not annotated with /*@__PURE__*/.

I was mistaken. It only worked in trivial cases. You still need to replace the comment text.

@kimamula

This comment has been minimized.

Copy link

kimamula commented May 22, 2018

I understand. Thanks!

@chen86860

This comment has been minimized.

Copy link

chen86860 commented May 25, 2018

The same as me, Could someone can help me :(

ivanivanyuk1993 pushed a commit to ivanivanyuk1993/util-angular that referenced this issue Mar 8, 2019

ivaivanyuk1993
Removed shared/core module structure (core is not required to have si…
…nce services are dependency injected and shared complicates things as its imports is not reliably tree shakeable as stated here https://medium.com/@armno/creating-a-custom-material-module-in-angular-ee6a5e925d30 and here webpack/webpack#2899), added some debug code to work on weak machine that cant run kubernetes and multiple IDEs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.