How to include Tailwind CSS styles from React component library into the app CSS bundle? - javascript

G'day,
I am building a React component library with TailwindCSS and ViteJS. The library outputs each component as a separate JS file, for example:
// #components-library/src/ComponentA.jsx
export default function ComponentA() {
return <div className="flex justify-center">Component A</div>;
}
// Bundle Output: #components-library/dist/ComponentA.js
import { j as jsx } from "./jsx-runtime.js";
import "react";
function ComponentA() {
return /* #__PURE__ */ jsx("div", {
className: "flex justify-center",
children: "Component A",
});
}
export { ComponentA as default };
The app that is consuming this components library is also using Tailwind. However, the styles are not applied to the imported component. App-specific styles are working fine.
/* app/src/index.css */
#tailwind base;
#tailwind components;
#tailwind utilities;
// app/src/App.jsx
import CompoenntA from "#component-library/ComponentA";
export default function App() {
return (
<div className="p-10">
<ComponentA />
</div>
);
}
Awaiting expert advice.
Thank you!

Currently, I am also working on a similar project as like as you. I have built my component library with rollup. It generated a CSS file then imported that CSS file to my main package.
My Rollup Config
import resolve from "#rollup/plugin-node-resolve";
import babel from "#rollup/plugin-babel";
import commonjs from "#rollup/plugin-commonjs";
import typescript from "#rollup/plugin-typescript";
import { terser } from "rollup-plugin-terser";
import external from "rollup-plugin-peer-deps-external";
import postcss from "rollup-plugin-postcss";
import swc from "rollup-plugin-swc";
import filesize from "rollup-plugin-filesize";
const packageJson = require("./package.json");
export default [
{
input: "index.ts",
output: [
{
file: packageJson.main,
format: "cjs",
sourcemap: false,
name: "#ht/components",
},
{
file: packageJson.module,
format: "esm",
sourcemap: false,
},
],
plugins: [
babel({
// this is needed because we're using TypeScript
babelHelpers: "bundled",
extensions: [".ts", ".tsx"],
}),
external(),
resolve(),
commonjs(),
typescript({ tsconfig: "./tsconfig.json" }),
postcss({
config: {
path: "./postcss.config.js",
},
extensions: [".css"],
minimize: true,
extract: "lib.css",
}),
swc({
jsc: {
parser: {
syntax: "typescript",
},
target: "es2018",
},
}),
terser(),
filesize(),
],
},
];
Main Package's index
import "#ht/components/dist/cjs/lib.css";
import "./assets/css/tailwind.css";

You should add the path of the component to the tailwind.config.js.
In my case, my component library is symlinked to the current project using yarn link and the same problem was happening. Here is what I added in tailwind.config.js:
module.exports = {
// use content instead of purge if using tailiwind v3
purge: [
"./src/**/*.{js,jsx,ts,tsx}",
"./public/index.html",
// this line fixed the issue for me
"./node_modules/{component-library-name}/src/**/*.{js,jsx,ts,tsx}"
],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {}
},
variants: {
extend: {}
},
plugins: []
};

Related

why css is not work corectly on vite lib mode?

I want to create a new npm package and I have a problem with vite lib mode.
I want my package to export some UI components that has some styles, project works fine on yarn dev but when I build it the style.css file inside dist directory is not used anywhere, so the styles not applied to the components
this is my vite.config.ts file
import { resolve } from "path";
import { defineConfig } from "vite";
import react from "#vitejs/plugin-react";
import dts from "vite-plugin-dts";
export default defineConfig({
plugins: [
react(),
dts({
insertTypesEntry: true,
}),
],
build: {
lib: {
entry: resolve(__dirname, "src/main.tsx"),
name: "MyLib",
fileName: "my-lib",
},
rollupOptions: {
external: ["react", "react-dom"],
output: {
globals: {
react: "React",
"react-dom": "ReactDOM",
},
},
},
},
});
and this is dist folder :
I know I can import my styles separately like :
import Skeleton from "skeleton-sh";
import "skeleton-sh/style";
but I want is to just import package like import Skeleton from "skeleton-sh"; and its import the styles for me

Rollup doesn't bundle all the files exported in my input src

