简体   繁体   中英

Not able to build project using webpack and babel

I am building a React app from scratch using webpack and babel . I have all the rules, babel configurations in place. I have setup my application with three config files for webpack:

  1. dev config
  2. prod config
  3. common items across both configs (rules, variables, aliases etc).

When I am trying to start my application locally (development) using webpack-dev-server , I get an error on line import merge from 'webpack-merge'

Command used: webpack-dev-server --config webpack.config.dev.babel.js --open

SyntaxError: Cannot use import statement outside a module
    at Module._compile (internal/modules/cjs/loader.js:891:18)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Module.require (internal/modules/cjs/loader.js:848:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at WEBPACK_OPTIONS (C:\Users\hp-pc\node_modules\webpack-cli\bin\convert-argv.js:115:13)
    at requireConfig (C:\Users\hp-pc\node_modules\webpack-cli\bin\convert-argv.js:117:6)
    at C:\Users\hp-pc\node_modules\webpack-cli\bin\convert-argv.js:124:17
    at Array.forEach (<anonymous>)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

I am not able to figure out where the issue is exactly

Possible fixes that I tried:

  1. Deleting node_modules and doing a fresh install.
  2. Updating all dependencies using yarn-upgrade-all .
  3. Setting a react project with webpack and babel from scratch.
  4. SO Answer.
  5. Adding "type":"module" to package.json .

None of these have worked for me so far. Can anyone please guide me on how to resolve this issue?

Here are a few files which might help troubleshoot this further:

package.json

{
  "name": "weather-app",
  "version": "0.0.1",
  "private": true,
  "dependencies": {
    "autoprefixer": "^10.2.5",
    "axios": "^0.21.1",
    "classnames": "^2.3.1",
    "copy-webpack-plugin": "^8.1.0",
    "dotenv": "^8.2.0",
    "git-revision-webpack-plugin": "^3.0.6",
    "html-webpack-plugin": "^5.3.1",
    "mini-css-extract-plugin": "^1.4.0",
    "moment": "^2.29.1",
    "prop-types": "^15.7.2",
    "react": "^17.0.2",
    "react-debounce-input": "^3.2.3",
    "react-dom": "^17.0.2",
    "react-redux": "^7.2.3",
    "react-router-dom": "^5.2.0",
    "redux": "^4.0.5",
    "redux-thunk": "^2.3.0",
    "sass-loader": "^11.0.1",
    "style-loader": "^2.0.0"
  },
  "devDependencies": {
    "@babel/cli": "^7.13.14",
    "@babel/core": "^7.13.14",
    "@babel/node": "^7.13.13",
    "@babel/plugin-transform-modules-commonjs": "^7.13.8",
    "@babel/plugin-transform-regenerator": "^7.12.13",
    "@babel/plugin-transform-runtime": "^7.13.10",
    "@babel/preset-env": "^7.13.12",
    "@babel/preset-flow": "^7.13.13",
    "@babel/preset-react": "^7.13.13",
    "@babel/register": "^7.13.14",
    "babel-loader": "^8.2.2",
    "babel-plugin-react-display-name": "^2.0.0",
    "babel-plugin-webpack-alias": "^2.1.2",
    "babel-preset-react-hmre": "^1.1.1",
    "case-sensitive-paths-webpack-plugin": "^2.4.0",
    "chai": "^4.3.4",
    "chalk": "^4.1.0",
    "css-loader": "^5.2.0",
    "enzyme": "^3.11.0",
    "eslint": "^7.23.0",
    "eslint-config-airbnb": "^18.2.1",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-jsx-a11y": "^6.4.1",
    "eslint-plugin-react": "^7.23.1",
    "node-sass": "^5.0.0",
    "terser-webpack-plugin": "^5.1.1",
    "webpack": "^5.30.0",
    "webpack-cli": "^4.6.0",
    "webpack-dev-server": "^3.11.2",
    "webpack-merge": "^5.7.3",
    "webpack-notifier": "^1.13.0"
  },
  "scripts": {
    "start:dev": "webpack-dev-server --config webpack.config.dev.babel.js --open",
    "start:mock": "nodemon mockAPI.js",
    "update:packages": "node wipe-dependencies.js && rm -rf node_modules && npm update --save-dev && npm update --save"
  },
  "lint-staged": {
    "*.js": [
      "eslint --fix",
      "git add"
    ]
  },
  "nyc": {
    "exclude": [
      "**/*.spec.js",
      "dist",
      "docs",
      "helpers",
      "node_modules",
      "styleguide",
      "webpack*"
    ],
    "extensions": [
      ".js",
      ".jsx"
    ]
  }
}

webpack.config.dev.babel.js


    /* eslint-disable import/no-extraneous-dependencies */
    import merge from 'webpack-merge';
    import Notifier from 'webpack-notifier';
    import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin';
    
    
    import common from './webpack.common';
    
    module.exports = merge(common, {
      mode: 'development',
      devtool: 'source-map',
      devServer: {
        contentBase: './app/src',
        historyApiFallback: true,
      },
      plugins: [
        new Notifier(),
        new CaseSensitivePathsPlugin(),
      ],
    });

webpack.common.js


    import path from 'path';
    import 'core-js/stable';
    import 'regenerator-runtime/runtime';
    import GitRevisionPlugin from 'git-revision-webpack-plugin';
    import HtmlWebpackPlugin from 'html-webpack-plugin';
    import MiniCssExtractPlugin from 'mini-css-extract-plugin';
    
    const gitRevisionPlugin = new GitRevisionPlugin();
    const buildDateTime = new Date().toISOString();
    
    const htmlConfig = {
        template: 'index.html',
        filename: 'index.html',
        inject: true,
        data: {
            __VERSION__: JSON.stringify(gitRevisionPlugin.version()),
            __COMMITHASH__: JSON.stringify(gitRevisionPlugin.commithash()),
            __BRANCH__: JSON.stringify(gitRevisionPlugin.branch()),
            __BUILDDATETIME__: buildDateTime,
        },
    };
    
    module.exports = {
        context: path.resolve(__dirname, './app/src'),
        entry: {
            app: ['./index.jsx'],
        },
        output: {
            path: path.resolve(__dirname, './app/dist'),
            publicPath: '/',
            filename: '[name].[chunkhash].js',
        },
        module: {
            rules: [
                {
                    test: /\.(woff|woff2|eot|ttf|otf)$/,
                    use: [
                        'file-loader?name=assets/fonts/[name].[ext]',
                    ],
                },
                {
                    test: /(\.js|\.jsx)$/,
                    loader: 'babel-loader',
                    exclude: [/node_modules/],
                    include: [path.resolve(__dirname, './node_modules/react-icons/fa'), path.resolve(__dirname, './node_modules/react-onclickoutside')],
                    query: {
                        presets: [['@babel/env',
                            {
                                useBuiltIns: 'usage',
                                corejs: 3,
                            },
                        ],
                            '@babel/react',
                            '@babel/flow'],
                        plugins: ['@babel/plugin-syntax-dynamic-import', '@babel/plugin-transform-regenerator', '@babel/plugin-proposal-class-properties', '@babel/plugin-transform-runtime', 'transform-class-properties'],
                    },
                },
                {
                    test: /\.(png|jpg|svg|ico)$/,
                    loader: 'file-loader',
                },
                {
                    test: /\.s?css$/,
                    use: [
                        'style-loader',
                        'css-loader',
                        'sass-loader'
                    ],
                },
            ],
        },
        plugins: [
            new MiniCssExtractPlugin({
                filename: '[name].[hash].css',
                chunkFilename: '[id].[hash].css',
            }),
            new HtmlWebpackPlugin(htmlConfig),
        ],
        resolve: {
            alias: {
                Actions: path.resolve(__dirname, 'app/src/actions'),
                Components: path.resolve(__dirname, 'app/src/components/'),
                Containers: path.resolve(__dirname, 'app/src/containers/'),
                Helpers: path.resolve(__dirname, 'helpers/'),
                Selectors: path.resolve(__dirname, 'app/src/selectors/'),
                Utils: path.resolve(__dirname, 'app/src/utils'),
                Assets: path.resolve(__dirname, 'app/src/assets'),
                Apis: path.resolve(__dirname, 'app/src/api'),
            },
            extensions: ['.js', '.jsx', '.json', '*'],
        },
    };

.babelrc

    {
      "presets": [
        "@babel/env",
        "@babel/preset-react",
        "@babel/preset-flow"
      ],
      "env": {
        "test": {
          "plugins": [
            "@babel/plugin-transform-regenerator",
            "@babel/plugin-syntax-dynamic-import",
            [
              "@babel/plugin-transform-runtime",
              {
                "regenerator": true
              }
            ],
            [
              "module-resolver",
              {
               
                "alias": {
                  "Actions": "./app/src/actions",
                  "Assets": "./app/src/assets",
                  "Components": "./dims-common-ui/components/",
                  "Containers": "./app/src/containers",
                  "Helpers": "./helpers",
                  "Selectors": "./app/src/selectors",
                  "Utils": "./app/src/utils",
                  "Apis": "./app/src/api"
                }
              }
            ],
            "@babel/plugin-proposal-class-properties"
          ]
        }
      }
    }

On the webpack-merge readme, there are no examples using the pattern you used. Where did you see this? Have you tried to emulate the pattern of the docs? What I think this means is you define your config externally, and then run a function who returns the merge. Have you tried this?

module.exports = env => {


switch(env) {
    case 'development':
      return merge(commonConfig, developmentConfig);
    case 'production':
      return merge(commonConfig, productionConfig);
    default:
      throw new Error('No matching configuration was found!');
  }
}

you need to tell babel what it needs to transpile and you do so with @babel/register so at yow entry point you need some like this


module.exports ={
  entry: [
     "@babel/register",
     "path-to-where-your-entry-is-at"
  ]
}

So, the solution that worked for me was using webpack 4 instead of webpack as there seems to be some issue with webpack 5 and babel 7 in my use case. Thanks for your answers Ernesto and IWI!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM