Reputation: 85
I try to create a monorepo with 2 React packages:
app
--template typescript)ui
)I've got a basic lerna.json
configuration
{
"packages": ["packages/*"],
"version": "1.0.0"
}
In the ui
package I simply export one Button (from src/Button.jsx
):
import React from 'react';
const Button = () => {
return (
<button>
Start
</button>
)
}
export default Button;
I've bootstrapped app
to use the ui
package.
Importing it inside the app
causes the following error:
Failed to compile
/lerna-demo/packages/ui/src/Button.jsx 5:4
Module parse failed: Unexpected token (5:4)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| const Button = () => {
| return (
> <button>
| Start
| </button>
Is there a way to add a loader to lerna or app
to fix the import?
EDIT
The project structure:
lerna-demo/
- node_modules/
- lerna.json
- package.json
- packages/
- app (created using create-react-app)
- ...
- ui
- node_modules/
- package.json
- yarn.lock
- src/
- Button.jsx
The way I import the Button component:
import React from 'react';
import logo from './logo.svg';
import './App.css';
import * as Button from 'ui/src/Button';
const App: React.FC = () => {
return (
<div className="App">
<Button />
</div>
);
}
export default App;
Upvotes: 5
Views: 1153
Reputation: 5389
I followed this answer and was able to import my separate standalone package in my lerna monorepo into my CRA typescript app by using craco and pointing the webpack config to my standalone package. I find this solution easier to manage instead of ejecting from your existing CRA config.
Given this structure:
├── package.json
├── packages
│ ├── app
│ ├── ui
└── yarn.lock
...here are the main steps:
craco
in app/package.json
:yarn add @craco/craco
craco.config.js
file in the CRA project root├── package.json
├── packages
│ ├── app
│ │ ├── src
│ │ └── craco.config.json <--- in CRA project root
│ │
│ ├── ui
│ │ ├── src
│
│
└── yarn.lock
// project/app/craco.config.js
// ---
const path = require('path');
/**
* ALlows us to edit create-react-app configuration
* without ejecting.
*
*
*/
const { getLoader, loaderByName } = require('@craco/craco');
// Replace `components` with your folder's structure.
// Again, Here I'm showcasing my current project.
const absolutePath = path.join(__dirname, '../ui');
/**
* This is extremely important if you're using a CI/CD to build and deploy
* your code!!! Read!
*
* If you create a package with a namespace, such as name is @schon/components, you need
* to add what I've commented down below. Otherwise Yarn will fail in CI/CD environments!!
*/
// const uiComponents = path.join(
// __dirname,
// './node_modules/ui',
// );
module.exports = {
webpack: {
configure: (webpackConfig, { env, paths }) => {
// https://medium.com/frontend-digest/using-create-react-app-in-a-monorepo-a4e6f25be7aa
const { isFound, match } = getLoader(
webpackConfig,
loaderByName('babel-loader'),
);
if (isFound) {
const include = Array.isArray(match.loader.include)
? match.loader.include
: [match.loader.include];
// match.loader.include = include.concat(absolutePath, uiComponents);
match.loader.include = include.concat(absolutePath);
}
return {
...webpackConfig,
/**
* Optionally, other webpack configuration details.
*/
// optimization: {
// splitChunks: {
// },
// },
};
},
},
};
Upvotes: 0
Reputation: 5253
In your tsconfig.json
created by CRA you will need to tell the compiler to include also the ui pacakge so in your example its something like that:
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
},
"include": [
"src", "../ui/src",
]
}
Another option is to extend your base lerna tsconfig.json
and there its already points to your package with path
I guess - so from your CRA tsconfig.json
just add this:
{
"extends": "../../tsconfig.json",
and in base tsconfig.json
u should define the alias name to the path:
main tsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"ui/*": ["./packages/ui/*"],
Upvotes: 3