Skip to content

feat(webpack): support rspack/rsbuild#4173

Merged
antfu merged 2 commits intomainfrom
feat/rspack
Sep 28, 2024
Merged

feat(webpack): support rspack/rsbuild#4173
antfu merged 2 commits intomainfrom
feat/rspack

Conversation

@sibbng
Copy link
Member

@sibbng sibbng commented Sep 27, 2024

Fixes #4142

Usage:

import { defineConfig } from '@rsbuild/core';
import { pluginVue } from '@rsbuild/plugin-vue';
import { UnoCSSRspackPlugin } from "@unocss/webpack/rspack";

export default defineConfig({
  plugins: [pluginVue()],
  tools: {
    rspack(config, ctx) {
      ctx.prependPlugins(UnoCSSRspackPlugin());
      config.optimization ??= {};
      config.optimization.realContentHash = true;
    }
  }
});

@sibbng sibbng requested a review from antfu as a code owner September 27, 2024 22:17
@netlify
Copy link

netlify bot commented Sep 27, 2024

Deploy Preview for unocss ready!

Name Link
🔨 Latest commit 45aa0cb
🔍 Latest deploy log https://app.netlify.com/sites/unocss/deploys/66f7534e9922b20008964178
😎 Deploy Preview https://deploy-preview-4173--unocss.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Sep 27, 2024

Open in Stackblitz

commit: 45aa0cb

return unplugin(configOrPath, defaults).webpack()
}

export function UnoCSSRspackPlugin<Theme extends object>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Named export will make the CJS interop hard - Maybe we should expose a new sub module with default export instead.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have a named export defineConfig in this file. What we should do with it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@antfu

Entry module "src/index.ts" is using named and default exports together. Consumers of your bundle will have to use chunk.default to access the default export, which may not be what you want. Use output.exports: "named" to disable this warning.

I removed defineConfig. We already export WebpackPluginOptions interface, it seemed unnecessary to me. After removing it the warning above disappeared. I guess this makes it a breaking change?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be a minor breaking change, I can bump a new minor version to be safe.

@wtto00
Copy link

wtto00 commented Oct 18, 2024

@sibbng Hello, how to use it?

Use it like in webpack: Add import 'uno.css' in src/index.ts

import { createApp } from 'vue'
import App from './App.vue''

import 'uno.css'

import './index.css'

createApp(App).mount('#root')

But I encountered a problem: The unocss I wrote in style.css cannot be processed.

/* src/style.css */
.body {
  --uno: m-0;
  @apply: bg-red;
}

The generated result is:

.body {
  --uno: m-0;
}

But should be:

.body {
  margin: 0;
  --un-bg-opacity: 1;
  background-color: rgb(248 113 113 / var(--un-bg-opacity));
}

I have added the css file in the filesystem and configured the transformerDirectives plugin.

import { defineConfig, presetUno, transformerDirectives, transformerVariantGroup } from 'unocss'

export default defineConfig<Theme>({
  content: {
    filesystem: ['src/**/*.{html,js,ts,jsx,tsx,vue,svelte,astro,css}'],
  },
  presets: [
    presetUno(),
  ],
  transformers: [transformerVariantGroup(), transformerDirectives()],
})

There is the same issue in the postcss plugin.

But this works fine in Vite.

@wtto00
Copy link

wtto00 commented Oct 18, 2024

I create a example project: https://codesandbox.io/p/github/rspack-contrib/rsbuild-codesandbox-example/csb-89wjsv/draft/clever-roman

// uno.config.mjs
import { defineConfig, presetUno } from 'unocss';

export default defineConfig({
  content: {
    filesystem: ['./src/**/*.{html,js,ts,jsx,tsx,css}'],
  },
  presets: [presetUno()],
  preflights: [
    {
      getCSS: ({ theme }) => `
        body {
          color: blue;
          --uno: bg-red;
        }
      `
    }
  ]
});
/* src/index.css */
@unocss preflights;
@unocss default;

@unocss;

body {
    --uno: font-italic;
    color: green;
}

The results are:

  • The output result of font-size: 36px; in preflights is correct, which is font-size: 36px;.
  • The output result of --uno: bg-red; in preflights is not correct, which is --uno: bg-red; with no processing.
  • The output result of color: green; in index.css is correct, which is color: green;.
  • The output result of --uno: font-italic in index.css is not correct, which is --uno: font-italic with no processing.

@wtto00
Copy link

wtto00 commented Oct 18, 2024

I found a new issue, @unocss/transformer-variant-group is not working.

<span className="hover:(c-red text-16) hover-font-bold hover:bg-pink">default style</span>
  • hover-font-bold hover:bg-pink works well.
  • hover:(c-red text-16) is not working.

@sibbng
Copy link
Member Author

sibbng commented Oct 18, 2024

Use it like in webpack: Add import 'uno.css' in src/index.ts?

Yes.

But I encountered a problem: The unocss I wrote in style.css cannot be processed.

Yeah, It seems that a problem in our Webpack plugin. For some reasons CSS files are excluded. You can fix that like that:

