通过npm导入Sass

问题描述 投票:0回答:8

目前在我们的 Sass 文件中,我们有如下内容:

@import "../../node_modules/some-module/sass/app";

这很糟糕,因为我们实际上不确定路径:它可能是

../node_modules
,也可能是
../../../../../node_modules
,因为 npm 如何安装东西。

Sass中有没有一种方法可以让我们向上搜索直到找到node_modules?或者甚至是通过 npm 包含 Sass 的正确方法?

node.js sass npm node-modules
8个回答
79
投票

如果您正在 2017 年寻找方便的答案并且正在使用 Webpack,这是我发现的最简单的答案。

假设你的模块路径是这样的:

node_modules/some-module/sass/app

然后在你的主 scss 文件中你可以使用:

@import "~some-module/sass/app";

波浪号运算符应将任何导入解析为模块。


18
投票

您可以将另一个 includePaths 添加到渲染选项中。

简单示例

基于 Oncle Tom 示例的片段。

var options = {
  file: './sample.scss',
  includePaths: [
    path.join(__dirname, 'bower_components'), // bower
    path.join(__dirname, 'node_modules') // npm
  ]
};

sass.render(options, function(err, result){
  console.log(result.css.toString());
});

应该可以。您可以使用

@import "my-cool-package/super-grid

包含包中的文件

Webpack 和 scss-loader 示例

{
  test: /\.scss$/, 
  loader: 'style!css!autoprefixer?browsers=last 2 version!sass?outputStyle=expanded&sourceMap=true&sourceMapContents=true&includePaths[]=./node_modules' 
},

注意最后一个参数,includePaths 必须是数组。请记住使用正确的格式


18
投票

正如 Oncle Tom 提到的,新版本的 Sass 有这个新的

importer
选项,您在 Sass 文件上执行的每个“导入”都将首先通过此方法。这意味着您可以修改此方法的实际 url。

我使用

require.resolve
来定位实际的模块入口文件。
看看我的 gulp 任务,看看它是否对您有帮助:

'use strict';

var path       = require('path'),
    gulp       = require('gulp'),
    sass       = require('gulp-sass');

var aliases = {};

/**
 * Will look for .scss|sass files inside the node_modules folder
 */
function npmModule(url, file, done) {
  // check if the path was already found and cached
  if(aliases[url]) {
    return done({ file:aliases[url] });
  }

  // look for modules installed through npm
  try {
    var newPath = path.relative('./css', require.resolve(url));
    aliases[url] = newPath; // cache this request
    return done({ file:newPath });
  } catch(e) {
    // if your module could not be found, just return the original url
    aliases[url] = url;
    return done({ file:url });
  }
}

gulp.task("style", function() {
  return gulp.src('./css/app.scss')
    .pipe(sass({ importer:npmModule }))
    .pipe(gulp.dest('./css'));
});

现在假设您使用节点安装了

inuit-normalize
。您可以简单地在您的 Sass 文件中“要求”它:

@import "inuit-normalize";

我希望对您和其他人有所帮助。因为添加相对路径总是很痛苦:)


8
投票

您可以使用 Sass

importer
函数来执行此操作。比照。 https://github.com/sass/node-sass#importer--v200

以下示例说明 [电子邮件受保护][电子邮件受保护]:

安装 Bower 依赖项:

$ bower install sass-mq
$ npm install sass/node-sass#3.0.0-pre

Sass 文件:

@import 'sass-mq/mq';

body {
  @include mq($from: mobile) {
    color: red;
  }
  @include mq($until: tablet) {
    color: blue;
  }
}

节点渲染器文件:

'use strict';

var sass = require('node-sass');
var path = require('path');
var fs = require('fs');

var options = {
  file: './sample.scss',
  importer: function bowerModule(url, file, done){
    var bowerComponent = url.split(path.sep)[0];

    if (bowerComponent !== url) {
      fs.access(path.join(__dirname, 'bower_components', bowerComponent), fs.R_OK, function(err){
        if (err) {
          return done({ file: url });
        }

        var newUrl = path.join(__dirname, 'bower_components', url);

        done({ file: newUrl });
      })
    }
    else {
      done({ file: url });
    }
  }
};

sass.render(options, function(err, result){
  if (err) {
    console.error(err);
    return;
  }

  console.log(result.css.toString());
});

这个很简单,而且不是递归的。

require.resolve
函数可以帮助处理树 – 或者等到 [email protected] 从扁平依赖树中受益。


5
投票

我专门为此制作了 sass-npm 模块。

npm install sass-npm

在你的 SASS 中:

// Since node_modules/npm-module-name/style.scss exists, this will be imported.
@import "npm-module-name";

// Since just-a-sass-file isn't an installed npm module, it will be imported as a regular SCSS file.
@import "just-a-sass-file";

我通常使用 gulp-sass (它与常规 SASS 具有相同的“导入器”选项)

var gulp = require('gulp'),
    sass = require('gulp-sass'),
    sassNpm = require('sass-npm')();

然后,在您的

.pipe(sass())
中,添加导入器作为选项:

.pipe(sass({
    paths: ['public/scss'],
    importer: sassNpm.importer,
}))

5
投票

对于

dart-sass
和 2022 年的命令行用户,只需使用
--load-path
选项:

$ npx sass --load-path=node_modules

重要提示:整个node_modules文件夹包含这么多内容,只需将其设置为在监视模式下启动速度极慢即可。你应该只设置你的包路径,例如:

$npx sass -w --load-path=node_modules/foo --load-path=node_modules/bar/scss 

0
投票

根据 Sass 的官方文档,在导入中添加

~
应该可以完成这项工作。

但是,由于某种原因它对我不起作用,并且 sass 编译器仍然抱怨找不到该模块。

因此,我尝试了另一种对我有用的方法,没有任何问题。解决办法如下:

  • 如果您直接从 CLI 编译 sass 文件,请尝试以下操作:
sass src/main.scss dist/main.css --load-path=node_modules 
  • 如果您使用 npm 和/或 webpack 来编译 sass 文件,请在
    scripts
    package.json
    中添加类似的内容:
  "scripts": {
    ...
    "build": "sass src/main.scss dist/main.css --load-path=node_modules",
    ...
  }

然后运行:

npm run build
  • 最后,像这样导入模块:
@import "some-module/sass/app";

为了结束它,添加

--load-path=node_modules
标志永久解决了这个问题。欲了解更多信息,您可以查看:

sass --help

0
投票

截至 2024 年 2 月之前的所有答案均已过时

更多信息可在此处

推荐的方法是使用

pkg:
协议。

@use 'pkg:my-npm-pkg';
/* Or */
@import 'pkg:my-npm-pkg';

sass 编译器必须配置

importers
as

sass.render({ 
  file: 'my-file.scss',
  importers: [
    new sass.NodePackageImporter()
  ]
});
© www.soinside.com 2019 - 2024. All rights reserved.