I have a problem. I'm currently making a component library for react, it works perfectly in storybook. But when I do a npm rollup, or install my package from npm. I look inside the cjs and esm folders and not all my necessary files are there.
Here are my config files:
const packageJson = require("./package.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/esm/types/index.d.ts",
output: [{ file: "dist/index.d.ts", format: "esm" }],
plugins: [dts()],
},
];
rollup.config.ts
export * from "./components";
export * from "./core";
export * from "./themes";
export * from "./hooks";
src/index.ts
export { default as GlobalTheme } from "./global-theme";
export { default as LightTheme } from "./light-theme";
export { default as DarkTheme } from "./dark-theme";
themes/index.ts
When I try to use my library in another project it gives me a lot of compile errors :
Failed to parse source map from '...\node_modules\#gitname\LIBRARY_NAME\src\themes\light-theme.ts' file: Error: ENOENT: no such file or directory
and the same message for every single component I created in the library.
I'm honestly stuck, I tried every solution on the internet none worked.
Thank you in advance for your help
It has to do with way you are importing your components. I had exactly the same issue with the same configuration as you have.
In my case I had something like:
{
input: "dist/types/index.d.ts",
output: [{ file: "dist/index.d.ts", format: "esm" }],
plugins: [dts()],
}
When you are using the components you have to import from where the actual bundled files are. In my case it was in dist folder. so just import it like so,
Import {Button} from "#yourlib/your-lib/dist"

Individual component exports with Rollup instead of one massive index.js file?

I’m working on a proprietary component library built with React and using Rollup to bundle everything. Currently, it’s bundling everything into these files:
dist
├ cjs
│ └ index.js (1.7mb)
└ esm
└ index.js (1.7mb)
My hope is that I could instead have every component be bundled individually so the consuming app doesn’t have to download a huge index.js file, but this may be where my inexperience with Rollup kicks in.
I currently have a single entrypoint for Rollup:
input: [
'src/index.js',
],
My index.js file looks something like this (but with many more components):
import { Badge } from './components/Badge';
import { Button } from './components/Button';
import { CardFooter } from './components/CardFooter';
import { CardHeader } from './components/CardHeader';
import { CardTagList } from './components/CardTagList';
import { CardToolbar } from './components/CardToolbar';
import { CartAnimation } from './components/CartAnimation';
export {
Badge,
BasePrice,
Button,
CardFooter,
CardHeader,
CardTagList,
CardToolbar,
CartAnimation,
};
What do I have to do to ensure that components are each bundled separately and can still be imported in the apps that use the library with:
import { Button } from '#company/component-library';
Here is my full config as it stands today:
import { babel } from '#rollup/plugin-babel';
import { terser } from 'rollup-plugin-terser';
import commonjs from '#rollup/plugin-commonjs';
import dynamicImportVars from '#rollup/plugin-dynamic-import-vars';
import eslint from '#rollup/plugin-eslint';
import json from '#rollup/plugin-json';
import resolve from '#rollup/plugin-node-resolve';
import stylelint from 'rollup-plugin-stylelint';
import styles from 'rollup-plugin-styles';
require('dotenv').config();
export default {
external: [
'react',
'react-dom',
'styled-components',
],
input: [
'src/index.js',
],
output: [
{
// Bundle into ESM for modern consumers.
// Only ESM build can currently be tree-shaken.
dir: 'dist/esm',
format: 'esm',
},
{
// Bundle into CJS for other consumers.
dir: 'dist/cjs',
format: 'cjs',
},
],
plugins: [
eslint({
include: '**/*.js',
throwOnError: true,
}),
stylelint(),
babel({
babelHelpers: 'bundled',
exclude: 'node_modules/**',
}),
resolve({
browser: true,
}),
styles(),
commonjs(),
json(),
dynamicImportVars({}),
terser(),
],
};
Note: Probably not important, but this project is published to npm as a private repo, but currently the app that uses it installs it using a commit hash.
You could try adding the preserveModule
export default {
preserveModules: true,
...
}
I have done some tweek to the rollup config. My problem statement was to export custom elements seperately. Find my custom solution below:
function generateComponentConfig() {
const dir = fs.readdirSync("./src/web-components");
return dir.map(folderName => {
return {
input: [`src/web-components/${folderName}/index.js`],
output: [
{ file: `public/build/wc/${folderName}.mjs`, 'format': 'es' },
{ file: `public/build/wc/${folderName}.js`, 'format': 'umd', name: folderName }
],
plugins: [
svelte({ compilerOptions:{customElement: true}, emitCss: false, include: /\.wc\.svelte$/ }),
svelte({ compilerOptions: {customElement: false}, emitCss: false, exclude: /\.wc\.svelte$/ }),
resolve()
]
};
})};
Use the above function in your export as below
export default [
...generateComponentConfig(), {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/bundle.js',
},
plugins: plugins(),
watch: {
clearScreen: false,
}}];

