Actuellement, dans nos fichiers Sass, nous avons quelque chose comme ceci:
@import "../../node_modules/some-module/sass/app";
C'est mauvais, car nous ne sommes pas vraiment sûrs du chemin: il pourrait être ../node_modules
, il pourrait être ../../../../../node_modules
, à cause de la façon dont npm installe les choses.
Existe-t-il un moyen dans Sass que nous puissions rechercher jusqu'à ce que nous trouvions node_modules? Ou même une bonne façon d'inclure Sass via npm?
Si vous cherchez une réponse pratique en 2017 et que vous utilisez Webpack, c'est la plus simple que j'ai trouvée.
Supposons que le chemin de votre module ressemble à:
node_modules/some-module/sass/app
Ensuite, dans votre fichier scss principal, vous pouvez utiliser:
@import "~some-module/sass/app";
L'opérateur Tilde doit résoudre toute importation en tant que module.
Comme Oncle Tom l'a mentionné, le la nouvelle version de Sass a cette nouvelle option importer
, où chaque "importation" que vous faites sur votre fichier Sass passera d'abord par cette méthode. Cela signifie que vous pouvez ensuite modifier l'URL réelle de cette méthode.
J'ai utilisé require.resolve
pour localiser le fichier d'entrée du module réel.
Jetez un œil à ma tâche de gorgée et voyez si cela vous aide:
'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'));
});
Supposons maintenant que vous ayez installé inuit-normalize
en utilisant le nœud. Vous pouvez simplement "l'exiger" sur votre fichier Sass:
@import "inuit-normalize";
J'espère que cela vous aide, vous et les autres. Parce que l'ajout de chemins relatifs est toujours pénible :)
Vous pouvez ajouter un autre includePaths à vos options de rendu.
Exemple simple
Extrait basé sur l'exemple d'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());
});
Cela devrait faire l'affaire. Vous pouvez inclure les fichiers du package à l'aide de @import "my-cool-package/super-grid
Exemple de Webpack et de chargeur scss
{
test: /\.scss$/,
loader: 'style!css!autoprefixer?browsers=last 2 version!sass?outputStyle=expanded&sourceMap=true&sourceMapContents=true&includePaths[]=./node_modules'
},
Remarquez le dernier argument, includePaths doit être un tableau. N'oubliez pas d'utiliser bon format
Vous pouvez utiliser une fonction Sass importer
pour ce faire. Cf. https://github.com/sass/node-sass#importer--v2 .
L'exemple suivant illustre [email protected] avec [email protected]:
Installez la dépendance Bower:
$ bower install sass-mq
$ npm install sass/node-sass#3.0.0-pre
Le fichier Sass:
@import 'sass-mq/mq';
body {
@include mq($from: mobile) {
color: red;
}
@include mq($until: tablet) {
color: blue;
}
}
Le fichier de rendu de noeud:
'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());
});
Celui-ci est simple et non récursif. Le require.resolve
la fonction pourrait aider à gérer l'arbre - ou attendre jusqu'à [email protected] pour bénéficier de l'arbre de dépendance plat.
J'ai créé le module sass-npm spécifiquement pour cela.
npm install sass-npm
Dans votre 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";
J'utilise normalement gulp-sass (qui a la même option "importateur" que SASS ordinaire)
var gulp = require('gulp'),
sass = require('gulp-sass'),
sassNpm = require('sass-npm')();
Ensuite, dans votre .pipe(sass())
, ajoutez l'importateur en option:
.pipe(sass({
paths: ['public/scss'],
importer: sassNpm.importer,
}))