Search code examples
javascripttypescriptwebpacksystemjscommonjs

Is there a way to rearrange JavaScript modules generated by the TypeScript compiler?


I have a TypeScript project, and the project structure is organized not unlike a typical Maven Java project. Below is more or less what the project structure looks like.

.
├── gulpfile.js
├── index.html
├── package.json
├── src
│   ├── entity
│   │   ├── car.ts
│   │   ├── animal.ts
│   └── sevice
│       ├── dao
│       │   ├── cardao.ts
│       │   ├── animaldao.ts
│       └── validator
│           ├── carvalidator.ts
│           └── animalvalidator.ts
├── test
│   ├── entity
│   │   ├── car.spec.ts
│   │   ├── animal.spec.ts
│   └── service
│       └── dao
│           ├── carvalidator.spec.ts
│           └── animalvalidator.spec.ts
├── tsconfig.json
└── webpack.config.js

I am able to generate a single *.js file for commonjs/webpack, system, and amd.

  • for commonjs/webpack, I use tsc + tsconfig.json and then webpack + webpack.config.js to generate a single file, bundle.js.
  • for system, I simply use the gulp-typescript task with module set to system to generate a single file, lib-system.js.
  • for amd, again, I use gulp-typescript with module set to amd to generate a single file, lib-amd.js.

However, after I load these single *.js files into the browser (with webpack I just use <script> tags and with the other I use SystemJS), I noticed that I have to instantiate my objects as follows.

var c = new car.Car('chevy', 'traverse', 2017);
var a = new animal.Animal('cat');

I don't like the fact that I am repeating myself in the code car.Car or animal.Animal. Is there a way to make it so that I can do the following without altering the project structure?

var c = new entity.Car('chevy', 'traverse', 2017);
var a = new entity.Animal('cat');

Of course I can just create a file, entity.ts and define both Car and Animal (or all entities, which there are a lot) in that one file. But that seems rather silly to me to have one long file with a lot of classes just to group the modules logically together.

I ventured into naively merging all the *.ts files into one uber ts file, but that doesn't really work because

  • there's a lot of imports, and you'd have to remove them (I don't know if gulp-concat can do this operation or if I need another package piped into the process to do so)
  • sub-classes must be defined after super-classes (as gulp-concat doesn't care about this rule when it concatenates files)

So my question is if is possible to logically group my classes (by function, e.g. entity, dao, validator, etc...) into modules instead of the default grouping (by files, one file is actually one module, I believe)?

I would expect some tools to make this possible, haven't found any solutions yet.


Solution

  • One solution is indeed to create a module for grouping, src/entity.ts, and re-export classes from it:

    export { Car } from './entity/car';
    export { Animal } from './entity/animal';
    

    Another possibility is to use rollup.js which seems to be capable of combining several compiled modules into one, but it's for javascript only, and I don't have any experience with it.