将 sass 文件捆绑到单个 sass 文件中

Posted

技术标签:

【中文标题】将 sass 文件捆绑到单个 sass 文件中【英文标题】:Bundle sass files into single sass file 【发布时间】:2018-08-29 03:49:47 【问题描述】:

TL;DR:我的问题是如何将我的一些 sass 文件捆绑到单个 sass 文件中?

我一直在开发一个 Angular 组件库,并用 ng-packagr 打包它。我们就叫它@my-lib/ngx-components吧。

我的 lib 的使用者将导入我的组件,例如 @my-lib/ngx-components/navbar

我决定为组件添加主题支持。

例如,我有一个带有默认颜色(背景、文本、悬停等)的导航栏组件。我希望我的库的使用者能够用他们自己的主题覆盖这些颜色。这就是为什么我写了一个mixin 接受$theme 输入并覆盖一些css规则如下(这是我所拥有的基本版本)

_navbar-theme.sass

@mixin navbar-theme($theme) 
    $primary-color: map-get($theme, primary-color)
    $secondary-color: map-get($theme, secondary-color)
    $color: map-get($theme, color)

    .navbar
         background-color: $primary-color
         color: $color
         &:hover
               background-color: $secondary-color

每个组件都有自己的*-theme.sass 文件。

我还有一个全局的 _theming.sass 文件,它导入所有这些如下

_theming.sass

@import './components/navbar/navbar-theme'
@import './components/button/button-theme'
@import './components/dropdown/dropdown-theme'

我想从我的库中导出这个_theming.sass 文件,这样人们就可以在他们自己的sass 文件中将此文件作为@import '~@my-lib/ngx-components/theming' 导入并开始使用所有可用的mixins。 如果他们想要自定义 navbarbutton 等,他们应该能够通过单一导入使用这些 mixins。

我试图让它看起来像角度材料主题设置。

起初,我尝试了node-sass,它已经在我的依赖项中。但是,它尝试将 sass 构建到 css 中,因此它在输出文件中省略了 mixins。

然后,我看看 angular-material 做了什么。他们使用scss-bundle

我想“这正是我想要的”。但是,它需要 scss 文件,而不是 sass 文件。它无法读取sass 文件。

然后,我想“好吧,我可以放弃 sass 并开始使用 scss。如何将所有这些文件转换为 scss 而无需手动处理”。然后,我找到了sass-convert。 In this question 据说我可以在命令行中使用它。但是,当我使用 npm 全局安装 sass-convert 时,它没有给我一个命令行可执行文件。我想我需要Gulp 才能使用它。

我从一开始就避免使用Gulp,因为它意味着另一种学习工具,它增加了代码库的复杂性。

此时,我感觉就像"Hal fixing light bulb"

TL;DR:我的问题是如何将我的一些 sass 文件捆绑到单个 sass 文件中?

另外,如果你能想出一个需要 webpack 的解决方案,那也很好。

【问题讨论】:

【参考方案1】:

还有一个被广泛使用的包,叫做scss-bundle。

使用起来非常简单,只需创建一个包含所有相关配置的配置文件,然后运行 ​​scss-bundle。

例如,这将使用在 entry.scss 中导入的所有 scss 文件并将其移动到 out.scss。所有导入都会被解析,除了这个例子中的角度主题,比如@import '~@angular/material/theming';

scss-bundle.config.json:


  "bundlerOptions": 
    "entryFile": "my-project/src/entry.scss",
    "outFile": "dist/out.scss",
    "rootDir": "my-project/src",
    "project": "../../",
    "ignoreImports": [
      "~@angular/.*"
    ],
    "logLevel": "debug"
  

【讨论】:

感谢您对此问题的关注。我很久以前就解决了。我最初的问题是我使用sass 而不是scss。这就是为什么我一开始不能使用那个包的原因。 啊,很高兴知道!认为这可能对其他阅读此问题的人有所帮助:) 添加注释角材质(角组件)使用它。【参考方案2】:

我的 scss / sass 文件解决方案 我用过小模块bundle-scss

它通过文件名掩码捆绑文件。所以你需要传递正确的掩码,比如./src/**/*.theme.scss 指定目标文件,也许你的自定义排序顺序

您不必创建一个包含所有导入的入口点文件。 bundle-scss 将通过掩码获取所有文件分析所有导入并包含此文件

【讨论】:

问题是我的文件是sass 文件。如果我可以将它们转换为scss 文件,那么我可以处理其余的事情。手动转换它们将是太多的工作。有什么工具可以处理这个过程吗? 实际上,我可以将该模块扩展为使用sassalso Bundle-scss 也支持 sass 如何在 vanilla js 中而不是 s 中运行它 最好在构建过程中运行。在节点中,您可以像const bundleScss = require("bundle-scss"); bundleScss(mask, dest, sort?) 那样做某事,因为结果包将结果文件保存在磁盘上。你可以用 node-sass 处理【参考方案3】:

