I've been beating my head against a wall for days, so I'm throwing myself on the mercy of people who are smarter than me.
(Sorry for the length... I'm trying to be thorough)
I'm currently working a small app where I'm using a component library I'm developing myself. I'm connecting to the library locally using "@name/library": "link:/path/to/library"
in the package.json
in my app. I'm exporting the components from the library using barrel files (hate me if you want). I'm also using rollup as my bundler for the library. Starting from the library component on up they look like this:
library/src/components/FormElements/FormTextInput.tsx
import FormInputLabel from './FormInputLabel';
type FormTextInputProps = {
label?: string;
name?: string;
type?: 'text' | 'password' | 'number';
labelPos?: 'left' | 'right' | 'above' | 'below';
value?: string | number;
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
};
const FormTextInput: React.FC<FormTextInputProps> = ({
label = '',
name = '',
type = 'text',
labelPos = 'left',
value = '',
onChange
}) => {
const onChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
onChange?.(e);
};
return (
<div>
{labelPos === 'left' || labelPos === 'above' ? (
<FormInputLabel position={labelPos} name={name} label={label} />
) : (
''
)}
<input
value={value}
type={type}
name={name}
id={name}
onChange={onChangeHandler}
/>
{labelPos === 'right' || labelPos === 'below' ? (
<FormInputLabel position={labelPos} name={name} label={label} />
) : (
''
)}
</div>
);
};
export default FormTextInput;
library/src/components/FormElements/index.ts
export { default as FormInputLabel } from './FormInputLabel';
export { default as FormTextInput } from './FormTextInput';
library/src/components/index.ts
export * from "./FormElements";
library/src/index.ts
export * from "./components";
Here's the component in my app, consumes it (collapsed):
MovieEditor.tsx
import { useQuery, useMutation } from '@apollo/client';
import { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import { useLocation } from 'react-router-dom';
import { GET_MOVIE } from './queries';
import { ADD_MOVIE, UPDATE_MOVIE } from './mutations';
import FormTextInput from '@name/library'; <-- No complaints about import
.......
const MovieEditor: React.FC = () => {
...........
return (
<>
<h3 className="text-lg font-semibold p-4">Create/Update Movie</h3>
<FormTextInput label="Not Working" /> <-- Errors here
<form ...
</form>
</>
);
};
export default MovieEditor;
Here are the errors I'm getting - Both on the same line:
Don't know if this helps, but here is my rollup.config.mjs
file:
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "@rollup/plugin-typescript";
import dts from "rollup-plugin-dts";
import packageJson from "./package.json" assert { type: "json" };
export default [
{
input: "src/index.ts",
output: [
{
file: packageJson.main,
format: "cjs",
sourcemap: true,
},
{
file: packageJson.module,
format: "esm",
sourcemap: true,
},
],
plugins: [
resolve(),
commonjs(),
typescript({ tsconfig: "./tsconfig.json" }),
],
},
{
input: "dist/ems/types/index.d.ts",
output: [{ file: "dist/index.d.ts", format: "esm" }],
plugins: [dts()],
},
];
And my package.json
for the library:
{
"name": "@name/library",
"publishConfig": {
"registry": "https://npm.pkg.github.com/name"
},
"version": "0.0.0",
"type": "module",
"module": "dist/ems/index.js",
"main": "dist/cjs/index.js",
"files": [
"dist"
],
"types": "dist/index.d.ts",
"scripts": {
"rollup": "rollup -c",
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"@rollup/plugin-commonjs": "^26.0.1",
"@rollup/plugin-terser": "^0.4.4",
"@stylexjs/stylex": "^0.7.5",
"react": "^18.3.0",
"react-dom": "^18.3.0"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-typescript": "^11.1.6",
"@types/react": "^18.3.0",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^7.13.1",
"@typescript-eslint/parser": "^7.13.1",
"@vitejs/plugin-react": "^4.3.1",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.7",
"react": "^18.3.1",
"rollup": "^4.18.0",
"rollup-plugin-dts": "^6.1.1",
"tslib": "^2.6.3",
"typescript": "^5.2.2",
"vite": "^5.3.1"
},
"peerDependencies": {
"react": "^18.3.1"
}
}
When I try import FormTextInput from '@name/library/src/components/FormElements/FormTextInput.tsx
it works like a champ.
I have tried every possible permutations of making those barrel files. I've checked spelling 1000 times (I really hope this isn't the problem 😅). I have Googled and tried every suggestion under the sun. Codeium hasn't be very helpful -- Just tells me to do what I've already tried.
And if you know a better way to do what I'm tying to do, feel free to drop that on me as well.
Please! Someone! Be my hero!
It is a default export in library/src/components/FormElements/FormTextInput.tsx
so if you import it like import FormTextInput from '@name/library/src/components/FormElements/FormTextInput.tsx'
it works.
However, in library/src/components/FormElements/index.ts
you have export { default as FormTextInput } from './FormTextInput';
which means it's re-exported as a named export FormTextInput
.
Then you have export *
statements in library/src/components/index.ts
, and again in library/src/index.ts
so FormTextInput
is also a named export there, and should be imported like import { FormTextInput } from '@name/library'
.
There error you saw occurred because you tried using a default export from library/src/index.ts
(which was probably something else, and it has no construct or call signatures).