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

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/**'
})
]
};

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 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

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

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"],
};

rollup MISSING_NODE_BUILTINS error when I include it

I keep getting this error:
src/legacy/widgetlib.tsx → dist/withReact16/browser.js...
{
code: 'MISSING_NODE_BUILTINS',
message: "Creating a browser bundle that depends on Node.js built-in module ('punycode'). You might need to include https://www.npmjs.com/package/rollup-plugin-node-builtins",
modules: [ 'punycode' ],
toString: [Function]
}
I have included rollup-plugin-node-builtins in multiple different ways and I've googled all over the place. Every "solution" I've found seems to basically be the same thing, but it isn't working for me. I am also not even directly using punycode. Two of my dependencies have it as a dependency. I am using twitter-text lib and oauth-signature. If I comment out those two imports I no longer get this problem. Here is my complete rollup.config.js file:
import resolve from '#rollup/plugin-node-resolve';
import postcss from 'rollup-plugin-postcss';
import commonjs from '#rollup/plugin-commonjs';
import babel from 'rollup-plugin-babel';
import json from '#rollup/plugin-json';
import image from '#rollup/plugin-image';
import replace from 'rollup-plugin-replace';
import gzipPlugin from 'rollup-plugin-gzip';
import { terser } from 'rollup-plugin-terser';
import includePaths from 'rollup-plugin-includepaths';
import builtins from 'rollup-plugin-node-builtins';
import globals from 'rollup-plugin-node-globals';
import React from 'react';
import ReactDOM from 'react-dom';
const extensions = ['.js', '.jsx', '.ts', '.tsx'];
const { PRODUCTION } = process.env;
const CODES = [
'THIS_IS_UNDEFINED',
'MISSING_GLOBAL_NAME',
'CIRCULAR_DEPENDENCY',
];
const globalVars = {
react: 'React',
'react-dom': 'ReactDOM',
};
const discardWarning = warning => {
if (CODES.includes(warning.code)) {
return;
}
// eslint-disable-next-line no-console
console.error(warning);
};
const commonConfig = {
onwarn: discardWarning,
plugins: [
replace({
'process.env.NODE_ENV': JSON.stringify(
PRODUCTION ? 'production' : 'development'
),
}),
image(),
globals(),
builtins(),
resolve({
jsnext: true,
extensions,
preferBuiltins: true,
browser: true,
mainFields: ['browser', 'jsnext', 'module', 'main'],
}),
includePaths({
paths: ['src'],
extensions: [...extensions, '.scss', '.json'],
}),
commonjs({
include: 'node_modules/**',
namedExports: {
react: Object.keys(React),
'react-dom': Object.keys(ReactDOM),
},
}),
babel({
extensions,
runtimeHelpers: true,
babelrc: true,
exclude: 'node_modules/**',
}),
json(),
postcss({
plugins: [],
}),
terser(),
],
};
const browserLibWithReact16 = {
...commonConfig,
input: 'src/legacy/widgetlib.tsx',
output: {
format: 'iife',
sourcemap: true,
name: 'WLIB',
file: 'dist/withReact16/browser.js',
},
plugins: [...commonConfig.plugins, gzipPlugin()],
};
const npmWLIBWithReact16 = {
...commonConfig,
input: 'src/widgetlib.tsx',
output: {
file: 'dist/withReact16/WLIB.js',
format: 'esm',
sourcemap: true,
},
};
const npmLibNoReact = {
...commonConfig,
external: Object.keys(globalVars),
input: 'src/widgetlib.tsx',
output: {
file: 'dist/index.js',
format: 'esm',
sourcemap: true,
},
};
export default [npmLibNoReact, npmWLIBWithReact16, browserLibWithReact16];
The error is only happening for the browserLibWithReact16 config.
Any help would be appreciated.

Resources