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
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 usingnpm run eject
, and edit the resultingconfig/webpack.config.js
to include processing the node_modules with typescript, which is a little more involved, as you have to search forisTypescript()
, and the object following, remove theexclude
andinclude
properties.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: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.