reactjs – 自定义字体未加载webpack / sass

我们有一个大型项目,我们正在尝试实现ITCSS模式(工作正常)并添加由我们的graphists创建的自定义图标字体.

这是文件夹结构(不详尽):

.
├── build
│   └── webpack.config.js
└── src
    ├── components                           # Using React
    │   ├── test.jsx
    │   └── test.scss
    └── styles
        ├── _objects                         # Components style reusable
        │   ├── _all.scss
        │   └── table.scss
        ├── _settings                        # Global variables
        │   ├── _all.scss
        │   ├── _custom-icons.scss           # Define icon font (see below)
        │   ├── _custom-icons-variables.scss # Define icon codes
        │   ├── _colors.scss                 # Define colors
        │   ├── _predefined-colors.scss      # Define brand colors
        │   └── _theme.scss                  # Define specific theme
        ├── _tools                           # Mixins / helpers
        │   ├── _all.scss
        │   ├── _animation.scss
        │   ├── _breakpoints.scss
        │   └── _transition.scss
        ├── _wins                            # Overrides
        │   ├── _all.scss
        │   ├── _display.scss
        │   ├── _position.scss
        │   └── _text.scss
        ├── assets
        │   └── fonts
        │       ├── custom-icons.eot
        │       ├── custom-icons.svg
        │       ├── custom-icons.ttf
        │       └── custom-icons.woff
        ├── _base.scss                       # HTML Selectors
        ├── _generic.scss                    # Reset (normalize)
        └── main.scss                        # Loads everything

好的,这是一个相当繁重的文件结构,但它完成了我们想要实现的目标!

我们在davezuko的react-redux-starter-kit上开始了我们的应用程序.我们调整了webpack配置文件以满足我们的需求,但没有更改样式部分,因此您可以参考webpack.config.js from GitHub.

现在,这是我们的文件:

_custom-图标,variables.scss

$fontPath: "./assets/fonts" !default;

$aw-happy: "\e9df";
$aw-smile: "\e9e1";
$aw-tongue: "\e9e3";
$aw-sad: "\e9e5";
$aw-wink: "\e9e7";
$aw-grin: "\e9e9";
$aw-cool: "\e9eb";
$aw-angry: "\e9ed";
…

_custom-icons.scss

自定义图标字体依赖于Semantic-UI字体图标样式.

@import "custom-icons-variables";

$fontName: 'custom-icons';

$fallbackSRC: url("#{$fontPath}/#{$fontName}.eot");
$src:
  url("#{$fontPath}/#{$fontName}.eot?#iefix") format('embedded-opentype'),
  url("#{$fontPath}/#{$fontName}.woff") format('woff'),
  url("#{$fontPath}/#{$fontName}.ttf") format('truetype'),
  url("#{$fontPath}/#{$fontName}.svg?##{$fontName}") format('svg')
;

@font-face {
  font-family: $fontName;
  src:  $fallbackSRC;
  src:  $src;
  font-weight: normal;
  font-style: normal;
}

i.icon.aw {
  font-family: $fontName !important;
}

.aw-happy {
  &:before {
    content: $aw-happy;
  }
}
.aw-smile {
  &:before {
    content: $aw-smile;
  }
}
.aw-tongue {
  &:before {
    content: $aw-tongue;
  }
}
.aw-sad {
  &:before {
    content: $aw-sad;
  }
}
.aw-wink {
  &:before {
    content: $aw-wink;
  }
}
.aw-grin {
  &:before {
    content: $aw-grin;
  }
}
.aw-cool {
  &:before {
    content: $aw-cool;
  }
}
.aw-angry {
  &:before {
    content: $aw-angry;
  }
}
…

main.scss

这里的所有内容都是全局的,因此我们避免webpack添加哈希并允许我们在组件中使用直接类名(请参阅下面的示例).

:global {
  @import "_settings/all";
  @import "_settings/custom-icons";
  @import "_tools/all";
  @import "generic";
  @import "base";
  @import "_objects/all";
  @import "_wins/all";
}

test.jsx

在这里,您可以看到我们使用全局和范围样式.

import React, { Component } from 'react'

import s from './test.scss'

export default class Test extends Component {
  render () {
    return (
      <div className={s['test']}>
        <i className='icon aw aw-happy'></i>
        <h1>Test</h1>
      </div>
    )
  }
}

test.scss

是的,对于使用我们品牌颜色的每个组件,我们需要重新导入Sass文件…我不知道这是不是坏事,但它有效:)

@import "src/styles/_settings/all";

.test {
  background: $brown;
  color: $white_smoke;
}

现在设置了背景,这是问题所在:

aw-happy图标呈现为正方形(就像没有加载你的字体时……)我无法让它工作,我在浏览了大量资源后尝试了所有的东西:/

我们使用Semantic-UI构建,然后与webpack捆绑在一起,所以我尝试将@ font-face规则添加到semantic.min.css,并将字体文件移动到语义文件夹:

semantic.min.css

@font-face {
   font-family: 'custom-icons';
   src:  url(themes/default/assets/fonts/custom-icons.eot);
   src:  url(themes/default/assets/fonts/custom-icons.eot?#iefix) format('embedded-opentype'),
   url(themes/default/assets/fonts/custom-icons.woff) format('woff'),
   url(themes/default/assets/fonts/custom-icons.ttf) format('truetype'),
   url(themes/default/assets/fonts/custom-icons.svg?#custom-icons) format('svg');
   font-weight: normal;
   font-style: normal;
 }
 // Semantic stuff…

并且…它的工作原理!

我想知道我是否能更好地构建和提供这种自定义字体,就像我们使用语义一样,但是将所有过程从全局样式中移除是令人讨厌的.

关于如何通过保留所有Sass / Webpack的东西来解决这个问题的任何想法?

最佳答案 这是我通过浏览react-redux-starter-kit项目的封闭错误找到的解决方案:

我将@ font-face定义移到了main.scss,上面是:global:

main.scss

$font-path: 'styles/assets/fonts';
$font-name: 'custom-icons';

$fallback-src: url("#{$font-path}/#{$font-name}.eot");
$src:
  url("#{$font-path}/#{$font-name}.eot?#iefix") format('embedded-opentype'),
  url("#{$font-path}/#{$font-name}.woff") format('woff'),
  url("#{$font-path}/#{$font-name}.ttf") format('truetype'),
  url("#{$font-path}/#{$font-name}.svg?##{$font-name}") format('svg')
;

@font-face {
  font-family: $font-name;
  src:  $fallback-src;
  src:  $src;
  font-weight: normal;
  font-style: normal;
}

当我将$font-path定义为../styles/assets/fonts而不是./assets/fonts时,它也有效.

这是一个已知的错误,是referenced at GitHub,但davezuko此时没有深入研究它.

点赞