skip to Main Content

I have tried to write a public component rd-component that contains some public page which used cross all project. when I import this public page, shows error:

Module parse failed: The keyword 'interface' is reserved (15:0)

I have made a minimal reproduce example, this is the simple component which use the public page:

import './App.css';
import React from 'react';
import Goods from "rd-component/src/component/good/Goods";

const Chat: React.FC = (props) => {

  return (<Goods></Goods>);
}

export default Chat;

this is the Index.tsx:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css';
import reportWebVitals from './reportWebVitals';
import Chat from './App';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <Chat />
  </React.StrictMode>
);


reportWebVitals();

this is my package.json contains all package:

{
  "name": "react-demo",
  "version": "0.1.0",
  "private": true,
  "config-overrides-path": "src/config/config-overrides.js",
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "@textea/json-viewer": "^2.16.2",
    "@types/jest": "^27.5.2",
    "@types/node": "^16.18.21",
    "@types/react": "^18.0.30",
    "@types/react-dom": "^18.0.11",
    "antd": "^5.4.0",
    "prismjs": "^1.29.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "react-syntax-highlighter": "^15.5.0",
    "typescript": "^4.9.5",
    "web-vitals": "^2.1.4",
    "rd-component": "0.1.1"
  },
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@types/react-syntax-highlighter": "^15.5.6",
    "customize-cra": "^1.0.0",
    "react-app-rewired": "^2.2.1"
  }
}

this is the full error output when running command npm run build:

> [email protected] build
> react-scripts build

Creating an optimized production build...
Failed to compile.

Module parse failed: The keyword 'interface' is reserved (15:0)
File was processed with these loaders:
 * ./node_modules/source-map-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
| import { doPay } from "@/service/pay/PayService";
| 
> interface IGoodsProp {
|   appId: string;
| }

2

Answers


  1. The problem is that react-scripts is loading webpack without a proper Typescript loader.

    The easiest way to fix this is to add a tsconfig.json file to your react project.

    If the public component is in the node_modules folder, either through the use of workspaces or npm packages, you have to eject the project using npm run eject, and edit the resulting config/webpack.config.js to include processing the node_modules with typescript, which is a little more involved, as you have to search for isTypescript(), and the object following, remove the exclude and include properties.

    Login or Signup to reply.
  2. By default TypeScript (or possibly create-react-app, if that is what you are using) does not compile modules from node_modules.

    Your Goods component seems to be in that case:

    import Goods from "rd-component/src/component/good/Goods";
    
    {
      "dependencies": {
        // ...
        "rd-component": "0.1.1"
      }
    }
    

    The default configuration assumes that everything in node_modules is ready for consumption by plain JavaScript projects.

    So a TypeScript-written library component is expected to be already transpiled into JavaScript.

    That being said, you can still try an easy workaround which consists in having a symlink in your project src that points to the TypeScript file of your library source.

    IIRC, unfortunately some build engines are "too" smart and see the actual path even through the symlink… in that case, you would have to manually include your library in the compilation scope.

    Of course, the proper solution is to pre-compile your library.

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