Anidetrix / rollup-plugin-styles

🎨 Universal Rollup plugin for styles: PostCSS, Sass, Less, Stylus and more.
https://anidetrix.github.io/rollup-plugin-styles
MIT License
244 stars 43 forks source link

Custom injector for server-side rendering (loosing treeshakeable ability) #169

Open HeadFox opened 3 years ago

HeadFox commented 3 years ago

Currently we need to use a custom injector to be able to retrieve all styles for SSR.

import originalInjector from 'rollup-plugin-styles/dist/runtime/inject-css';
const injectCss = (css) => {
    if (typeof document === 'undefined') {
        if (global.ssrStyles) global.ssrStyles.push(css);
        else global.ssrStyles = [];
    }
    originalInjector(css, {
        singleTag: true,
    });
};

export default injectCss;

Then we get the global.ssrStyles on our Next.js _document.tsx

import Document, { Head, Html, Main, NextScript } from 'next/document';

export default class MyDocument extends Document {
    static async getInitialProps(ctx: any) {
        const initialProps = await Document.getInitialProps(ctx);

        //@ts-ignore
        const globalStyle = global.ssrStyles.join(' ');

        return {
            ...initialProps,
            styles: (
                <>
                    {initialProps.styles}
                    {[
                        <style
                            dangerouslySetInnerHTML={{ __html: globalStyle }}
                            id="server-side-styles"
                        />,
                    ]}
                </>
            ),
        };
    }
    render() {
        return (
            <Html lang="fr">
                <Head />
                <body>
                    <Main />
                    <NextScript />
                </body>
            </Html>
        );
    }
}

My rollup-plugin-styles config (preserveModules enabled):

 styles({
    autoModules: true,
    minimize: true,
    mode: [
        'inject',
        (varname) => {
            const pathInjector = path.resolve('./tools/rollup/inject-css.js');
            return ` import injectCss from '${pathInjector}';injectCss(${varname})`;
        },
    ],
}),

I didn't find a better way to properly inject my css on server-side. But with this approach we completely loose the ability to use the treeshakeable option.

Do you think that there is a better way to inject our css on server-side render ?

HeadFox commented 3 years ago

Any help on this ? The only solution I see right now for me is to fork the réponse:(

jpapini commented 3 years ago

Any update of this ?

AntonyF-Andreani commented 2 years ago

Any update of this? I can help if is need it.

maxarias-io commented 2 years ago

Bumping.

schmolie commented 2 years ago

I'm also wondering how to solve this. Any updates?

814k31 commented 2 years ago

I havent done server side rendering

However I've been playing around with using this plugin and @emotion/css for injection instead of the standard injection So I'm going to throw this here because it may spark ideas of using @emotion to do some server side rendering stuff

styles({
    mode: [
        "inject",
        (varName) => `
            const { injectGlobal } = require('@emotion/css');
            injectGlobal(${varName});
        `,
    ],
    autoModules: true,
    modules: true,
}),

You may be able to use docs from emotion to achieve what you're looking for https://emotion.sh/docs/ssr