目前在我们的 Sass 文件中,我们有如下内容:
@import "../../node_modules/some-module/sass/app";
这很糟糕,因为我们实际上不确定路径:它可能是
../node_modules
,也可能是 ../../../../../node_modules
,因为 npm 如何安装东西。
Sass中有没有一种方法可以让我们向上搜索直到找到node_modules?或者甚至是通过 npm 包含 Sass 的正确方法?
如果您正在 2017 年寻找方便的答案并且正在使用 Webpack,这是我发现的最简单的答案。
假设你的模块路径是这样的:
node_modules/some-module/sass/app
然后在你的主 scss 文件中你可以使用:
@import "~some-module/sass/app";
波浪号运算符应将任何导入解析为模块。
您可以将另一个 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 必须是数组。请记住使用正确的格式
正如 Oncle Tom 提到的,新版本的 Sass 有这个新的
importer
选项,您在 Sass 文件上执行的每个“导入”都将首先通过此方法。这意味着您可以修改此方法的实际 url。
我使用
require.resolve
来定位实际的模块入口文件。'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";
我希望对您和其他人有所帮助。因为添加相对路径总是很痛苦:)
您可以使用 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] 从扁平依赖树中受益。
我专门为此制作了 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,
}))
对于
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
根据 Sass 的官方文档,在导入中添加
~
应该可以完成这项工作。
但是,由于某种原因它对我不起作用,并且 sass 编译器仍然抱怨找不到该模块。
因此,我尝试了另一种对我有用的方法,没有任何问题。解决办法如下:
sass src/main.scss dist/main.css --load-path=node_modules
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
截至 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()
]
});