<p dir="auto">If a helper function is added by a plugin to the top of a file, and that helper function uses a babel-runtime function like <code class="notranslate">Object.keys</code>, the import does not always get converted.</p>
<p dir="auto">This only seems to happen if the helper is added from within a class.</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="const assert = require('assert');
const foo = {a: true};
class MyClass {
  static query = getKeys(foo);
}
assert.deepEqual(MyClass.query, ['a']);"><pre class="notranslate"><span class="pl-k">const</span> <span class="pl-s1">assert</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'assert'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">const</span> <span class="pl-s1">foo</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-c1">a</span>: <span class="pl-c1">true</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">class</span> <span class="pl-v">MyClass</span> <span class="pl-kos">{</span>
  <span class="pl-k">static</span> <span class="pl-c1">query</span> <span class="pl-c1">=</span> <span class="pl-en">getKeys</span><span class="pl-kos">(</span><span class="pl-s1">foo</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>
<span class="pl-s1">assert</span><span class="pl-kos">.</span><span class="pl-en">deepEqual</span><span class="pl-kos">(</span><span class="pl-v">MyClass</span><span class="pl-kos">.</span><span class="pl-c1">query</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-s">'a'</span><span class="pl-kos">]</span><span class="pl-kos">)</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="const buildHelper = template(`
  function GET_KEYS(obj) {
    return Object.keys(obj);
  }
`);

writeFileSync(
  __dirname + '/output.js',
  transformFileSync(__dirname + '/fixture.js', {
    babelrc: false,
    plugins: [
      ({types: t}) =&gt; {
        return {
          visitor: {
            Identifier(path) {
              if (path.node.name === 'getKeys') {
                const identifier = this.file.scope.generateUidIdentifier('getKeys');
                const helper = buildHelper({
                  GET_KEYS: identifier,
                });
                this.file.path.unshiftContainer(&quot;body&quot;, helper);
                path.replaceWith(identifier);
              }
            },
          },
        };
      },
      require(&quot;babel-plugin-transform-class-properties&quot;),
      require(&quot;babel-plugin-transform-es2015-classes&quot;),
      require(&quot;babel-plugin-transform-es2015-modules-commonjs&quot;),
      require(&quot;babel-plugin-transform-runtime&quot;),
    ],
  }).code
);"><pre class="notranslate"><span class="pl-k">const</span> <span class="pl-s1">buildHelper</span> <span class="pl-c1">=</span> <span class="pl-en">template</span><span class="pl-kos">(</span><span class="pl-s">`</span>
<span class="pl-s">  function GET_KEYS(obj) {</span>
<span class="pl-s">    return Object.keys(obj);</span>
<span class="pl-s">  }</span>
<span class="pl-s">`</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-en">writeFileSync</span><span class="pl-kos">(</span>
  <span class="pl-s1">__dirname</span> <span class="pl-c1">+</span> <span class="pl-s">'/output.js'</span><span class="pl-kos">,</span>
  <span class="pl-en">transformFileSync</span><span class="pl-kos">(</span><span class="pl-s1">__dirname</span> <span class="pl-c1">+</span> <span class="pl-s">'/fixture.js'</span><span class="pl-kos">,</span> <span class="pl-kos">{</span>
    <span class="pl-c1">babelrc</span>: <span class="pl-c1">false</span><span class="pl-kos">,</span>
    <span class="pl-c1">plugins</span>: <span class="pl-kos">[</span>
      <span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-c1">types</span>: <span class="pl-s1">t</span><span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
        <span class="pl-k">return</span> <span class="pl-kos">{</span>
          <span class="pl-c1">visitor</span>: <span class="pl-kos">{</span>
            <span class="pl-en">Identifier</span><span class="pl-kos">(</span><span class="pl-s1">path</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
              <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">path</span><span class="pl-kos">.</span><span class="pl-c1">node</span><span class="pl-kos">.</span><span class="pl-c1">name</span> <span class="pl-c1">===</span> <span class="pl-s">'getKeys'</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
                <span class="pl-k">const</span> <span class="pl-s1">identifier</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">file</span><span class="pl-kos">.</span><span class="pl-c1">scope</span><span class="pl-kos">.</span><span class="pl-en">generateUidIdentifier</span><span class="pl-kos">(</span><span class="pl-s">'getKeys'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
                <span class="pl-k">const</span> <span class="pl-s1">helper</span> <span class="pl-c1">=</span> <span class="pl-s1">buildHelper</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
                  <span class="pl-c1">GET_KEYS</span>: <span class="pl-s1">identifier</span><span class="pl-kos">,</span>
                <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
                <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">file</span><span class="pl-kos">.</span><span class="pl-c1">path</span><span class="pl-kos">.</span><span class="pl-en">unshiftContainer</span><span class="pl-kos">(</span><span class="pl-s">"body"</span><span class="pl-kos">,</span> <span class="pl-s1">helper</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
                <span class="pl-s1">path</span><span class="pl-kos">.</span><span class="pl-en">replaceWith</span><span class="pl-kos">(</span><span class="pl-s1">identifier</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
              <span class="pl-kos">}</span>
            <span class="pl-kos">}</span><span class="pl-kos">,</span>
          <span class="pl-kos">}</span><span class="pl-kos">,</span>
        <span class="pl-kos">}</span><span class="pl-kos">;</span>
      <span class="pl-kos">}</span><span class="pl-kos">,</span>
      <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"babel-plugin-transform-class-properties"</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
      <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"babel-plugin-transform-es2015-classes"</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
      <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"babel-plugin-transform-es2015-modules-commonjs"</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
      <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"babel-plugin-transform-runtime"</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
    <span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">code</span>
<span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<h3 dir="auto">Expected Behavior</h3>
<p dir="auto">The output code should have the import statement transformed into a <code class="notranslate">require</code> call.</p>
<h3 dir="auto">Current Behavior</h3>
<p dir="auto">The import statement is left in the output code.</p>
<h3 dir="auto">Possible Solution</h3>
<p dir="auto">Ensure that transform-modules always detects imports, regardless of when they are added.</p>
<h3 dir="auto">Context</h3>


<p dir="auto">I'm attempting to maintain a couple of plugins that add helper functions to the top of files when they detect certain code.</p>
<h3 dir="auto">Your Environment</h3>

<table role="table">
<thead>
<tr>
<th>software</th>
<th>version(s)</th>
</tr>
</thead>
<tbody>
<tr>
<td>Babel</td>
<td>6.24.1</td>
</tr>
<tr>
<td>node</td>
<td>6.4.0</td>
</tr>
<tr>
<td>npm</td>
<td>3.10.3</td>
</tr>
<tr>
<td>Operating System</td>
<td>OSX</td>
</tr>
</tbody>
</table>
<p dir="auto">I've uploaded a complete demonstration of this bug to <a href="https://github.com/ForbesLindesay/demo-transform-runtime-and-es2015-modules-commonjs-order-bug">https://github.com/ForbesLindesay/demo-transform-runtime-and-es2015-modules-commonjs-order-bug</a> so you can easily reproduce it.</p>
<p dir="auto">I'm currently maintaining the 6to5-loader for webpack and I got an <a href="https://github.com/Couto/6to5-loader/issues/3" data-hovercard-type="issue" data-hovercard-url="/babel/babel-loader/issues/3/hovercard">issue</a> where <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/zxcabs/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/zxcabs">@zxcabs</a> suggests to create an extra runtime file, since my loader was generating duplicated code.</p>
<p dir="auto">For debugging purposes, I created a <a href="https://github.com/Couto/6to5-runners-example">repository</a> where I use several 6to5 runners (<a href="https://github.com/Couto/6to5-loader">6to5-loader</a>, <a href="https://github.com/sindresorhus/grunt-6to5">grunt-6to5</a>, <a href="https://github.com/sindresorhus/gulp-6to5">gulp-6to5</a> and the 6to5 cli itself, to convert some example classes.</p>
<p dir="auto">If you ran the scripts on that example, you'll notice that every runner, including the 6to5 cli, will repeat the <code class="notranslate">_extend</code> function in all files that extend a class.</p>
<p dir="auto">My question is, am i doing something wrong? If not, is this a problem?</p>
<p dir="auto">I reckon that gzip should to solve the duplication problem for browsers, but repeating the same code for every file seems a little bit wrong.</p>