让我们通过您的意见或问题:

我想从我的库中导出这个 _theming.sass 文件,这样人们就可以 将此文件导入到他们自己的 sass 文件中作为 @import '~@my-lib/ngx-components/theming' 并开始使用所有的 mixins 可用的。如果他们想要自定义导航栏、按钮等,他们应该 能够通过单一导入使用这些 mixin。

您需要知道,您的目标受众是什么。大多数人使用 Angular cli 来创建他们的应用程序,比如模板从头开始。

所以你需要提供css bundle(人们只想导入你的css)和sass bundle(他们想使用你的对象或你的mixin)。

我想从我的库中导出这个 _theming.sass 文件,这样人们就可以 将此文件导入到他们自己的 sass 文件中作为 @import '~@my-lib/ngx-components/theming' 并开始使用所有的 mixins 可用的。如果他们想要自定义导航栏、按钮等,他们应该 能够通过单一导入使用这些 mixin。

我试图让它看起来像角度材料主题设置。

首先,您需要知道@angular/material 不会导出sass(他们使用scss),而是导出由scss-bundle 编译的css(正如您提到的那样),请参阅他们的code 和文档@987654322 @。

我想“这正是我想要的”。但是,它需要scss 文件,而不是 sass 文件。它无法读取 sass 文件。

我想引用这个answer:

Sass 是一个具有语法改进的 CSS 预处理器。样式表在 高级语法经过程序处理,转化为 常规的 CSS 样式表。但是,它们没有扩展 CSS 标准 自己。

最好你需要将你的代码从 sass 转移到 scss(你自己),这样做并不多(我想,我总是写 scss 而不是 sass 文件)。


解决方案:

1。提供css和sass(s​​css更好)

交付组件库时,您必须提供cssscss。因为 Angular cli 默认不提供scss loader。

不要使用sass 文件,使用scss 文件,请参阅我的参考答案。

scss-bundle + webpack

既然你必须提供css,你可以webpack shell plugin来捆绑scss。 scss有提供cli,如果你想用cli的话。

2。构建你的 scss

好的,让我们从 bootstrap@4 模块中获取示例。 Bootstrap 使用这样的结构(Documents):

scss
|-- _variables.scss
|-- _mixins.scss
|-- _functions.scss
|-- ...
|-- index.scss

index.scss里面会有这样的:

@import 'variables'
@import 'mixins'
@import 'functions'
...

所以,这个scss 你必须在css 旁边提供。就像bootstrap 一样,那么mixin 将可供消费者使用。当消费者在scss 文件夹中找到scss 文件时,这也是一种很好的方法(很容易指出哪个是scss 放入的)。


更新

对于捆绑到单个文件,您必须创建任务运行器来执行此操作。在您想使用 webpack 的情况下,您可以创建一个插件来执行此操作。

这里是插件示例:

scss-bundle-plugin.js

打电话给你配置 webpack:

plugins: [
   new webpack.NoEmitOnErrorsPlugin(),
   new SCSSBundlePlugin(
        file: path.join(__dirname, 'src/index.scss')
   )
],

要尝试游乐场,请查看hello-world-loader 然后:

# install dependency
npm install
# try play ground
npm run webpack

它将在./dist创建文件_theme.scss

对于这个简单的案例,我的建议不要使用 webpack,而是使用任务运行程序(gulp 或 grunt)。 Webpack 太先进了,写任务太难了。

【讨论】:

我已经在我的库中提供了 css。我只想将一些 mixin 捆绑在一起并发送单个 theming.scss 文件。正如您所建议的,我想将我的 sass 文件更改为 scss。但是,其中有很多。我找不到一个简单的方法来做到这一点。如果你能帮助我,我会给你赏金。 谢谢,我去看看。它是否也适用于 sass 文件,还是我仍需要转换它们? @BunyaminCoskuner,我的目标是 scss 文件,只需克隆和 npm run webpack。如果您想尝试使用sass,请将webpack.config.jsscss-bundle-plugin.js 中的.scss 扩展名更改为.sass 扩展名。这只是给你一个想法 好的,会试一试,几个小时内告诉你结果。感谢您的帮助。 我刚刚检查了它,它有效!谢谢您的帮助!现在,我有一个可以处理的例子。享受你的赏金:)

以上是关于将 sass 文件捆绑到单个 sass 文件中的主要内容,如果未能解决你的问题,请参考以下文章

SASS 将样式应用于整个网站,尽管仅导入到单个页面中

将所有 sass 文件合并到一个文件中

如何在与 webpack 捆绑时将 SASS 变量转换为原生 CSS 变量?

有没有一种优雅的方法来参数化 npm 中每页的 Sass 捆绑?

如何安装并编译sass为css文件

SASS 没有在 symfony 中编译