Rollup: inject "import index.css" into the index.ts file - reactjs

I have a project that I want to create an NPM package from it.
My stack is: React, Typescript, less, and AntD.
When I'm creating a bundle with rollup.js, everything workes fine, but, the import CSS isn't injected to the top of the index.ts that I'm exporting. the only way I was able to have the CSS code in another project is by explicitly importing the CSS file (import "mypackage/dist/index.css").
I'm searching for a way to config rollup to inject the line import "./index.css" to the beginning of the main index.ts file. I have tried a lot of plugins of css/less, with no success.
Here is my current rollup.config.js:
import typescript from "rollup-plugin-typescript2";
import postcss from "rollup-plugin-postcss";
import pkg from "./package.json";
export default {
input: "src/index.tsx",
output: [
{
file: pkg.main,
format: "esm",
exports: 'named',
sourcemap: true,
strict: false,
},
],
plugins: [
postcss({
extensions: ['.less', '.css'],
minimize: true,
modules: true,
use: {
sass: null,
stylus: null,
less: { javascriptEnabled: true },
},
extract: true,
}),
typescript({
objectHashIgnoreUnknownHack: true,
sourceMap: true,
inlineSources: true,
}),
],
external: ["react", "react-dom"],
};

Related

Fail to integrate scss in my rollup build

What I try to achieve
I'm trying to create a little library for private use - basically just splitting up some code into lib (product) and app (project) code.
All my source code lives in /src folder which contains React, TypeScript and SCSS code. It would be great, if I can use the SCSS imports directly in React like: import './_button.scss';
I have another SCSS file: src/style/_main.scss it includes some mixins, global styles, resets etc.
Config files
import commonjs from '#rollup/plugin-commonjs';
import json from '#rollup/plugin-json';
import resolve from '#rollup/plugin-node-resolve';
import terser from '#rollup/plugin-terser';
import typescript from '#rollup/plugin-typescript';
import url from '#rollup/plugin-url';
import dts from 'rollup-plugin-dts';
import scss from 'rollup-plugin-scss';
import { format, parse } from 'path';
import pkg from './package.json' assert { type: 'json' };
const getTypesPath = (jsFile) => {
const pathInfo = parse(jsFile);
return format({
...pathInfo,
base: '',
dir: `${pathInfo.dir}/types`,
ext: '.d.ts',
});
};
export default [
{
input: 'src/index.ts',
output: [
{
file: pkg.main,
format: 'cjs',
interop: 'compat',
exports: 'named',
sourcemap: true,
inlineDynamicImports: true,
},
{
file: pkg.module,
format: 'esm',
exports: 'named',
sourcemap: true,
inlineDynamicImports: true,
},
],
plugins: [
resolve({ browser: true }),
commonjs({ extensions: ['.js', '.jsx', '.ts', '.tsx'] }),
typescript({ tsconfig: './tsconfig.build.json' }),
url(),
scss({
failOnError: true
}),
json(),
terser(),
],
external: ['react', 'react-dom'],
},
{
input: getTypesPath(pkg.module ?? pkg.main),
output: [{ file: pkg.types, format: 'esm' }],
plugins: [dts()],
},
];
My tsconfig.build.json looks like this:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./types",
"declaration": true,
"declarationDir": "./types",
"allowSyntheticDefaultImports": true
}
}
Where I struggle
The main issue right now is, that it imports my SCSS file in the definition file e.g. button.d.ts looks like:
import type { FunctionComponent } from 'react';
import type { IButtonProps } from './button.type';
import './_button.scss';
export declare const Button: FunctionComponent<IButtonProps>;
[!] RollupError: Could not resolve "./_button.scss" from "build/esm/types/button/button.d.ts"
Which is indeed a problem, but how can I fix it?
I also get the error:
Error:
#use rules must be written before any other rules.
╷
4 │ #use 'src/style/util/mixin';
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
╵
stdin 4:1 root stylesheet
But it does not really make a lot of sense, since my _button.scss partial has this written on the first line.
My Question
How do I make it work so that I can use SCSS in my library? The best case would be that I don't have to touch my original code. I just want to transpile/bundle it so I can use it somewhere else. Any advice?
After hours of probing, I finally made it work.
The issue was, that it bundled all my sass styles and it did not take into account, that I am using the new #use module syntax. Because everything got concatenated into one big file, #use syntax got placed in the middle of the file resulting in an error. Apparently, only the old #import syntax is properly supported by rollup-plugin-scss - or I was just too incapable of making it work.
So I switched to the https://anidetrix.github.io/rollup-plugin-styles/
library to process the files. All I had to do is to use the styles plugin and I set mode: 'inject' it then injected the styles into my [esm|cjs]/index.js file. Upon importing the lib in the app and starting it, the styles got applied.
Besides, I also had to externalize the imports from the index.d.ts.
The updated config file:
import commonjs from '#rollup/plugin-commonjs';
import json from '#rollup/plugin-json';
import resolve from '#rollup/plugin-node-resolve';
import terser from '#rollup/plugin-terser';
import typescript from '#rollup/plugin-typescript';
import url from '#rollup/plugin-url';
import { format, parse } from 'path';
import dts from 'rollup-plugin-dts';
import external from 'rollup-plugin-peer-deps-external';
import styles from 'rollup-plugin-styles';
import pkg from './package.json' assert { type: 'json' };
const getTypesPath = (jsFile) => {
const pathInfo = parse(jsFile);
return format({
...pathInfo,
base: '',
dir: `${pathInfo.dir}/types`,
ext: '.d.ts',
});
};
export default [
{
input: 'src/index.ts',
output: [
{
file: pkg.main,
format: 'cjs',
interop: 'compat',
exports: 'named',
sourcemap: true,
inlineDynamicImports: true,
},
{
file: pkg.module,
format: 'esm',
exports: 'named',
sourcemap: true,
inlineDynamicImports: true,
},
],
external: ['react', 'react-dom'],
plugins: [
external(),
resolve({
browser: true,
}),
url(),
styles({
mode: 'inject'
}),
json(),
commonjs({
extensions: ['.js', '.jsx', '.ts', '.tsx'],
}),
typescript({
tsconfig: './tsconfig.build.json',
}),
terser(),
],
},
{
input: getTypesPath(pkg.module ?? pkg.main),
output: [
{
file: pkg.types,
format: 'esm',
},
],
external: [/\.(sass|scss|css)$/] /* ignore style files */,
plugins: [dts()],
},
];

