codehitman
codehitman

Reputation: 1188

Why does `export default` export an object with `default` instead of the object itself?

So I have three Typescript files:

config/env/development.ts

import { Config } from '../config';

class DevConfig {
    public config : Config = {
        HOST: 'localhost',
        PORT: 8080
    };

    constructor() {
        this.config.HOST = 'localhost';
        this.config.PORT = (process.env.PORT as unknown as number) || 8080;
    }
}

export default new DevConfig().config;

config/index.ts

import { Config } from './config';

process.env.NODE_ENV = process.env.NODE_ENV || 'development';

class AppConfig {
    public allConfig : Config;
    public envConfig : Config;

    constructor() {
        this.envConfig = require(`${__dirname}/env/${process.env.NODE_ENV}.js`);
        this.allConfig = require(`${__dirname}/all.js`);
    }
}

export default new AppConfig().envConfig;

and the other file is: ./app.ts

import * as express from 'express';
import { hi } from './controllers/status';
import AppConfig from './config';

class App {
    public express: any;
    public config: object;

    constructor() {
        this.express = express();
        this.config = AppConfig;
        this.mountRoutes();

        console.log(`Output test: ${JSON.stringify(this.config, null, 4)}`);
    }

    private mountRoutes() {
        const router = express.Router();

        router.get('/', hi);
        this.express.use('/', router);
    }
}

export default new App();

The output I see when I run this is the following:

Output test: { "default": { "HOST": "localhost", "PORT": 8080 } }

Where is the "default" coming from? If I try to do console.log(this.config.PORT);, I get an undefined. Could someone please clarify?

Upvotes: 3

Views: 1440

Answers (1)

Jonas Wilms
Jonas Wilms

Reputation: 138267

A module can have a default export and regular exports, yet require() can only return one value. Therefore the transpiler you are using has to turn multiple exports into one value. It does so by turning all the exports into an object.

  // this
  export default 1;
  export const named = 2;

  // turns into:
  module.exports = { 
    default: 1,
    named: 2 
  };

As default is a reserved keyword and thus cannot be used as a named export, having a default key for the export default makes perfectly sense.

You can easily get the default export with require("...").default.

Upvotes: 2

Related Questions