【问题标题】:node-sass custom importer for file from the web not working来自网络的文件的 node-sass 自定义导入器不起作用
【发布时间】:2021-03-08 17:49:00
【问题描述】:

我正在尝试将样式表从 Google 字体导入到样式表中,以避免稍后出现 eytra 请求。

我的main.scss 文件以

开头
@import "https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;1,400;1,700;1,900&family=Source+Code+Pro:wght@400;700&display=swap";

我希望得到的 main.css

开头
@font-face {
  font-family: 'Lato';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/lato/v17/S6u8w4BMUTPHjxswWw.ttf) format('truetype');
}
/* etc */

为此,我有以下脚本:

var scss = require("node-sass");
var https = require('https');

function compile(filePath, dirs, callback){
  scss.render({
    file: filePath,
    includePaths: dirs,
    outputStyle: 'expanded',
    sourceMap: false,
    importer: [
      function(url, prev, done) {
        if (url.startsWith('https')) {
          https.get(url, (res) => {
            let contents = '';
            res.on('data', (d) => contents += d);
            res.on('end', () => {
              console.log('scss')
              done({contents})
            });         
          });
        }
        return null;
      }
    ]
  }, function (e, css) {
    if (error) {
      return callback(error)
    }
    callback(null, css.css)
  });
}

compile('main.scss', null, (e, d)=>{console.log(d.toString())})

node-sass spec 表示内容应该以如下形式返回

具有键 contents 的对象,其值是样式表的内容(在 SCSS 语法中)。这会导致 Sass 加载该样式表的内容。

我可以看到导入器函数被调用,解析了请求并且在contents 变量中有想要的样式表文本。输出被写入控制台,但仍然有原来的@import 行。

这哪里出错了?

编辑:如果使用 node-sass,节点会崩溃并显示消息 Speicherzugriffsfehler。将使用的库改成sass后,没有出现crash,但是仍然存在not-resolved import的错误。

同样,尝试使用虚拟静态规则 .bla {--blubb: green;} 作为返回的内容不起作用。

【问题讨论】:

  • 我也有同样的问题,我想see my question。我解决这个问题的唯一方法是在 sass 文件中使用 google font v1 API import url。
  • 如果我理解您的问题,您并没有尝试将@import 换成已解决的@font-face,而只是在url 语法上有问题。这不是这里的问题。
  • 与编译后的 css 留下 sass @import 语法的相似之处很奇怪。一旦切换到 v1 api url。它编译正确。

标签: node.js sass node-sass


【解决方案1】:

在仔细检查了 dart-sass 库后,我找到了一个解决方案。似乎以 http(s):// 协议开头的 URL 永远不会传递给导入器函数。

所以你得花点心思,这不是一个通用的解决方案。

main.scss文件中,缩短协议的URL:

@import "fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;1,400;1,700;1,900&family=Source+Code+Pro:wght@400;700&display=swap";

然后,在导入器函数的开头捕获fonts

    importer: function(url, prev, done) {
      if (url.startsWith('fonts')) {
        https.get('https://' + url, (res) => {
          let contents = '';
          res.on('data', (d) => contents += d);
          res.on('end', () => done({contents}));
        });
      }
    },

注意一个重要的区别:if 子句之后没有return null;。这导致导入器结果被传递,尽管它正确加载了文件内容。

整个解决方案只适用于(dart-)sass,不适用于node-sass,由于某种原因以无限循环结束。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-06
    • 1970-01-01
    • 2014-03-19
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    • 1970-01-01
    • 2023-02-09
    相关资源
    最近更新 更多