<p dir="auto">I originally reported this against a downstream project: <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="58491949" data-permission-text="Title is private" data-url="https://github.com/hailocab/react-pure/issues/2" data-hovercard-type="issue" data-hovercard-url="/hailocab/react-pure/issues/2/hovercard" href="https://github.com/hailocab/react-pure/issues/2">hailocab/react-pure#2</a></p>
<p dir="auto">I think it's terrific that Babel doesn't just dump the entire external helpers file everywhere, or requires the whole thing to be used by every project, because that's effectively what traceur ends up doing and for small projects it ends up being quite bloated.</p>
<p dir="auto">However, I've noticed that a small set of helpers is being duplicated across every file in the aforementioned project.  I've read about helpers here:<br>
<a href="https://babeljs.io/docs/usage/external-helpers/" rel="nofollow">https://babeljs.io/docs/usage/external-helpers/</a></p>
<p dir="auto">There doesn't seem to actually be a way to disable the helpers. The default behaviour seems to be:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="babel --external-helpers"><pre class="notranslate">babel --external-helpers</pre></div>
<p dir="auto">and the following doesn't change the behaviour:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="babel --no-external-helpers"><pre class="notranslate">babel --no-external-helpers</pre></div>
<p dir="auto">Is there a way to have Babel output a deduplicated centralised module (or modules) for the tailored set of helpers, and automatically have <code class="notranslate">require()</code> statements injected into the output where the duplicated content used to be?</p>
<h2 dir="auto">Bug Report</h2>
<p dir="auto"><strong>Current Behavior</strong><br>
When encountering a <code class="notranslate">declare</code> statement for an identifier that's already in scope, Babel throws up. The upstream TypeScript compiler understands this syntax.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="{ SyntaxError: /Users/ec/Sync/Code/excmd/src/interface.ts: Identifier 'Something'
    has already been declared (3:14)

   1 | import Something from './somewhere.js'
   2 | 
&gt;  3 | declare class Something {
     |               ^
   4 |    // ...
   5 | }
    at Object.raise (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:6325:17)
    at TypeScriptScopeHandler.checkRedeclarationInScope (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:3759:12)
    at TypeScriptScopeHandler.declareName (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:3725:12)
    at TypeScriptScopeHandler.declareName (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:3835:11)
    at Object.checkLVal (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:8021:22)
    at Object.checkLVal (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:5727:15)
    at Object.parseClassId (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:10855:14)
    at Object.parseClassId (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:5508:11)
    at Object.parseClass (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:10572:10)
    at Object.tsTryParseDeclare (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:4984:21)
  pos: 1216,
  loc: Position { line: 3, column: 14 },
  code: 'BABEL_PARSE_ERROR' }"><pre class="notranslate"><code class="notranslate">{ SyntaxError: /Users/ec/Sync/Code/excmd/src/interface.ts: Identifier 'Something'
    has already been declared (3:14)

   1 | import Something from './somewhere.js'
   2 | 
&gt;  3 | declare class Something {
     |               ^
   4 |    // ...
   5 | }
    at Object.raise (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:6325:17)
    at TypeScriptScopeHandler.checkRedeclarationInScope (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:3759:12)
    at TypeScriptScopeHandler.declareName (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:3725:12)
    at TypeScriptScopeHandler.declareName (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:3835:11)
    at Object.checkLVal (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:8021:22)
    at Object.checkLVal (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:5727:15)
    at Object.parseClassId (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:10855:14)
    at Object.parseClassId (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:5508:11)
    at Object.parseClass (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:10572:10)
    at Object.tsTryParseDeclare (/Users/ec/Sync/Code/excmd/node_modules/@babel/parser/lib/index.js:4984:21)
  pos: 1216,
  loc: Position { line: 3, column: 14 },
  code: 'BABEL_PARSE_ERROR' }
</code></pre></div>
<p dir="auto"><strong>Input Code</strong></p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import Something from './somewhere.js'

declare class Something {
   // ...
}"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-smi">Something</span> <span class="pl-k">from</span> <span class="pl-s">'./somewhere.js'</span>

<span class="pl-k">declare</span> <span class="pl-k">class</span> <span class="pl-smi">Something</span> <span class="pl-kos">{</span>
   <span class="pl-c">// ...</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto"><strong>Expected behavior/code</strong><br>
As with <code class="notranslate">tsc</code>, this should have no effect on the produced code; these declarations are essentially "inline .d.ts" for non-TypeScript imports. To satisfy the current Babel, I guess I'll need to extract these declarations into additional <code class="notranslate">.d.ts</code> files, and check those into my source-control; but as I only have a single TypeScript file in my codebase, I'd <em>really</em> prefer to keep the typings for other modules centralized to that single TypeScript file!</p>
<p dir="auto"><strong>Babel Configuration (.babelrc, package.json, cli command)</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// .babelrc
{
   &quot;presets&quot;: [&quot;@babel/env&quot;, &quot;@babel/preset-typescript&quot;]
}

// CLI invocation
babel --verbose src --extensions '.ts,.js' --ignore '**/*.bs.js' --ignore '**/*.d.ts' --copy-files --out-dir lib"><pre class="notranslate"><span class="pl-c">// .babelrc</span>
<span class="pl-kos">{</span>
   <span class="pl-s">"presets"</span>: <span class="pl-kos">[</span><span class="pl-s">"@babel/env"</span><span class="pl-kos">,</span> <span class="pl-s">"@babel/preset-typescript"</span><span class="pl-kos">]</span>
<span class="pl-kos">}</span>

<span class="pl-c">// CLI invocation</span>
<span class="pl-s1">babel</span> <span class="pl-c1">--</span><span class="pl-s1">verbose</span> <span class="pl-s1">src</span> <span class="pl-c1">--</span><span class="pl-s1">extensions</span> <span class="pl-s">'.ts,.js'</span> <span class="pl-c1">--</span><span class="pl-s1">ignore</span> <span class="pl-s">'**/*.bs.js'</span> <span class="pl-c1">--</span><span class="pl-s1">ignore</span> <span class="pl-s">'**/*.d.ts'</span> <span class="pl-c1">--</span><span class="pl-s1">copy</span><span class="pl-c1">-</span><span class="pl-s1">files</span> <span class="pl-c1">--</span><span class="pl-s1">out</span><span class="pl-c1">-</span><span class="pl-s1">dir</span> <span class="pl-s1">lib</span></pre></div>
<p dir="auto"><strong>Environment</strong></p>
<ul dir="auto">
<li>Babel version(s): <strong>7.5.5</strong> (@babel/core 7.5.5)</li>
<li>Node/npm version: <strong>v10.12.0</strong></li>
<li>OS: macOS <strong>10.14.5</strong></li>
<li>How you are using Babel: <code class="notranslate">cli</code></li>
</ul>
<p dir="auto"><strong>Additional context/Screenshots</strong><br>
The above example is somewhat massaged / simplified from my actual codebase I can't even get the web-playground (with "TypeScript" enabled!) to parse a <em>simple</em> <code class="notranslate">declare class Blah</code>, but I would have included a working example if I could.</p>