I am trying to setup a new project with lerna, react-scripts, webpack and sass.
My directory structure is the following
myApp
/packages
/myReactApp -> this is a react create app application
/tsconfig.json
/package.json
/components -> this is built using webpack
/dist => is is autogenerated
/index.js
/index.d.ts
/elements
/Button.d.ts
/tsconfig.json
/package.json
/webpack.config.js
/src/elements/Button
/Button.tsx
/Button.scss
/tsconfig.json
/tsconfig.settings.josn
/package.json
in my /packages/myReactApp/src/components/SomeComponent.js import a component from the 'components' package.
import { Button } from 'components';
the /packages/myReactApp/package.json file from myReactApp has a dependency of the 'components' package
{
"name": "myApp",
"version": "1.0.0",
"private": true,
"main": "src/index.tsx",
"dependencies": {
"@types/react-router-dom": "^5.1.5",
"cra-template-typescript": "1.0.3",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.0",
"types": "^0.1.1",
"components": "1.0.0" => this is the dependency of the other package
},
"scripts": {
"start": "react-scripts start",
==> "myApp:start": "yarn run start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
}
the /packages/myReactApp/tsconfig.json file looks like this
{
"extends": "../tsconfig.settings.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"skipLibCheck": true
},
"references": [
{
"path": "../components"
}
],
"include": [
"src"
]
}
the /packages/components/package.json looks like this
{
"name": "components",
"version": "1.0.0",
"main": "./dist/index.js",=> this file is generate by webpack and is in the right location
"types": "./dist/index.d.ts", => this file is generate by webpack and is in the right location
"scripts": {
"delete": "rimraf dist",
"start": "yarn run delete && webpack --env.mode development --watch",
"myApp:start": "yarn run start",
"test": "jest"
},
"devDependencies": {
....
}
}
/packages/components/webpack.config.js
module.exports = {
mode: 'development',
entry: './src/index.tsx',
output: {
filename: 'index.js',
path: __dirname + '/dist',
libraryTarget: 'commonjs',
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.css', '.scss'],
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.scss$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{ loader: 'sass-loader' },
],
},
{ test: /\.tsx?$/, loader: 'ts-loader' },
],
}
};
/packages/tsconfig.json
{
"files": [],
"references": [
{ "path": "myReactApp" },
{ "path": "components" }
]
}
/packages/tsconfig.settings.json
{
"compilerOptions": {
"target": "es6",
"module": "esnext",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"strict": true,
"composite": true,
"esModuleInterop": true,
"moduleResolution": "node",
"jsx": "react",
"skipLibCheck": false
}
}
the error is the following:
/Users/.../projects/.../MyApp/packages/myReactApp/src/components/SomeComponent/myComponent.tsx
TypeScript error in /projects/.../myApp/packages/myReactApp/src/components/SomeComponent/myComponent.tsx(3,26):
Cannot find module 'components'. TS2307
The index.js and index.d.ts files are generated corectly in the components package, however the main react app doesn't know about it.
my guess is that I run a rimraf /dist when I start the webpack server and lerna start the two projects in paralel, and myApp starts first and it doesn't know about the definition from the dependency package.
I tried combining the "composite": true option with the references option but it didn't work. maybe I am missing something.
I also tried to use tsc instead of webpack to run the /packages/components package. It worked very well, but the problem with tsc is that I cannot import scss files (or other type of files). So it might also be a webpack configuration issue.
EDIT: If I change the import from import { Button } from 'component'; to import { Button } from 'component/'; it will start working, even if I remove the / again. (Or I can remove the entire line, let the webpack recompile and add it back)
Thank you for reading this long post. Please let me know if you need any more details.