Search code examples
javascriptwebpackpolymerbabeljsmixins

Polymer 3 + webpack + babel Class constructor PolymerElement cannot be invoked without 'new'


I am trying to extent a mixin class in polymer. It works fine but as soon as I try to transpile my code with babel, I get Class constructor PolymerElement cannot be invoked without 'new. I get the error as soon as I call super. I am sure the problem has something to do with extend a native class with a transpiled class code but I could not yet find a resource/example that managed to solve my issue. My guess is that I need to configure my babel differently, but as I said, found examples did not help. You can access the repository where I am reproducing the error here: https://github.com/skukan159/DebuggingPolymerWebpack

This is my webpack config:

const webpack = require('webpack');
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const WorkboxPlugin = require('workbox-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');


const webcomponentsjs = './node_modules/@webcomponents/webcomponentsjs';

const polyfills = [
    {
        from: path.resolve(`${webcomponentsjs}/webcomponents-*.{js,map}`),
        to: path.join(__dirname, 'wwwroot'),
        flatten: true
    },
    {
        from: './node_modules/web-animations-js/*{.js,.js.map}',
        to: './node_modules/web-animations-js/[name].[ext]'
    }
];
const assets = [
    {
        from: 'manifest.json',
        to: path.resolve(__dirname, 'wwwroot'),
        context: './src/'
    },
    {
        from: 'sw-service-worker.js',
        to: path.resolve(__dirname, 'wwwroot'),
        context: './src/'
    },
    {
        from: 'include/images/*',
        to: path.resolve(__dirname, 'wwwroot'),
        context: './src/'
    },
    {
        from: '*.html',
        to: path.resolve(__dirname, 'wwwroot'),
        context: './src/'
    }
];

module.exports = function (env) {
    return {
        entry: './src/index.js',
        output: {
            publicPath: '/',
            path: path.resolve(__dirname, 'wwwroot'), changed
            filename: "[name].[contenthash].js",  
            chunkFilename: '[name].[contenthash].js',
        },
        node: {
            dns: 'mock',
            net: 'mock'
        },
        optimization: {
            splitChunks: {
                cacheGroups: {
                    vendor: {
                       test: /[\\/]node_modules[\\/]/,
                       name: 'vendors',
                       chunks: 'all'
                    }
                }
            },
            runtimeChunk: 'single',
        },

        module: {
            rules: [
                {
                    test: /\.js$/,
                   exclude: /node_modules/,
                    use: {
                        loader: 'babel-loader',
                        options: {
                            presets: ['@babel/preset-env', { exclude: ["transform-classes"] }],
                            plugins: [
                                "@babel/plugin-proposal-class-properties",
                                "@babel/plugin-proposal-object-rest-spread",
                                "@babel/plugin-syntax-dynamic-import"
                            ]
                        }
                    }
                },

                {
                    "test": /\.html$/,
                    "use": [{
                        loader: 'html-loader',
                    }]
                },
                {
                    test: /\.json$/,
                    use: 'json-loader'
                },
                {
                    test: /\.(png|svg|jpg|gif)$/,
                    use: [
                        {
                            loader: 'file-loader',
                            options: {
                                name: '/img/[name].[ext]'
                            }
                        }
                    ]
                }
            ]
        },

        resolve: {
            modules: [
                "node_modules",
                path.resolve(__dirname, "src")
            ],
            extensions: [".js", ".json"],

            alias: {
                'markjs': path.resolve(__dirname, "./node_modules/mark.js/dist/mark.min.js"),
            }
        },

        plugins: [
            new webpack.HashedModuleIdsPlugin(),
            new HtmlWebpackPlugin({
                template: 'src/index.html'}),
            new webpack.ProvidePlugin({
                IntlMessageFormat: ['intl-messageformat/index.js', 'default'],
                'Mark': 'markjs'
            }),
            new CleanWebpackPlugin(['wwwroot']),
            new WorkboxPlugin.GenerateSW({
                swDest: 'sw.js',
                clientsClaim: true,
                skipWaiting: true
            }),
            new CopyWebpackPlugin([...polyfills, ...assets,
                {
                    from: 'include/components/oidc-client/oidc-client.min.js',
                    to: path.resolve(__dirname, 'wwwroot'),
                    context: './src/'
                },
            ]),
        ],

        watch: true,
        watchOptions: {
            aggregateTimeout: 1000,
            poll: true,
            poll: 500,
        },
    }
};

And here is my .babelrc file

    {
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "browsers": [ "last 2 versions", "ie >= 11" ]
        },
        "exclude": [ "transform-classes" ]
      }
    ]
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-object-rest-spread",
    "@babel/plugin-syntax-dynamic-import"
  ]
}

Solution

  • I found out what was the problem. I needed to comment out options for my babel loader from the webpack config file. Only that way was my .babelrc configuration file being applied.