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

时间:2018-03-20 10:57:25

标签: css angular webpack sass gulp

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'

我想从我的lib中导出这个_theming.sass文件,以便人们可以将这个文件作为sass导入到他们自己的@import '~@my-lib/ngx-components/theming'文件中,然后开始使用所有mixin可用。 如果他们想要自定义navbarbutton等,他们应该可以使用单个导入的mixin

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

首先,我尝试了node-sass已经存在于我的依赖项中。但是,它试图将sass构建为css,因此它省略了输出文件中的mixins。

然后,我看了一下角质材料做了什么。他们使用scss-bundle

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

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

我从一开始就习惯使用Gulp,因为它意味着要学习的另一个工具,它会增加代码库的复杂性。

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

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

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

3 个答案:

答案 0 :(得分:2)

通过您的意见或问题:

  

我想从我的lib导出这个_theming.sass文件,所以人们可以   将此文件作为@import导入自己的sass文件中   '〜@我-LIB / NGX组件/主题化'并开始使用所有mixins   可用。如果他们想要自定义导航栏,按钮等,他们应该   能够使用单一导入的mixins。

您需要知道,您的目标受众是什么。大多数人使用角度cli来创建他们的应用程序,如模板划痕。

因此,您需要提供css个捆绑(人们只想导入您的CSS)和sass捆绑(想要使用您的对象或您的混合)。

  

我想从我的lib导出这个_theming.sass文件,所以人们可以   将此文件作为@import导入自己的sass文件中   '〜@我-LIB / NGX组件/主题化'并开始使用所有mixins   可用。如果他们想要自定义导航栏,按钮等,他们应该   能够使用单一导入的mixins。

     

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

首先,您需要知道@angular/material没有导出sass(他们使用scss),但他们导出scss-bundle编译的css(正如您所说),请参阅他们的code和文档theme

  

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

我想引用此answer

  

Sass是一款具有语法改进功能的CSS预处理器。样式表   高级语法由程序处理,并转换为   常规的CSS样式表。但是,它们没有扩展CSS标准   本身。

你最好将代码从sass转移到scss(由你自己),它不会那么做(我想,我总是写scss而不是sass文件)。

解决方案:

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

当您交付组件库时,您必须提供cssscss。默认情况下,beacuse angular cli不提供scss加载程序。

请勿使用sass文件,请使用scss文件查看我的推荐答案。

scss-bundle + webpack

由于你必须提供css,你可以webpack shell plugin捆绑scss。如果你想使用cli,scss会提供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

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

我的建议是不使用webpack,而是使用任务运行器(gulp或grunt)来处理这个简单的情况。 Webpack太先进了,很难写任务。

答案 1 :(得分: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"
  }
}

答案 2 :(得分:0)

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

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

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