23

I want to compile TypeScript to one file when using with Node.js.

I have tried configuring "tsconfig.json" like this:

"compilerOptions": {
    "module": "commonjs",
    "target": "es6",
    "noImplicitAny": false,
    "sourceMap": false,
    "outFile": "./app/index.js",
    "pretty": true,
    "types": [
      "node"
    ]
  }",

...but when I try with module" set to"commonjs"`, I get the error:

error TS6082: Only 'amd' and 'system' modules are supported alongside --outFile.

If I change it to "module": "system", I get this error when running the file in node:

ReferenceError: System is not defined

If I change module to "amd", I get this error when running the file in node:

ReferenceError: define is not defined
SE_net4 the downvoter
  • 21,043
  • 11
  • 69
  • 107
user236582
  • 347
  • 1
  • 2
  • 6

2 Answers2

30

It is not possible to bundle Node.js modules into a single file with the TypeScript compiler alone: each file in the CommonJS module system (used by Node.js) is treated as a single module, and cannot be joined together without proper module bundling techniques found in the many JavaScript code bundlers out there (such as Browserify, Webpack, Rollup, Parceljs, ...).

Other module systems such as SystemJS do not have this limitation, and module definitions can be concatenated into a single file using just the TypeScript compiler: tsc ... --outfile bundle.js -module system. However, they are not supported by Node.js on the fly.

For the actual solution, there are two reasonable choices: either configure your project to bundle the solution using a separate tool (Browserify, Webpack, ...), or include an implementation of SystemJS into your Node.js application (instructions here).

I will also end with a side note: consider evaluating whether you really need to bundle your server-sided code. Bundling is typically performed in frontend projects to reduce the size of client-sided resources, although it can be done as well for server applications in resource-efficient scenarios.

SE_net4 the downvoter
  • 21,043
  • 11
  • 69
  • 107
7

@E_net4 is right. Currently, it is not possible to build modules into a single file with the TypeScript compiler alone. This article describes how to do so with webpack where the file structure is:

├── index.js
├── package.json
├── src
│   ├── add-message
│   │   └── index.ts
│   ├── index.ts
│   └── upcase-messages
│       └── index.ts
├── tsconfig.json
└── webpack.config.js

webpack.config.js

const nodeExternals = require('webpack-node-externals');

module.exports = {
    entry: './src/index.ts',
    output: {
        filename: 'index.js', // <-- Important
        libraryTarget: 'this' // <-- Important
    },
    target: 'node', // <-- Important
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: 'ts-loader',
                options: {
                    transpileOnly: true
                }
            }
        ]
    },
    resolve: {
        extensions: [ '.ts', '.tsx', '.js' ]
    },
    externals: [nodeExternals()] // <-- Important
};

tsconfig.json

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "outDir": "./",
    "noImplicitAny": true,
    "strictNullChecks": true
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}
Tom
  • 3,419
  • 25
  • 41