skip to Main Content

I have a create-react-app application in web which I want to locally import a module that is outside of src. However, there seems to be some issue with loaders and Webpack. I have no idea why this is an issue.

Currently stuck with the following error:

Failed to compile.

../common/dist/common.js 149:26
Module parse failed: Unexpected token (149:26)
File was processed with these loaders:
 * ./node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js
 * ./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
|   return (axios = globalAxios, basePath = BASE_PATH) => {
|     const axiosRequestArgs = { ...axiosArgs.options,
>       url: (configuration?.basePath || basePath) + axiosArgs.url
|     };
|     return axios.request(axiosRequestArgs);

Folder Structure

    - app
      - common
        - api
          - openapi
            - v1
              - index.ts
              - api.ts
              - base.ts
              - common.ts
            - openapi.json
        - dist
        - package.json
        - tsconfig.json
      - web
        - public
        - src
        - package.json
        - tsconfig.json

app/common/package.json

{
  "name": "@my-module/common",
  "version": "1.0.0",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "dependencies": {
    "axios": "^0.21.1",
    "typescript": "^4.1.3"
  },
  "devDependencies": {
    "@openapitools/openapi-generator-cli": "^2.1.25"
  },
}

app/web/package.json

{
  "name": "jsapi-create-react-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    ...
    "@my-module/common": "file:../common",
    "axios": "^0.21.1",
    ...
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "ncp": "^2.0.0"
  },
  "description": "This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).",
  "main": "index.js",
  "keywords": [],
  "author": "",
  "license": "ISC"
}

tsconfig.json (basically the same for both cause I was trying a bunch of things, no change in error)

{
  "compilerOptions": {
    "target": "es2020",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext",
      "es6"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "noImplicitAny": true,
    "noImplicitThis": true,
    "strictNullChecks": true,
    "typeRoots": [
      "./node_modules/@types",
      "./custom_types"
    ]
  }
}

3

Answers


  1. You have two options:

    Option 1 – use react-app-rewired

    CRA is very opinioned regarding its configurations. Meaning, you don’t have a way to modify its configurations without using third party tools such as react-app-rewired. You can do it this way:

    1. run npm install --save-dev react-app-rewired react-app-rewire-alias customize-cra
    2. update package.json -> scripts to:
      "scripts": {
       "start": "react-scripts start",
       "start": "react-app-rewired start",
       "build": "react-scripts build",
       "build": "react-app-rewired build",
       "test": "react-scripts test",
       "test": "react-app-rewired test",
       "eject": "react-scripts eject"
    }
    
    1. create a file named config-overrides.js in the root folder:
    const { override } = require("customize-cra");
    const { alias } = require("react-app-rewire-alias");
    
    const aliasMap = {
      common: "../common",
    };
    
    module.exports = override(
      alias(aliasMap)
    );
    
    

    In a nutshell about react-app-rewire-alias:

    Currently, create-react-app (CRA) does not support more than one src directory in the project. Monorepo, multi-repo and library projects with examples require more than one directories like src.

    Option 2 – use a monorepo library

    There are many options out there, one of them is lerna. You can move both of the projects inside packages folder and then symlink them. In other words, instead of importing your common code relatively (e.g "../../../common/…"), you import it from a dependency (e.g "@myapp/common/…"). You can learn more about lerna here.

    Login or Signup to reply.
  2. This seems to be a version problem: Newer versions (5.x) of OpenAPI generates code that causes this error. Here are the steps I followed to resolve it:

    mkdir ~/openapi && cd ~/openapi
    wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/4.3.1/openapi-generator-cli-4.3.1.jar -O openapi-generator-cli-4.3.1.jar
    
    echo "#!/bin/bash" > openapi-generator
    echo "java -jar $HOME/openapi/openapi-generator-cli-4.3.1.jar $@" >> openapi-generator
    chmod +x openapi-generator
    

    Then adding $HOME/openapi to $PATH and generating the code, everything works.

    Login or Signup to reply.
  3. Webpack configuration in create-react-app is unable to handle this line, and the problem is the optional chaining – ?. (which was specified in ecma 2020)

    url: (configuration?.basePath || basePath) + axiosArgs.url
    

    Your target – "target": "es2020" – is just too high for webpack configuration.
    Just lower it to es2017 and webpack should be able to handle your package output. (Webpack config from create-react-app v4.03 uses ECMA 8, which is 2017 version)

    Also in my opinion it would be better to use typescript lib like esnext instead of es6, so you will have newest type definitions.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search