29

When I try to compile a .ts file I get the following error:

Module build failed: Error: Typescript emitted no output for C:\xampp\htdocs\node-api\src\js\server.ts. 
at successLoader (C:\xampp\htdocs\node-api\node_modules\ts-loader\dist\index.js:39:15)
at Object.loader (C:\xampp\htdocs\node-api\node_modules\ts-loader\dist\index.js:21:12)

For compiling I use the following config files.

Webpack:

const path = require( 'path' ),
    CleanWebpackPlugin = require( 'clean-webpack-plugin' );

module.exports = env => {
    return {
        mode: env.dev ? 'development' : 'production',
        entry: {
            'server': './src/js/server.ts'
        },
        output: {
            path: __dirname,
            filename: './dist/js/[name].js',
        },
        externals: '/node_modules',
        module: {
            rules: [
                {
                    test: /\.js$/,
                    exclude: ['/node_modules/', '/src/scss/'],
                    use: [
                        'babel-loader'
                    ]
                },
                {
                    test: /\.ts(x?)$/,
                    exclude: ['/node_modules/', '/src/scss/'],
                    use: [
                        'babel-loader',
                        'ts-loader',
                    ]
                },
                {
                    test:  /\.json$/,
                    loader: 'json-loader'
                },
            ]
        },
        resolve: {
            extensions: ['.ts', '.tsx', '.js' ],
            alias: {
                '@': path.resolve(__dirname, './src/js')
            }
        },
        plugins: [
            new CleanWebpackPlugin(['./dist/js', './dist/css']),
        ]
    }
};

Typescript:

{
    "compilerOptions": {
        "removeComments": true,
        "preserveConstEnums": true,
        "allowJs": true,
        "outDir": "./dist/js",
        "target": "es5",
        "moduleResolution": "node",
        "module": "es2015",
        "lib": [
            "es2015",
            "es2016"
        ]
    },
    "exclude": [
        "node_modules"
    ]
}

Babel:

{
    "presets": [
        [
            "env", {
                "targets": {
                    "node": "current"
                }
            }
        ],
        "stage-2", "es2015"
    ],
    "plugins": ["dynamic-import-node"]
}

As suggested in some other questions I've already changed the order of resolve extensions but that didn't solve it (.js before .ts) . Typescript 2.8.3 is used in combination with Node 8.11.1 and Mongoose 5.0.15 and compiled by Webpack 4.6. So I'm still wondering how to to solve the error mentioned above.

9
  • Post your tsconfig.json Commented Apr 22, 2018 at 18:04
  • @Sajeetharan its under Typescript: Commented Apr 22, 2018 at 18:04
  • can you try adding "files": [ "./src/components/index.d.ts" ] to your tsconfig Commented Apr 22, 2018 at 18:14
  • @Sajeetharan Tried that but also didn't work Commented Apr 22, 2018 at 18:15
  • ok what about index.ts instead of index.d.ts Commented Apr 22, 2018 at 18:16

5 Answers 5

36

Please set noEmit to false in your tsconfig.json. By default it sets to true, once we change it to false we may not get this error.

"noEmit": false

Sign up to request clarification or add additional context in comments.

4 Comments

Try adding this as comment or elaborate your answer.
But... but... why?
yes, this works but why?
Plus this doesn't solve the case where you actually don't want emits...
11

Override compilerOptions like this in webpack config (when using ts-loader):

    rules: [
      {
        test: /\.[jt]s$/,
        exclude: /(node_modules)/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env'],
            },
          },
          {
            loader: 'ts-loader',
            options: {
              compilerOptions: {
                noEmit: false,
              },
            },
          },
        ],
      },
    ]

3 Comments

this option is not available to be set in webpack.config.json, Webpack version 5.47
I like this option, since it allows noEmit: true in tsconfig, which prevents output except during build. @BEvo it is available, but you may need to change use: 'ts-loader' to loader: 'ts-loader'.
This worked for me on Cypress plugins file setting up the ts-loader preprocessor for cucumber .feature files: on( 'file:preprocessor', webpack({ webpackOptions: { resolve: { extensions: ['.ts', '.js'], }, module: { rules: [ { test: /\.ts$/, exclude: [/node_modules/], use: [ { loader: 'ts-loader', options: { compilerOptions: { noEmit: false, }...
3

In my case I had to remove "emitDeclarationOnly": true from the tsconfig.json

(or just set it to false)

With this on, it will only output d.ts files and not JavaScript files.

Read more: https://www.typescriptlang.org/tsconfig#emitDeclarationOnly

1 Comment

Exactly! That is the correct answer. Using webpack 5.76 and ts-loader 9.4 here. Thank you.
2

Using webpack 5 and Typescript 4.5, I can run an expressjs + prisma server with the following:

webpack.config.js:

const path = require('path');

module.exports = {
  entry: './src/index.ts',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: [
          {
            loader: 'ts-loader',
            options: {
              compilerOptions: {noEmit: false},
            }
          }
        ],
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

tsconfig.json:

{
  "compilerOptions": {
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "CommonJS",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "jsx": "preserve",
    "incremental": true
  },
  "include": [
    "**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

Source: https://webpack.js.org/guides/typescript/

Comments

0

As others pointed out, using "noEmit": false will solve this issue. This is because ts-loader relies on tsc’s emit to works. Using noEmit in tsconfig.json means ts-loader doesn't receive anything, and throw this error.

However, using "noEmit": false can have other side effects when using allowImportingTsExtensions or by generating .d.ts files in your outDir when you don't want to.

A solution which doesn't require to set noEmit to false is to type-check with noEmit, and them compile with emits, in two individual steps. This can easily be done by using the Fork TS Checker Webpack Plugin, which also have the benefit of speeding up TypeScript type checking by moving it to a separate process :

  1. npm install --save-dev fork-ts-checker-webpack-plugin
  2. In webpack.config.js :
    // webpack.config.js
    const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
    
    module.exports = {
      // ...
      plugins: [new ForkTsCheckerWebpackPlugin()],
    };
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.