Skip to content

Can css be styleInjected in library mode? #1579

Open
@gwsbhqt

Description

@gwsbhqt

Is your feature request related to a problem? Please describe.
I'm using vite to build a library, and sometimes the library requires a dozen lines of simple styles. After building, a style.css file will be generated. But I think it is not necessary to generate two files, it may be enough to generate only one file. Is there any way to add style.css to the target js file?

The styleInject helper function is used in rollup and babel plug-ins. In iife/umd mode, the style is automatically injected when library loaded.

image

Activity

changed the title [-]can css styles be appended into the single target js file in library mode?[/-] [+]Can css styles be appended into the single target js file in library mode?[/+] on Jan 18, 2021
changed the title [-]Can css styles be appended into the single target js file in library mode?[/-] [+]Can css be styleInjected in library mode?[/+] on Jan 19, 2021
yyx990803

yyx990803 commented on Jan 20, 2021

@yyx990803
Member

The problem is injecting the style assumes a DOM environment which will make the library SSR-incompatible.

If you only have minimal css, the easiest way is to simply use inline styles.

gwsbhqt

gwsbhqt commented on Jan 20, 2021

@gwsbhqt
Author

Generally, existing style libraries are used in a dom environment.
Now I am using ts/vite/preact/module less to build a library. If I use the inline style, then there is no way to use modular less.
Maybe you are right. It may be a better choice to directly use inline styles, but still hope to provide more library mode options.
Thanks for your reply.

eikooc

eikooc commented on Jan 26, 2021

@eikooc

I know you already answered that assuming a DOM environment will make the library SSR-incompatible, but maybe it would be possible to provide an option for enabling inlining of the styles?

I have made a reproduction project showing a component being created in the ui-components project then after being built and installed in the separate project not including any styles. vite-library-style-repro

@yyx990803 how would you suggest making a library of components that can be included without importing a global styles.css, possibly including styles that are unneeded or clashing with other styles?

shanlh

shanlh commented on Feb 3, 2021

@shanlh

In pass, I use rollup build vue2 library, I found that the style will auto inject to "<head></head>"

richardtallent

richardtallent commented on Feb 8, 2021

@richardtallent

I've been running into this for the past week and pulling my hair out, as this is not a documented behavior. I was about to file an issue (repro: https://github.com/richardtallent/vite-bug-cssnotimported) and just came across this one.

Requiring non-SSR users to manually import a CSS file to get a component's default style to work is suboptimal DX, and an unfamiliar surprise for anyone accustomed to importing components under Vue 2.

Inline CSS is not a viable alternative, at least for a non-trivial component. Inline CSS also creates additional challenges for a user who wants to override the default style.

Is there a middle ground here to help developers who want to support the SSR use case, without making non-SSR users jump through an extra hoop to style each component they use?

fuxingloh

fuxingloh commented on Feb 8, 2021

@fuxingloh

@richardtallent Sharing my experience here, I moved to inline all CSS and moved all <template> into render function.

I was following this issue for over 2 weeks now, I was stumbled upon how to effectively inject style into the head. Effectively for DX, requiring the user to import style was suboptimal for my use case. By comparison Vue 2 was much easier to install for the users than Vue 3, so this was a no go for me.

My trivial library target SSR/SSG/SPA and is e2e tested on all 3 modes which makes it an extra headache to move to Vue 3 in Vite. There was also some quirks with head injected css for my use case so inlining style was not something I was entirely against. (In fact I wanted to for consistency sake.)

For inline CSS overriding, what I did to allow default style override is to explicitly state how to with ::v-deep and !important in the documentation. reference

.some-component ::v-deep(.v-hl-btn) {
  width: 8px !important;
}

Not all css can be inlined directly (pseduo, media query, '>' and many more), which require me to rewrite my entire component into render function. reference

export default defineComponent({
  render() {
    return h('div', {
      class: 'vue-horizontal',
      style: {
        position: 'relative',
        display: 'flex',
      }
    }, [...])
  }
})

I hope this helps anyone down this road. For reference: fuxingloh/vue-horizontal#87

richardtallent

richardtallent commented on Feb 8, 2021

@richardtallent

Thanks @fuxingloh! This sounds like an interesting workaround, but I don't want to give up on writing idiomatic SFCs (with template and style blocks) and allowing users to override styles with standard CSS. However, I have bookmarked your component since I like how you've done your testing and I hope to learn from it!

ziping-li

ziping-li commented on Feb 27, 2021

@ziping-li

I am using the style-inject now. I wonder if this problem has been solved? Eventually a css file will be generated, and the style code is also included in js.

