typescriptwebpackworker-loader

Webpack worker-loader fails to compile typescript worker


I am configuring my project as described in worker-loader documentation and I was able to get TS code intel working using the correct d.ts.

However, during webpack build it throws an error and I don't understand why.

 ERROR in ./src/test.worker.ts
Module parse failed: Unexpected token (1:9)
You may need an appropriate loader to handle this file type.
| const ctx: Worker = self as any;
| ctx.addEventListener('message', event => {
|   console.log(event);

My worker file content test.worker.ts:

const ctx: Worker = self as any;
ctx.addEventListener('message', event => {
  console.log(event);
  setTimeout(() => ctx.postMessage({
    foo: 'boo'
  }), 5000);
});

Application entry index.ts

import TestWorker from './test.worker.ts';

const test = new TestWorker();
test.postMessage({});

And finally here is my webpack.config.js

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const DIR_SOURCE = path.resolve(__dirname, 'src');
const DIR_BUILD = path.resolve(__dirname, 'build');

module.exports = {

  entry: `${DIR_SOURCE}/index.tsx`,

  output: {
    path: DIR_BUILD,
    filename: 'project.bundle.js'
  },

  devtool: "source-map",

  resolve: {
    // Add '.ts' and '.tsx' as resolvable extensions.
    extensions: [".ts", ".tsx", ".js", ".json"]
  },

  module: {
    rules: [
      {test: /\.tsx?$/, loader: "ts-loader" },
      {test: /\.worker\.ts$/, use: ['ts-loader', 'worker-loader'] },
      {test: [/\.vert$/, /\.frag$/], use: 'raw-loader'},
      {test: /\.(png|jpg|gif|svg)$/, use: {loader: 'file-loader', options: {}} },
      {test: /.*\.sass/, use: ['style-loader', 'css-loader', 'sass-loader'] },
    ]
  },

  plugins: [
    new webpack.DefinePlugin({
      'CANVAS_RENDERER': JSON.stringify(true),
      'WEBGL_RENDERER': JSON.stringify(true)
    }),
    new HtmlWebpackPlugin({
      template: 'src/index.ejs'
    }),
  ]
};

Any help is much appreciated.

Thank you :)


Solution

  • Ok I figured it out.

    First I needed to move worker loader before the ts-loader and did not need to specify array in worker use property and just keep it as described in documentation of worker-loader.

    module: {
        rules: [
          {test: /\.worker\.ts$/, loader: 'worker-loader'},
          {test: /\.tsx?$/, loader: "ts-loader" },
          {test: [/\.vert$/, /\.frag$/], use: 'raw-loader'},
          {test: /\.(png|jpg|gif|svg)$/, use: {loader: 'file-loader', options: {}} },
          {test: /.*\.sass/, use: ['style-loader', 'css-loader', 'sass-loader'] },
        ]
      },
    

    Then in my worker I also needed to export anything otherwise typescript (2.8.3) would complain that it can't find a module and I export default null as any to avoid confusing ts even further.

    worker.js

    const ctx: Worker = self as any;
    ctx.addEventListener('message', event => {
      console.log(event);
      setTimeout(() => ctx.postMessage({
        foo: 'boo'
      }), 5000);
    });
    export default null as any;
    

    index.js

    import TestWorker from './test.worker.ts';
    const test = new TestWorker('');
    test.postMessage({});