<p dir="auto">Choose one: is this a bug report or feature request? <strong>feature request</strong></p>

<h3 dir="auto">Input Code</h3>


<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class MyComponent extends React.Component {
  // ...
}"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">MyComponent</span> <span class="pl-k">extends</span> <span class="pl-v">React</span><span class="pl-kos">.</span><span class="pl-c1">Component</span> <span class="pl-kos">{</span>
  <span class="pl-c">// ...</span>
<span class="pl-kos">}</span></pre></div>
<h3 dir="auto">Babel Configuration (.babelrc, package.json, cli command)</h3>

<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;plugins&quot;: [ [ &quot;transform-es2015-classes&quot;, { inline: true, loose: true } ] ]
}"><pre class="notranslate"><span class="pl-kos">{</span>
  <span class="pl-s">"plugins"</span>: <span class="pl-kos">[</span> <span class="pl-kos">[</span> <span class="pl-s">"transform-es2015-classes"</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">inline</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span> <span class="pl-c1">loose</span>: <span class="pl-c1">true</span> <span class="pl-kos">}</span> <span class="pl-kos">]</span> <span class="pl-kos">]</span>
<span class="pl-kos">}</span></pre></div>
<h3 dir="auto">Expected Behavior</h3>


<p dir="auto">Ideally, instead of inserting an <code class="notranslate">inherits</code> function into the scope, the code from the <code class="notranslate">inherits</code> function would be inserted into the compiled class function</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var MyComponent = function(_reactComponent) {
  MyComponent.prototype = Object.create(_reactComponent.prototype);
  MyComponent.prototype.constructor = MyComponent;
  MyComponent.__proto__ = _reactComponent;

  function MyComponent { ... };

  return MyComponent;
}(React.Component);"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-v">MyComponent</span> <span class="pl-c1">=</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-s1">_reactComponent</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-v">MyComponent</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span> <span class="pl-c1">=</span> <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">create</span><span class="pl-kos">(</span><span class="pl-s1">_reactComponent</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-v">MyComponent</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span><span class="pl-kos">.</span><span class="pl-c1">constructor</span> <span class="pl-c1">=</span> <span class="pl-v">MyComponent</span><span class="pl-kos">;</span>
  <span class="pl-v">MyComponent</span><span class="pl-kos">.</span><span class="pl-c1">__proto__</span> <span class="pl-c1">=</span> <span class="pl-s1">_reactComponent</span><span class="pl-kos">;</span>

  <span class="pl-k">function</span> <span class="pl-v">MyComponent</span> <span class="pl-kos">{</span> ... <span class="pl-kos">}</span><span class="pl-kos">;</span>

  <span class="pl-k">return</span> <span class="pl-v">MyComponent</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span><span class="pl-kos">(</span><span class="pl-v">React</span><span class="pl-kos">.</span><span class="pl-c1">Component</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">My basic testing (using the Rollup REPL) seems to imply that that would successfully be tree shaken. However, that is only true for the loose inherits, the full inherits still would not be tree shaken.</p>
<h3 dir="auto">Current Behavior</h3>


<p dir="auto">An <code class="notranslate">inherits</code> function is inserted into the scope and called within the compiled class.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var inherits = function(subClass, superClass) { ... };

var MyComponent = function(_reactComponent) {
  inherits(MyComponent, _reactComponent);

  function MyComponent { ... };

  return MyComponent;
}(React.Component);"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-en">inherits</span> <span class="pl-c1">=</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-s1">subClass</span><span class="pl-kos">,</span> <span class="pl-s1">superClass</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> ... <span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-k">var</span> <span class="pl-v">MyComponent</span> <span class="pl-c1">=</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-s1">_reactComponent</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-en">inherits</span><span class="pl-kos">(</span><span class="pl-v">MyComponent</span><span class="pl-kos">,</span> <span class="pl-s1">_reactComponent</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

  <span class="pl-k">function</span> <span class="pl-v">MyComponent</span> <span class="pl-kos">{</span> ... <span class="pl-kos">}</span><span class="pl-kos">;</span>

  <span class="pl-k">return</span> <span class="pl-v">MyComponent</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span><span class="pl-kos">(</span><span class="pl-v">React</span><span class="pl-kos">.</span><span class="pl-c1">Component</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<h3 dir="auto">Possible Solution</h3>


<p dir="auto">We could pass an <code class="notranslate">inline: true</code> option to the <code class="notranslate">transform-es2015-classes</code> plugin and it would inline the inherits code instead of inserting the helper function into the scope and calling that.</p>
<p dir="auto">I'm not familiar enough with Babel to say whether adding an option to the plugin is a viable solution. Instead, this might have to be done with a separate plugin.</p>
<h3 dir="auto">Context</h3>


<p dir="auto">I was experimenting with moving a project (React Router) to a single file build. Currently, our <code class="notranslate">main</code> and <code class="notranslate">module</code> builds are just the compiled files from our source. This allows users to cherry pick imports so that their bundles only include the files that they want. If we were to switch to a single file, users obviously could no longer cherry pick, so we would want to make our exports tree shake-able to have feature parity.</p>
<p dir="auto">This isn't a React specific problem, but since React now encourages using <code class="notranslate">class &lt;C&gt; extends React.Component</code>, any React component package that does so will have this issue.</p>
<h3 dir="auto">Feature request</h3>
<p dir="auto">Minifiers like Uglify try to remove dead code from minified builds.<br>
To completely remove a declaration, they have to prove that it is side-effect free.<br>
Unfortunately in JS this is often not possible as pretty much anything can have arbitrary effects.</p>
<p dir="auto">An important issue is that ES5 emit for <code class="notranslate">class</code> can't easily be determined to be side-effect free.<br>
As a result, tree-shaking is ineffective. In simple words: no class is removed from the output, even if it is never used.</p>
<p dir="auto">A very simple solution could be to have a hint for the minifier, inside a special comment.<br>
If the emit added a <code class="notranslate">/*#__PURE__*/</code> comment at the beginning of ES5 classes it could easily be detected and removed by Uglify.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="var V6Engine = /*#__PURE__*/(function () {
    function V6Engine() {
    }
    V6Engine.prototype.toString = function () {
        return 'V6';
    };
    return V6Engine;
}());"><pre class="notranslate"><code class="notranslate">var V6Engine = /*#__PURE__*/(function () {
    function V6Engine() {
    }
    V6Engine.prototype.toString = function () {
        return 'V6';
    };
    return V6Engine;
}());
</code></pre></div>
<p dir="auto">This is an important enhancement that can dramatically reduce the size of unused code, especially in large libraries.<br>
Uglify|JS already supports this annotation: <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="203844934" data-permission-text="Title is private" data-url="https://github.com/mishoo/UglifyJS/issues/1448" data-hovercard-type="pull_request" data-hovercard-url="/mishoo/UglifyJS/pull/1448/hovercard" href="https://github.com/mishoo/UglifyJS/pull/1448">mishoo/UglifyJS#1448</a><br>
Original UglifyJS discussion: <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="172331650" data-permission-text="Title is private" data-url="https://github.com/mishoo/UglifyJS/issues/1261" data-hovercard-type="issue" data-hovercard-url="/mishoo/UglifyJS/issues/1261/hovercard" href="https://github.com/mishoo/UglifyJS/issues/1261">mishoo/UglifyJS#1261</a><br>
For reference, implementation details are here: <a class="commit-link" data-hovercard-type="commit" data-hovercard-url="https://github.com/mishoo/UglifyJS/commit/1e51586996ae4fdac68a8ea597c20ab170809c43/hovercard" href="https://github.com/mishoo/UglifyJS/commit/1e51586996ae4fdac68a8ea597c20ab170809c43">mishoo/UglifyJS@<tt>1e51586</tt></a></p>
<p dir="auto">The issue was originally raised at Webpack: <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="171022058" data-permission-text="Title is private" data-url="https://github.com/webpack/webpack/issues/2867" data-hovercard-type="issue" data-hovercard-url="/webpack/webpack/issues/2867/hovercard" href="https://github.com/webpack/webpack/issues/2867">webpack/webpack#2867</a></p>