React npm packages using rollup not working with srr or nextjs?

I create a simple react packages for personal uses (private package). But when I want to use it into nextjs project it's css not working with ssr. Actually, working but not ssr friendly. Here after component loading then css will be loaded. But I want it with ssr. I mean css also work with ssr.
rollup.config.mjs-
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 postcss from "rollup-plugin-postcss";
import peerDepsExternal from "rollup-plugin-peer-deps-external";
export default [
{
input: "src/index.ts",
output: [
{
file: "dist/cjs/index.js",
format: "cjs",
sourcemap: true,
},
{
file: "dist/esm/index.js",
format: "esm",
sourcemap: true,
},
],
plugins: [
peerDepsExternal(),
resolve(),
commonjs(),
typescript({ tsconfig: "./tsconfig.json" }),
postcss()
],
external: ["react", "react-dom"]
},
{
input: "dist/esm/types/index.d.ts",
output: [{ file: "dist/index.d.ts", format: "esm" }],
plugins: [dts()],
external: [/\.css$/]
}
];
Can anyone help me.

React libray created with rollup not working css with srr or nextjs?

I create a simple react packages for personal uses (private package). But when I want to use it into nextjs project it's css not working with ssr. Actually, working but not ssr friendly. Here after component loading then css will be loaded. But I want it with ssr. I mean css also work with ssr.
rollup.config.mjs-
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 postcss from "rollup-plugin-postcss";
import peerDepsExternal from "rollup-plugin-peer-deps-external";
export default [
{
input: "src/index.ts",
output: [
{
file: "dist/cjs/index.js",
format: "cjs",
sourcemap: true,
},
{
file: "dist/esm/index.js",
format: "esm",
sourcemap: true,
},
],
plugins: [
peerDepsExternal(),
resolve(),
commonjs(),
typescript({ tsconfig: "./tsconfig.json" }),
postcss()
],
external: ["react", "react-dom"]
},
{
input: "dist/esm/types/index.d.ts",
output: [{ file: "dist/index.d.ts", format: "esm" }],
plugins: [dts()],
external: [/\.css$/]
}
];

RollupError: Node tried to load your configuration as an ES module even though it is likely CommonJS

I am trying to build a library of components in React, and I am using Rollup to bundle things up. It is the first time that I am using it and I have watched a couple of tutorials and followed their setup (like this).
Here is my rollup.config.js 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";
const packageJson = require("./package.json");
export default [
{
input: "src/index.ts",
output: [
{
file: packageJson.main, //CommonJS
format: "cjs",
sourcemap: true,
},
{
file: packageJson.module, //ES6
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()],
}
];
Now, when I run rollup, I am getting the error below. I have tried changing the file extension or use the flag as suggested, but the solutions are not working.
Thoughts?
You can try the following steps:
Add the line "type": "module" to your package.json file
Add this line import packageJson from './package.json' assert { type: 'json' }; to your rollup.config.js file
I hope it will be useful

How to process css/scss from a specific .scss file (and not entry.js) using rollup

I'm currently using Rollup and PostCSS. How do I target a specific scss file that I want to be processed rather than having to use #import 'source/scss/main.scss'in mysource/js/entry.js`
For example doing something like...
// rollup.config.js
...
postcss({
from: 'source/scss/main.scss'
minimize: true,
sourceMap: true,
extract : 'build/css/main.css'
}),
...
Rather than in source/js/entry.js
//source/js/entry.js
import '../scss/main.scss'; // don't want to import SCSS from within JS file
import { someJSmodule } from './someJSmodule.js';
import { anotherJSmodule } from './anotherJSmodule.js';
Here is my current rollup.config.js
// rollup.config.js
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import copy from 'rollup-plugin-copy';
import postcss from 'rollup-plugin-postcss';
export default {
input: 'source/js/entry.js',
output: {
file: 'build/js/bundle.js',
format: 'iife'
},
plugins: [
copy({
'source/index.html': 'build/index.html',
verbose: true
}),
resolve({
preferBuiltins: true
}),
postcss({
minimize: true,
sourceMap: true,
extract : 'build/css/main.css'
}),
commonjs(),
babel({
exclude: 'node_modules/**'
})
]
};

Resources