Импорт Sass через npm
В настоящее время в наших файлах Sass у нас есть что-то вроде следующего:
@import "../../node_modules/some-module/sass/app";
Это плохо, потому что мы на самом деле не уверены в правильности пути: это может быть ../node_modules
, может быть ../../../../../node_modules
, из-за того, как npm устанавливает материал.
есть ли способ в Sass, который мы можем искать, пока не найдем node_modules? Или даже правильный способ включения Sass через npm?
5 ответов
вы можете использовать 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());
});
Это простой и не рекурсивные. The require.resolve
функция может помочь справиться с деревом - или подождать, пока npm@3.0.0 чтобы извлечь выгоду из плоского дерева зависимостей.
Если вы ищете удобный ответ в 2017 году и используете Webpack, это было проще всего найти.
предположим, что ваш путь модуля похож на:
node_modules/some-module/sass/app
затем в вашем основном файле scss вы можете использовать:
@import "~some-module/sass/app";
оператор Тильды разрешает любой импорт как модуль.
как сказал дядюшка том,новая версия 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";
Я надеюсь, что это поможет вам и другим. Потому что добавление относительных путей всегда является болью в заднице:)
вы можете добавить еще 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 должен быть массив. Поддерживать ум использовать формат
Я 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,
}))