Rollup error: could not load a module from #babel/runtime when importing a Material-UI component

I'm trying to compile this index.js file using rollup:
import React from "react";
import ReactDOM from "react-dom";
import Grid from "#material-ui/core/Grid";
ReactDOM.render(
<React.StrictMode>
<Grid container>
</Grid>
</React.StrictMode>,
document.getElementById('root')
);
rollup.config.js:
import { nodeResolve } from '#rollup/plugin-node-resolve';
import babel from '#rollup/plugin-babel';
import commonjs from '#rollup/plugin-commonjs';
export default {
input: 'index.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
},
plugins: [
nodeResolve(),
babel({ babelHelpers: 'bundled', exclude: /node_modules/ }),
commonjs(),
],
};
babel.config.json:
{
"presets": [
"#babel/preset-react",
"#babel/preset-env"
]
}
Now, when I run npx rollup -c i get this error:
[!] Error: Could not load /home/recursive-beast/Desktop/repositories/myproject/node_modules/#babel/runtime/helpers/esm/objectWithoutProperties (imported by node_modules/#material-ui/core/esm/Grid/Grid.js): ENOENT: no such file or directory, open '/home/recursive-beast/Desktop/repositories/myproject/node_modules/#babel/runtime/helpers/esm/objectWithoutProperties'
This is unexpected because #babel/runtime is a dependency of #material-ui/core, and I already checked that it is installed in the node_modules folder.
I've been trying to figure out the solution since yesterday without success, so what could be the source of the problem?
I found a workable solution.
I just add the #rollup/plugin-alias plugin
... //other code
const alias = require('#rollup/plugin-alias');
module.exports = [
{
... // other config
plugins: [
alias({
entries: [
{ find: '#ui/lab', replacement: '#material-ui/lab/esm' },
{ find: '#ui/core', replacement: '#material-ui/core/esm' },
{ find: '#ui/icons', replacement: '#material-ui/icons/esm' },
{ find: /^#babel\/runtime\/helpers\/(.*)$/, replacement: '#babel/runtime/helpers/$1.js' }
]
}),
...// other plugins
],
},
]
Use #material-ui in js files
import Alert from '#ui/lab/Alert'
import AppBar from '#ui/core/AppBar'
import Toolbar from '#ui/core/Toolbar'
import Grid from '#ui/core/Grid'
import Paper from '#ui/core/Paper'
import Container from '#ui/core/Container'
import PlayIcon from '#ui/icons/PlayArrow'
import {
createMuiTheme,
ThemeProvider,
makeStyles,
createStyles
} from '#ui/core/styles'
import red from '#ui/core/colors/red'
... // other code
Above, hope it helps.
We had the same, after days of researching we solved it by setting jail: '/A_PATH_THAT_DOESNT_EXIST' to nodeResolve to be like the following.
nodeResolve({
// Lock the module search in this path (like a chroot). Module defined
// outside this path will be marked as external
jail: '/A_PATH_THAT_DOESNT_EXIST', // Default: '/'
})

rollupjs dynamic require not bundling

I've a component library with an Atom component that have an external lib for do a specific task. This external lib (imported in this component) have a dynamic svg import like that:
require('../flags/' + countryCode.toLowerCase() + '.svg') and I can compile it without any error. But when I use this lib give me that error: Can't resolve '../flags'.
There's my rollup.config.js
import { nodeResolve } from "#rollup/plugin-node-resolve";
import postcss from "rollup-plugin-postcss";
import babel from '#rollup/plugin-babel';
import peerDepsExternal from "rollup-plugin-peer-deps-external";
import commonjs from '#rollup/plugin-commonjs';
import svg from 'rollup-plugin-svg'
import path from 'path'
export default {
input: "src/index.js",
output: {
file: "lib/bundle.js",
format: "cjs",
},
external: [
'react',
'react-dom',
'prop-types',
],
plugins: [
peerDepsExternal(),
nodeResolve({
extensions: [".jsx", ".js"],
}),
postcss({
extract: true,
namedExports: true,
extensions: ['.sass', '.scss'],
modules: true,
use: [
[
'sass', {
includePaths: [path.resolve('node_modules')]
}
]
]
}),
babel({
babelHelpers: 'runtime',
exclude: 'node_modules/**',
}),
commonjs(),
svg()
],
};
How I can fix this problem? I cannot change the dynamic import because it's an external lib, any other solution?
Have you tried:
...,
commonjs({
dynamicRequireTargets: 'path/to/your/file'
}),
...

Categories