2015-02-02 2 views
25

В настоящее время в наших файлах Sass мы имеем что-то вроде следующего:Импорт Sass через НПМ

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

Это плохо, потому что мы на самом деле не уверены в пути: он может быть ../node_modules, это может быть ../../../../../node_modules , из-за того, как npm устанавливает материал.

Есть ли способ в Сасс, который мы можем найти, пока не найдем node_modules? Или даже правильный способ включить Sass через npm?

+0

Возможный дубликат [SASS: импортировать файл из другого каталога?] (Http://stackoverflow.com/questions/6502313/sass-import-a-file-from-a-different-directory) – cimmanon

+3

@cimmanon : Какие? Нет, это совсем другой вопрос ... – callumacrae

ответ

8

Для этого вы можете использовать функцию Sass importer. Ср https://github.com/sass/node-sass#importer--v200.

Следующий пример иллюстрирует [email protected] с [email protected]:

Установите зависимость Bower:

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

Сасс файла:

@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], чтобы извлечь выгоду из плоского дерева зависимостей.

+0

Удивительно, я не знал о пользовательских импортерах в узлах. Благодаря! – callumacrae

+1

для этого следует использовать includeepaths – n3utrino

16

Как сказал он, Том new version of Sass has this new importer option, где каждый «импорт», который вы делаете в вашем файле 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"; 

Я надеюсь, что это поможет вам и другим. Поскольку добавление относительных путей всегда является болью в заднице :)

+2

Это потрясающе! Какое имя файла внутри 'node_modules/inuit-normalize' будет' @import 'inuit-normalize' 'load? – mikemaccana

+0

«относительные пути - это всегда боль в сущности» FTFY :) – jrharshath

14

Вы можете добавить еще один способ оплаты: includePaths.

Plain пример

сниппета на основе, например, из Oncle Тома.

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 и СКС-Loader пример

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

Обратите внимание на последний аргумент, INCLUDEPATHs должен быть массивом. Имейте в виду использовать right format

+0

Это сработало для меня. Вот еще примеры того, как указать параметры sass-loader: https://github.com/jtangelder/sass-loader#sass-options –

+1

Намного больше, чем что-либо еще IMHO, спасибо! –

3

Я специально разработал модуль 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"; 

Я обычно использую Глоток-дерзость (который имеет один и тот же вариант 'импортер' в качестве регулярного SASS)

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

Тогда в вашем .pipe(sass()), добавьте импортер в качестве опции:

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

Пожалуйста, заполните поле репозитория в вашем пакете.json! – callumacrae

+0

Кажется очень похожим на тот, который я написал, за исключением того, что у меня есть путь из package.json, а не для того, чтобы требовать стилей. Hssps://gist.github.com/callumacrae/09de2b8294339d6a6785 Вы написали «sass -npm-import "в ваших документах, но на самом деле это называется" sass-npm ". – callumacrae

+0

Добавлен поле хранилища @callumacrae, обновлено README, приветствия! Если вы хотите добавить получение sass из 'package.json' в качестве PR, пойдите для этого! – mikemaccana

24

Если вы ищете удобный ответ в 2017 году и используете Webpack, это было самым простым.

Пусть ваш путь модуль подобен:

node_modules/some-module/sass/app 

Затем в главном файле SCSS вы можете использовать:

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

Тильда оператор должен разрешить любой импорт в качестве модуля.

+1

Простейший из всех :) – Shreyas

+3

Мне кажется, что это работает автоматически, если вы используете Webpack. – CTarczon

+1

@CTarczon это следует упомянуть в ответе, многие люди, включая меня, не используют Webpack для компиляции их Sass. –

Смежные вопросы