import { defineConfig, presetUno, transformerDirectives, transformerVariantGroup } from 'unocss'
import { Theme } from 'unocss/preset-mini'

export default defineConfig<Theme>({
    content: {
        pipeline: {
            exclude: [],
        }
    },
    presets: [
        presetUno(),
    ],
    transformers: [transformerVariantGroup(), transformerDirectives({ enforce: "pre" })],
})

But I encountered a problem: The unocss I wrote in style.css cannot be processed.

Also you need to set transformerDirectives({ enforce: "pre" }). And you should use @apply not @apply: (no colon)

@unocss; at only supported in PostCSS plugin, in Webpack/Rspack plugin you don't need to do that. import "uno.css" will do it for you.

I found a new issue, @unocss/transformer-variant-group is not working.

I cannot fork Codesandbox project. I tried locally on my project It works for me. Maybe you should update rsbuild to latest. Your template using beta version.

@wtto00
Copy link

wtto00 commented Oct 18, 2024

Thank you for your reply. I will start trying right away.


The issue with @unocss/transformer-variant-group has been resolved.

However, the @apply syntax in src/index.css is still not working.

/* src/index.css */
:root {
  @apply c-grey-700 bg-primary-50;
}

No output was generated.

I tried using --at-apply: c-grey-700 bg-primary-50; but the generated CSS has no processing.

I am migrating my project from vite to rsbuild.

I will create a GitHub example repository later to replicate this issue.


@sibbng Hello, Sorry to trouble you, I have created a repository for reproduction, could you take a look? https://github.com/wtto00/rsbuild-unocss-apply-issue

The @apply syntax in src/index.css is not working.

This issue is not necessary for the migration work. I replaced the @apply syntax with several CSS variables used in preflights injection.

@sibbng
Copy link
Member Author

sibbng commented Oct 18, 2024

My bad, also need to include CSS in include section:

    content: {
        pipeline: {
            include: [/\.(css|vue|svelte|[jt]sx|mdx?|astro|elm|php|phtml|html)($|\?)/],
            exclude: [],
        }
    },

@wtto00
Copy link

wtto00 commented Oct 18, 2024

Perfact, it works! Thanks a lot.

By the way, hope to add the usage and precautions to the document.

@Asukaaaaaa
Copy link

Asukaaaaaa commented Jan 20, 2025

@apply still not work after following the configs above

export default defineConfig({
  plugins: [pluginReact()],
  tools: {
    rspack(config, ctx) {
      ctx.prependPlugins(
        UnoCSSRspackPlugin({
          content: {
            pipeline: {
              include: [/\.(css|[jt]sx|html)($|\?)/],
              exclude: [],
            },
          },
          presets: [presetMini()],
          transformers: [transformerVariantGroup(), transformerDirectives()],
        })
      );
      config.optimization ??= {};
      config.optimization.realContentHash = true;
    },
  },
});

image
you can reproduce it here: https://codesandbox.io/p/devbox/kx3sxl

@wtto00
Copy link

wtto00 commented Jan 20, 2025

@Asukaaaaaa

Also you need to set transformerDirectives({ enforce: "pre" })

@Asukaaaaaa
Copy link

that works fine in react, but looks not good in vue2😭
image

@Asukaaaaaa
Copy link

that works fine in react, but looks not good in vue2😭 image

Previously, in order to solve this problem in vue2, I had to use both the rspack plugin and the postcss plugin at the same time. But when there were many styles, doing so would cause some disturbing problems.

@snecker
Copy link

snecker commented Feb 19, 2025

@apply doenst work in vue3

rsbuild.config.ts

import {defineConfig} from '@rsbuild/core';
import {pluginVue} from '@rsbuild/plugin-vue';
import {UnoCSSRspackPlugin} from "@unocss/webpack/rspack";
import {presetAttributify, presetUno, transformerDirectives, transformerVariantGroup} from "unocss";


export default defineConfig({
    plugins: [pluginVue()],
    tools: {
        rspack(config, ctx) {
            ctx.prependPlugins(UnoCSSRspackPlugin({
                    content: {
                        pipeline: {
                            include: [/\.(css|vue|svelte|[jt]sx|mdx?|astro|elm|php|phtml|html)($|\?)/],
                            exclude: [],
                        }
                    },
                    presets: [presetUno(), presetAttributify()],
                    transformers: [
                        transformerVariantGroup(),
                        transformerDirectives({enforce: "pre"}),
                    ]
                })
            );
            config.optimization ??= {};
            config.optimization.realContentHash = true;
        }
    }
});

index.ts

import { createApp } from 'vue';
import App from './App.vue';
import "uno.css"
import './index.css';

createApp(App).mount('#root');

App.vue

<template>
  <div class="content text-green-500">
    Rsbuild with Vue3
  </div>
</template>

<style scoped>
.content {
  border:1px solid gray;   /* worked */
  @apply text-red-400;  /* doesnt worked */
  --at-apply: text-yellow-400; /* doesnt worked */
}
</style>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Is there a plan to support rsbuild?

5 participants