44

I have these dependencies:

"devDependencies": {
  "@types/node": "^4.0.27-alpha",
  "babel-core": "^6.10.4",
  "babel-loader": "^6.2.4",
  "babel-polyfill": "^6.9.1",
  "babel-preset-es2015": "^6.9.0",
  "babel-preset-stage-0": "^6.5.0",
  "ts-loader": "^0.8.2",
  "typescript": "^2.0.0",
  "webpack": "^1.13.1"
}

.babelrc:

{
  "presets": [
    "es2015",
    "stage-0"
  ]
}

tsconfig.json:

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "noImplicitAny": false,
        "sourceMap": false,
        "outDir": "built"
    },
    "exclude": [
        "node_modules"
    ]
}

webpack.config.js:

module.exports = {
  entry: ['babel-polyfill', './src/'],
  output: {
    path: __dirname,
    filename: './built/bundle.js',
  },
  resolve: {
    modulesDirectories: ['node_modules'],
    extensions: ['', '.js', '.ts'],
  },
  module: {
    loaders: [{
      test: /\.tsx?$/, loaders: ['ts-loader', 'babel-loader'], exclude: /node_modules/
    }],
  }
};

/src/index.ts:

async function foo() {
  const value = await bar();
  console.log(value);
}

function bar() {
  return new Promise((resolve, reject) => {
    return resolve(4);
  });
}

(async function run() {
  await foo();
}());

With this setup it does work, I can build and run it (logs 4 correctly). However I'm always getting some errors on Webpack:

ERROR in ./src/index.ts
(4,32): error TS2304: Cannot find name 'regeneratorRuntime'.

ERROR in ./src/index.ts
(6,12): error TS2304: Cannot find name 'regeneratorRuntime'.

ERROR in ./src/index.ts
(31,451): error TS2346: Supplied parameters do not match any signature of call target.

ERROR in ./src/index.ts
(40,33): error TS2304: Cannot find name 'regeneratorRuntime'.

ERROR in ./src/index.ts
(41,12): error TS2304: Cannot find name 'regeneratorRuntime'.

It seems it has something to do with babel-polyfill. What am I missing?

Youssouf Oumar
  • 29,373
  • 11
  • 46
  • 65
BrunoLM
  • 97,872
  • 84
  • 296
  • 452

4 Answers4

103

Babel 7 does not need ts-loader.

As of Babel 7 the ts-loader is unnecessary, because Babel 7 understands TypeScript. Complete details of a TypeScript + Babel7 + Webpack setup are here.

An overview of the set up without ts-loader.

Install Babel's TypeScript support. Only @babel/preset-typescript is mandatory; the other three add additional features that TypeScript supports.

npm install --save-dev @babel/preset-typescript 
npm install --save-dev @babel/preset-env 
npm install --save-dev @babel/plugin-proposal-class-properties 
npm install --save-dev @babel/plugin-proposal-object-rest-spread

Configure the additional .babelrc plugins and presets.

{
    "presets": [
        "@babel/preset-env",
        "@babel/preset-typescript"
    ],
    "plugins": [
        "@babel/proposal-class-properties",
        "@babel/proposal-object-rest-spread"
    ]
}

And update your webpack.config.js (other code is omitted for clarity).

module: {
  rules: [
  {
     test: /\.(js|jsx|tsx|ts)$/,
     exclude: /node_modules/,
     loader: 'babel-loader'
    }
  ]
},
resolve: {
  extensions: ['*', '.js', '.jsx', '.tsx', '.ts'],
},
Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467
  • 1
    Is it necessary to repeat presets configuration in webpack file? Isn't specyfying them in babelrc enough? – Piotr Sobczyk Sep 15 '18 at 08:24
  • 3
    This is the right answer^ with the move to babel@7. – arete Oct 11 '18 at 21:50
  • 27
    One difference between `ts-loader` and using Babel 7 with `babel-loader` is that `ts-loader` type-checks during transpilation; babel-loader does not. The instructions for using TypeScript with Babel 7 linked in this answer suggest calling `tsc` separately to type-check. – Ben Regenspan Jul 17 '19 at 20:57
  • How about the namespaces ?? they are not supported – AbuDawood Dec 08 '19 at 17:10
  • 3
    ts-loader also have additional option like custom tsconfig path. It should not be advised to use babel-loader instead of ts-loader (at least now in 2020) – Eric Burel Mar 03 '20 at 16:00
  • 1
    @EricBurel: I'm against your point. `ts-loader` is not required in using babel. This is the point. Either Babel itself or tsc itself will come to a state where no plugin is required to achieve the same result. Advising people to rely on community-maintained plugin is usually not future proof. FYI: I don't use `ts-loader`, since I don't need those features. I want stability. – NeoZoom.lua Apr 07 '22 at 06:36
45

Loaders always execute right to left, so changing to

test: /\.tsx?$/, loaders: ['babel-loader', 'ts-loader'], exclude: /node_modules/

fixed the issue since it is going to run ts-loader first.

Full webpack.config.js file:

module.exports = {
  entry: ['babel-polyfill', './src/'],
  output: {
    path: __dirname,
    filename: './dist/index.js',
  },
  resolve: {
    extensions: ['', '.js', '.ts'],
  },
  module: {
    loaders: [{
      test: /\.ts$/, loaders: ['babel-loader', 'ts-loader'], exclude: /node_modules/
    }],
  }
};

Sample project: brunolm/typescript-babel-webpack.

Youssouf Oumar
  • 29,373
  • 11
  • 46
  • 65
BrunoLM
  • 97,872
  • 84
  • 296
  • 452
10

(4,32): error TS2304: Cannot find name 'regeneratorRuntime'.

This is a symptom that the output of babel is getting fed to ts. This order is wrong

Fix

You compilation setup should have TS output fed to Babel.

Alternatively you can compile TypeScript with just Babel using @babel/preset-typescript.

More

Compiling TypeScript with Babel : https://babeljs.io/docs/en/babel-preset-typescript

basarat
  • 261,912
  • 58
  • 460
  • 511
  • Fixes should avoid linking to external sites which fragments the information. Instead, consider providing the same idea in your answer. – monokrome Jan 22 '21 at 03:54
2

This thread is a little dated...
If you want to use babel together with ts-loader in 2023:

Install

npm install -D babel-loader @babel/core @babel/preset-env

Webpack loaders configuration

{
  entry: './src/index.tsx',
  // ... your other webpack configs
  module: {
    // ... your other module configs
    rules: [
      // ... your other rolues configs
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: [
                ['@babel/preset-env', { targets: 'defaults' }],
              ],
            },
          },
          {
            loader: 'ts-loader',
            options: {
              transpileOnly: true,
            },
          },
        ],
      },
    ],
  },
}

Tested with my electron-forge setup.
(Running NodeJS 19.0.0 with TypeScript 5.0.2, @babel/core 7.21.3, babel-loader 9.1.2 and ts-loader 9.2.2)

donnikitos
  • 776
  • 1
  • 9
  • 18
  • the `transpileOnly` option of ts-loader should only be true in dev mode tho, you still need to type check when building – Nanachi Jul 10 '23 at 04:55