Webpack 5 - 导入 axios 后出现“意外令牌:punc (.)”

fis*_*lin 5 reactjs webpack axios

我在为生产环境捆绑 webpack 时遇到一个奇怪的问题。

Unexpected token: punc (.)
Run Code Online (Sandbox Code Playgroud)

在 React 组件导入时发生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
Run Code Online (Sandbox Code Playgroud)

这会导致以下错误:

$ 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)
Run Code Online (Sandbox Code Playgroud)

再现

  1. 请 fork 以下axios-issue-example-with-webpack5存储库
  2. 履行 npm install
  3. npm run build

预期行为

捆绑后无错误

环境

  • Axios 版本 [0.21.1]
  • Node.js 版本 [v12.20.1]
  • 其他库版本 [React 17.0.1、Webpack 5.15.0]

配置文件

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
                        }
                    }
                })
            ],
        },
    }
Run Code Online (Sandbox Code Playgroud)

tmh*_*005 3

问题

就像我说的,问题出debugwebpack您的构建文件(node代码部分)中。该代码如下所示:

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');
}

Run Code Online (Sandbox Code Playgroud)

解决方案

debug上面的for代码node已经添加,因为您还没有告诉webpack您为网络应用程序构建,所以它不会包含该代码。

因此,只要您在配置中进行设置,那么它就会起作用targetweb

webpack.common.js

module.exports = {  
  target: 'web',
  // ...
}
Run Code Online (Sandbox Code Playgroud)

我发现另一件事是typeface-roboto你导入的 css 需要你设置publicPath为输出:

webpack.prod.js

module.exports = {
  // ...
  output: {
    // ...
    publicPath: '/',
  },
}
Run Code Online (Sandbox Code Playgroud)