通过 npm 导入 Sass
Importing Sass through npm
目前在我们的 Sass 文件中有如下内容:
@import "../../node_modules/some-module/sass/app";
这很糟糕,因为我们实际上不确定路径:可能是 ../node_modules
,也可能是 ../../../../../node_modules
,因为 npm 安装东西的方式。
有没有办法在 Sass 中向上搜索直到找到 node_modules?或者甚至是通过 npm 包含 Sass 的正确方法?
您可以使用 Sass importer
函数来执行此操作。比照。 https://github.com/sass/node-sass#importer--v200.
以下示例说明了 node-sass@3.0.0 和 node@0.12.2:
安装 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
函数可以帮助处理树——或者等到 npm@3.0.0 从平面依赖树中受益。
正如 Oncle Tom 提到的,new version of Sass has this new importer
option,您对 Sass 文件所做的每个 "import" 都将首先通过此方法。这意味着您可以修改此方法的实际 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
。您可以简单地 "require" 它在您的 Sass 文件中:
@import "inuit-normalize";
希望对您和其他人有所帮助。因为添加相对路径总是很麻烦:)
您可以在渲染选项中添加另一个 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 必须是数组。请记住使用 right format
我专门为此制作了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 具有相同的 'importer' 选项)
var gulp = require('gulp'),
sass = require('gulp-sass'),
sassNpm = require('sass-npm')();
然后,在您的 .pipe(sass())
中添加导入程序作为选项:
.pipe(sass({
paths: ['public/scss'],
importer: sassNpm.importer,
}))
如果您在 2017 年寻找方便的答案并且正在使用 Webpack,这是我发现的最简单的方法。
假设您的模块路径如下:
node_modules/some-module/sass/app
然后在你的主 scss 文件中你可以使用:
@import "~some-module/sass/app";
Tilde 运算符应将任何导入解析为模块。
对于 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 文件中有如下内容:
@import "../../node_modules/some-module/sass/app";
这很糟糕,因为我们实际上不确定路径:可能是 ../node_modules
,也可能是 ../../../../../node_modules
,因为 npm 安装东西的方式。
有没有办法在 Sass 中向上搜索直到找到 node_modules?或者甚至是通过 npm 包含 Sass 的正确方法?
您可以使用 Sass importer
函数来执行此操作。比照。 https://github.com/sass/node-sass#importer--v200.
以下示例说明了 node-sass@3.0.0 和 node@0.12.2:
安装 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
函数可以帮助处理树——或者等到 npm@3.0.0 从平面依赖树中受益。
正如 Oncle Tom 提到的,new version of Sass has this new importer
option,您对 Sass 文件所做的每个 "import" 都将首先通过此方法。这意味着您可以修改此方法的实际 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
。您可以简单地 "require" 它在您的 Sass 文件中:
@import "inuit-normalize";
希望对您和其他人有所帮助。因为添加相对路径总是很麻烦:)
您可以在渲染选项中添加另一个 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 必须是数组。请记住使用 right format
我专门为此制作了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 具有相同的 'importer' 选项)
var gulp = require('gulp'),
sass = require('gulp-sass'),
sassNpm = require('sass-npm')();
然后,在您的 .pipe(sass())
中添加导入程序作为选项:
.pipe(sass({
paths: ['public/scss'],
importer: sassNpm.importer,
}))
如果您在 2017 年寻找方便的答案并且正在使用 Webpack,这是我发现的最简单的方法。
假设您的模块路径如下:
node_modules/some-module/sass/app
然后在你的主 scss 文件中你可以使用:
@import "~some-module/sass/app";
Tilde 运算符应将任何导入解析为模块。
对于 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