在组件中包含部分会导致重复的 css
Posted
技术标签:
【中文标题】在组件中包含部分会导致重复的 css【英文标题】:Including partials in components results in duplicate css 【发布时间】:2020-03-13 07:32:28 【问题描述】:我正在尝试使用 sass 的 @extend
,这样我就不会将标记和 html 混合在一起。如this article 中所述。
简而言之,而不是写
<div class="alert alert-primary>This is an alert!</div>
你应该写类似的东西
<div class="banner">This is an alert!</div>
.banner
@extend .alert;
@extend .alert-primary;
这样样式和内容可以很好地分开。
问题:将它与 webpack (sass-loader) 和组件(例如 Vue.js 或 Angular)一起使用时,我运行进入一个问题,现在包含一个引导程序部分将导致整个引导程序文件完全编译到 css 中。
这会为使用部分 bootstrap/scss/_buttons.scss
的每个组件以及在该部分中定义的所有类生成一个类 .btn[data-v-3614b62c]
和另一个 .btn[data-v-45ac961c]
等。
即使我不使用它。
从长远来看,这对应用程序是不利的,因为它的大小会迅速增加,而且我认为浏览器会因为要解析的 css 类太多而变慢。
问题:如何确保 sass 不会复制整个导入的部分? 我可以启用某种只包含我使用的类的摇树吗? 我是否必须更改我的文件结构,以便 sass 了解我只需要部分内部的某些类而不是所有类?
代码示例
这是一个使用 bootstrap 的 vue 组件
<template>
<form class="form">
<input type="text" class="input">
<button class="button-submit">Send</button>
<button class="button-cancel">Cancel</button>
</form>
</template>
<style lang="scss" scoped>
@import "node_modules/bootstrap/scss/functions";
@import "node_modules/bootstrap/scss/variables";
@import "node_modules/bootstrap/scss/mixins";
@import "node_modules/bootstrap/scss/root";
@import "node_modules/bootstrap/scss/buttons";
.form
.button-submit
@extend .btn;
@extend .btn-primary;
.button-cancel
@extend .btn;
@extend .btn-danger;
</style>
这将导致整个部分 _buttons.scss
被编译成 css,而不仅仅是 .form .button-submit
和 .form .button-cancel
。
现场示例
https://codesandbox.io/embed/musing-feynman-8w2kx.
查看我遇到的问题:
-
右键单击右侧的示例,然后单击检查
在“元素”选项卡中,导航到 #document > html > head
在底部有几个
style
元素
其中两个将包含所有按钮 css,其中只有 [data-v-######]
属性不同,最后是我的几行代码。
请注意,生产版本也会发生同样的情况。然后将 css 简单地捆绑在一个文件中,但仍然存在重复项。
【问题讨论】:
【参考方案1】:如果您将@import
相同的 CSS 规则添加到不同的组件中,那么您将在所有模块中复制相同的规则。这就是它的工作原理。
您应该只是@import
ing 定义抽象声明(如变量、mixin、函数等)的模块,而不是实际样式。
您可以在全局范围内对样式进行去重的唯一方法是,如果您使用类似 mini-css-extract-plugin 的东西将所有 CSS 提取并组合到一个文件中,然后通过类似 cssnano 的东西运行它,这将丢弃重复的规则 (尽管使用作用域 CSS,这可能行不通)。
模块通常是独立于其他模块构建的,没有简单的方法可以知道规则是否已由前一个模块声明。在开发中,您可能正在使用style-loader,它基于每个模块运行,并根据需要将样式注入网页;如果某个特定样式已经被另一个组件注入,它无法确定应该注入哪些样式。
它变得一团糟;首先不要重复样式,以保持简单。
如果你真的想使用@extend
,那么创建一个单独的.scss
文件,这是@import
s 引导样式的唯一模块,并在其中定义所有扩展。
【讨论】:
感谢您的回答!关于导入仅包含抽象声明的模块:问题是我找不到任何实际公开功能齐全的占位符或 mixin 的 sass 框架。如果您查看引导程序中.btn
的实现,那里有太多代码而不是简单的@extend %btn
,所以我可以使用%btn
。其他 sass 框架,如 Bulma 和 Fomantic UI 似乎也这样做。以上是关于在组件中包含部分会导致重复的 css的主要内容,如果未能解决你的问题,请参考以下文章