How to build a single ES6 module from several Type

2019-01-26 17:02发布

问题:

The code of my frontend library is split into several source files.

Example:

// a.ts
function a() {}

// b.ts
function b() {}

// main.ts
const myLib = {
    a: a,
    b: b
}

I need to build one ES6 module (ie. one JavaScript file) that exports only myLib, as the default export.

I see two options. The first one:

  1. Run tsc to compile each file to JavaScript;
  2. Concatenate all the generated JS files into a single file my-lib.js;
  3. Append the code needed by ES6 (export …).

The second one:

  1. Concatenate all the TypeScript files into a single file my-lib.ts;
  2. Append the export: export default myLib;
  3. Run tsc on the concatenated file.

Both options are ugly and loose the map file.

Is there a better way to do that?

回答1:

The correct way is to create a barrel file that will re export the modules.

// foo/a.ts
export function a() {}

// foo/b.ts
export function b() {}

// foo/index.ts
export {a} from './a';
export {b} from './b';

Then in your consumer:

import {a, b} from './foo';

a();
b();


回答2:

I add an answer because today the correct way for a frontend library is to use Rollup.

First, write ES6 modules, import and export them:

// file-a.ts
export function a() {}

// file-b.ts
export function b() {}

// main.ts
export { a } from "./file-a"
export { b } from "./file-b"

Then, compile the code to JavaScript using tsc with the option module set to "es6".

Then, let Rollup build a flat bundle from the JavaScript code. For the code above, Rollup generates this bundle:

function a() {}
function b() {}
export { a, b };

See also:

  • The Rollup REPL: https://rollupjs.org/repl
  • The article: Webpack and Rollup: the same but different

Notice: The definitive solution to build the definition file (.d.ts) is not implemented yet (March, 2018). I still concatenate files with a Node.js script to generate exported types in a single TypeScript definition file.