在Web Components中使用自定义字体

自定义字体是个好东西啊,FontAwesome/Remixicon等优秀的图标都是用自定义字体来实现的,非常省事好用。如此让人上瘾的东西,可惜碰到了web components之后麻烦就来了。

首先,web components是自隔离的,父页面中的样式是不能作用于组件的,所以按照常规方法是把样式嵌入到组件中。非常遗憾的是,css加载是没问题的,但是它并没有于我们预期想象的一样把图标显示出来。

这个看起来就像是字体缺失,打开网路请求检查一下,的确就是没有字体请求!但是,令人意外的是,如果在父页面中引入自定义字体,在组件内部使用自定义字体,居然是行得通的!

所以这个丑陋的方案就出来了,把他们拆成两个部分:

  1. 字体定义部分放在父页面中,通过父页面来请求自定义字体;
  2. 样式部分放在web components中,因为样式是隔离的。

当然,我们可以通过js来在父页面中注入自定义字体:

const FONT_FACES = `@font-face

在React中分离Shadow DOM样式及使用Sass

Shadow DOM已经比较成熟了,基本上所有的现代浏览器都已经支持了,可以参考Can I Use。在React中使用shadow DOM也不是什么新鲜事,也有一些关于shadow DOM的第三方库,但是在CSS方面,几乎都是使用了styled components的方式。我个人不太喜欢这种css和js混在一起方式,而且这种方式下也没法使用scss了。

开始看了下style-laoder的文档,里面有个选项insert,可以传入一个function,这样你可以在里面进行你想要的操作,比如找到shadow DOM的shadow root,然后把你的style插入进去:

rules: [
  // Other webpack modules
  ...
  {
    test: /\.css$/,
    use: [
      {
        loader: require.resolve('style-loader'),
        options: {
          insertInto: function