import { computed, defineComponent, ref } from 'vue';
import { queryMedia } from '@convue-lib/utils';
import styleInject from 'style-inject';
import css from './index.less';

styleInject(css);

export default defineComponent({
  name: 'Container',
  props: {
    fuild: {
      type: Boolean,
      default: false,
    },
  },
  setup(props, { slots }) {
    const media = ref('');
    queryMedia((data: string) => (media.value = data));
    const className = computed(() => ({
      'convue-container': true,
      fuild: props.fuild,
      [media.value]: true,
    }));

    return () => <div class={className.value}>{slots.default?.()}</div>;
  },
});

https://github.com/ziping-li/convue-lib/blob/master/packages/container/src/index.tsx

96 remaining items

added a commit that references this issue on Oct 28, 2024
Mori-Yang

Mori-Yang commented on Dec 8, 2024

@Mori-Yang

Sorry to bother you, I'm a beginner and I'm trying to build my own component library! But I encountered a similar problem, I'm not sure if it fits this issue, if you know how to solve it or it belongs to this issue, please tell me!

My question:
My component library defines a global css variable index.css to specify some colors. I use lib mode for packaging and formats: ['es']. In addition, the entry file has an import import "./index.css"! But in the packaging result, no style is introduced! I think this is because such a product will report an error when running in the browser! Should I use a plug-in to inject css?

emosheeep

emosheeep commented on Dec 8, 2024

@emosheeep
Contributor

You should add css files into the sideEffects configurations in package.json, otherwise it will be tree-shaked when bundling.

Mori-Yang

Mori-Yang commented on Dec 9, 2024

@Mori-Yang

You should add css files into the sideEffects configurations in package.json, otherwise it will be tree-shaked when bundling.

Thank you very much for replying to me!

I searched for related content before trying to add sideEffects: I did not find the sideEffects field in npm doc and vite doc, but I saw some webpack related ones! Can you tell me where I can get the knowledge related to sideEffects?

I set "sideEffects": [ "dist/*", "src/style/*" ],
according to other repositories, but it still didn't work after packaging! Regardless of whether I set sideEffects or not, style.css will exist in the packaging result. I am curious why this is!

My repo is here:https://github.com/Ys-OoO/vue-sketch-ui .You can see the detailed configuration here

Mori-Yang

Mori-Yang commented on Dec 9, 2024

@Mori-Yang

You should add css files into the sideEffects configurations in package.json, otherwise it will be tree-shaked when bundling.

I seem to have solved the problem. I didn't use sideEffects. The global styles I introduced in the entry file and the styles of each component are packaged into a css file. This way, users can import them when they use them!

But I still want to know about sideEffects! How is it handled in Vite?

pfdgithub

pfdgithub commented on Dec 9, 2024

@pfdgithub

You should add css files into the sideEffects configurations in package.json, otherwise it will be tree-shaked when bundling.

I seem to have solved the problem. I didn't use sideEffects. The global styles I introduced in the entry file and the styles of each component are packaged into a css file. This way, users can import them when they use them!

But I still want to know about sideEffects! How is it handled in Vite?

https://github.com/vitejs/vite/blob/main/packages/vite/src/node/packages.ts#L177

sarojregmi200

sarojregmi200 commented on Dec 23, 2024

@sarojregmi200

for those who are exporting multiple files and only want to add intro to only the index or some entry file. You can also provide function to the intro that returns a string.

output: {
    intro: (chunk) => {
        if (chunk.fileName === 'index.js') {
            return `import "./style.css";`
        }
        return ''
    },
}

https://rollupjs.org/configuration-options/#output-intro-output-outro
See this for more information.

Adding a intro is a clean and easy solution more than adding a plugin, if it works for you.

Dyinfalse

Dyinfalse commented on Jun 13, 2025

@Dyinfalse

您应该将 css 文件添加到sideEffectspackage.json 的配置中,否则捆绑时将会被 tree-shaking。

非常感谢您回复我!

在尝试添加副作用之前,我搜索了相关内容:我在 npm 文档和 vite 文档中没有找到副作用字段,但我看到了一些与 webpack 相关的!请问哪里可以找到与副作用相关的知识?

"sideEffects": [ "dist/*", "src/style/*" ], 按照其他仓库的设置,打包后还是不行!不管我设置了没有,打包结果里都会有 style.css 。好奇这是怎么回事!

我的 repo 在这里:https://github.com/Ys-OoO/vue-sketch-ui。你可以在这里查看详细配置

try https://www.npmjs.com/package/rollup-plugin-import-css

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @kevinansfield@FreekVR@yyx990803@marcelobotega@cutterbl

        Issue actions

          Can css be styleInjected in library mode? · Issue #1579 · vitejs/vite