Webpack 5 - "Unexpected token: punc (.)" after import axios

Viewed 1981

I am getting a strange issue on bundling webpack for production environment.

Unexpected token: punc (.)

This happens only when a React component imports axios

import React from "react";
import axios from "axios"; // <---------------

class SimpleComponent extends React.Component {
  render() {

    return (
      <section className="bg-white py-16">
        Simple
      </section>
    )
  }
}

export default SimpleComponent

This results in the following error:

$ npm run build

ERROR in static/main.b394a534fa5736fe90cc.js from Terser
Unexpected token: punc (.) [static/main.b394a534fa5736fe90cc.js:18978,6]
    at js_error (/home/franciscocarvalho/code/oss/axios-issue-example-with-webpack5/node_modules/terser-webpack-plugin/node_modules/terser/dist/bundle.min.js:546:11)
    at croak (/home/franciscocarvalho/code/oss/axios-issue-example-with-webpack5/node_modules/terser-webpack-plugin/node_modules/terser/dist/bundle.min.js:1264:9)
    at token_error (/home/franciscocarvalho/code/oss/axios-issue-example-with-webpack5/node_modules/terser-webpack-plugin/node_modules/terser/dist/bundle.min.js:1272:9)
    at unexpected (/home/franciscocarvalho/code/oss/axios-issue-example-with-webpack5/node_modules/terser-webpack-plugin/node_modules/terser/dist/bundle.min.js:1278:9)
    at statement (/home/franciscocarvalho/code/oss/axios-issue-example-with-webpack5/node_modules/terser-webpack-plugin/node_modules/terser/dist/bundle.min.js:1397:17)
    at _embed_tokens_wrapper (/home/franciscocarvalho/code/oss/axios-issue-example-with-webpack5/node_modules/terser-webpack-plugin/node_modules/terser/dist/bundle.min.js:1322:26)
    at block_ (/home/franciscocarvalho/code/oss/axios-issue-example-with-webpack5/node_modules/terser-webpack-plugin/node_modules/terser/dist/bundle.min.js:2155:20)
    at statement (/home/franciscocarvalho/code/oss/axios-issue-example-with-webpack5/node_modules/terser-webpack-plugin/node_modules/terser/dist/bundle.min.js:1386:29)
    at _embed_tokens_wrapper (/home/franciscocarvalho/code/oss/axios-issue-example-with-webpack5/node_modules/terser-webpack-plugin/node_modules/terser/dist/bundle.min.js:1322:26)
    at if_ (/home/franciscocarvalho/code/oss/axios-issue-example-with-webpack5/node_modules/terser-webpack-plugin/node_modules/terser/dist/bundle.min.js:2141:21)

To Reproduce

  1. Please fork the following axios-issue-example-with-webpack5 repository
  2. Perform npm install
  3. Run npm run build

Expected behavior

None error after bundle

Environment

  • Axios Version [0.21.1]
  • Node.js Version [v12.20.1]
  • Additional Library Versions [React 17.0.1, Webpack 5.15.0]

webpack.config

const path = require("path")
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const {CleanWebpackPlugin} = require("clean-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const Dotenv = require("dotenv-webpack")

const ROOT_DIR = path.resolve(__dirname, "..")

    module.exports = {
        mode: "production",
        entry: [
            path.resolve(ROOT_DIR, "./src/index.js"),
            path.resolve(ROOT_DIR, "./src/styles/styles.scss")
        ],
        module: {
            rules: [
                {
                    test: /\.(js|jsx)$/,
                    exclude: /node_modules/,
                    use: [
                        "babel-loader",
                        {
                            loader: "eslint-loader",
                            options: {
                                configFile: path.resolve(ROOT_DIR, ".eslintrc")
                            }
                        }
                    ]
                },
                {
                    test: /\.(jpe?g|png|gif|ico|svg|woff|woff2|webp)$/i,
                    use: [
                        {
                            loader: "file-loader",
                            options: {
                                name: "static/[name].[ext]"
                            }
                        }
                    ]
                },
                {
                    test: /\.(sa|sc|c)ss$/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        {
                            loader: "css-loader",
                            options: {
                                importLoaders: true
                            }
                        },
                        'postcss-loader',
                        {
                            loader: "sass-loader",
                            options: {
                                sassOptions: {
                                    includePaths: [
                                        path.resolve(ROOT_DIR, "node_modules"),
                                        path.resolve(ROOT_DIR, "src/styles/")
                                    ]
                                }
                            }
                        }
                    ],
                }
            ]
        },
        resolve: {
            extensions: ["*", ".js", ".jsx", ".scss"],
            fallback: {
                assert: false,
                http: false,
                https: false,
                zlib: false,
                tty: false,
                util: false,
                fs: false,
                net: false,
                stream: false
            }
        },
        plugins: [
            new Dotenv({
                path: path.resolve(__dirname, "..", "./.env")
            }),
            new CleanWebpackPlugin(),
            new HtmlWebpackPlugin({
                title: "Advanced React with Webpack Setup",
                template: path.resolve(__dirname, "..", "./src/index.ejs")
            }),
            new MiniCssExtractPlugin({
                filename: "static/[name]-[contenthash].css",
            }),
            new PurgeCSSPlugin({
                paths: glob.sync(`${ROOT_DIR}/src/**/*`, {nodir: true}),
            }),
        ],
        stats: {
            modules: true,
            hash: true,
            assetsSort: "!size",
            children: true
        },
        output: {
            path: path.resolve(__dirname, "..", "dist"),
            chunkFilename: 'static/[name].[hash].js',
            filename: "static/[name].[hash].js",
            chunkLoading: false,
            wasmLoading: false
        },
        optimization: {
            minimize: true,
            minimizer: [
                // For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
                // `...`,
                new CssMinimizerPlugin(),
                /*new UglifyJsPlugin({
                  test: /\.js(\?.*)?$/i,
                  parallel: true,
                })*/
                new TerserPlugin({
                    terserOptions: {
                        ecma: 6,
                        compress: {
                            warnings: true
                        },
                        output: {
                            comments: false,
                            beautify: false
                        }
                    }
                })
            ],
        },
    }
1 Answers

Problem

Like I said the problem is from debug which has been included by webpack in your built file (the node code part). That code looks like:

function save(namespaces) {
  if (null == namespaces) {
    delete {}.DEBUG;
  } else {    
    {}.DEBUG = namespaces; // that is the invalid statement that `terser` complains about
  }
}

// Plus, the main file `index.js` of `debug`:
if (typeof process !== 'undefined' && process.type === 'renderer') {
  module.exports = require('./browser.js');
} else {
  // Above code is from here
  module.exports = require('./node.js');
}

Solution

Above code of debug for node has been added since you haven't yet told webpack you build for web app so then it won't include that code.

So as long as you set target as web in your configuration, then it would work:

webpack.common.js

module.exports = {  
  target: 'web',
  // ...
}

One more thing I found that your css typeface-roboto you imported requires you set publicPath as output:

webpack.prod.js

module.exports = {
  // ...
  output: {
    // ...
    publicPath: '/',
  },
}
Related