Esbuild: exporting default type should remove in build output

Created on 4 Aug 2020  路  3Comments  路  Source: evanw/esbuild

on build output the type didnt remove, i think this should be remove since the output is plain javascript

./src/types.ts

type ReaderConfig = {
  source: ReaderSource
};

export enum ReaderSource {
  Figma = 'figma'
}

export default ReaderConfig

./src/index.ts

import ReaderConfig, { ReaderSource } from './types'

const a: ReaderConfig = {
  source: ReaderSource.Figma
}

export { a }

build-script.js

  const { buildSync } = require('esbuild')

  const {outputFiles} = buildSync({
    entryPoints: [ './src/index.ts' ],
    outdir: "./dist",
    minify: false,
    bundle: true,
    write: false,
    target: "esnext",
    sourcemap: false,
    format: 'esm'
  })

  console.log(Buffer.from(outputFiles[0].contents).toString())

actual output

// src/types.ts
var ReaderSource;
(function(ReaderSource2) {
  ReaderSource2["Figma"] = "figma";
})(ReaderSource || (ReaderSource = {}));
var types_default = ReaderConfig;

// src/index.ts
const a = {
  source: ReaderSource.Figma
};
export {
  a
};

Most helpful comment

This should be fixed in version 0.6.17.

All 3 comments

Thanks for reporting this. This case is particularly tricky because esbuild currently treats types as comments, so it can't tell that ReaderConfig in export default ReaderConfig is a type instead of a global variable.

I still need to investigate what specifically the TypeScript compiler does in this case before I know how to fix this in esbuild. For now, you can work around this by using an export clause instead:

export { ReaderConfig as default }

This export syntax should be handled correctly by esbuild.

For my future reference:

This decision of whether or not to drop the export default statement is made in visitExportAssignment in ts.ts. That calls isValueAliasDeclaration in checker.ts that looks like this:

function isValueAliasDeclaration(node: Node): boolean {
  switch (node.kind) {
    ...
  case SyntaxKind.ExportAssignment:
    return (<ExportAssignment>node).expression && (<ExportAssignment>node).expression.kind === SyntaxKind.Identifier ?
      isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol) :
      true;
  }
  return false;
}

So there is a special case for export default of bare identifiers where the identifier is a type. TypeScript treats anything that is not an identifier as a value, including types formed by compound expressions such as Namespace.Type.

This should be fixed in version 0.6.17.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

frandiox picture frandiox  路  3Comments

iamakulov picture iamakulov  路  4Comments

a7ul picture a7ul  路  3Comments

elektronik2k5 picture elektronik2k5  路  3Comments

Gotterbild picture Gotterbild  路  3Comments