简体   繁体   中英

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 eg 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()],
    },
];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM