web-dev-qa-db-fra.com

Importation de Sass via npm

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?

39
callumacrae

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.

48
ProllyGeek

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 :)

17
Lucas Motta

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

16
Kamil Jopek

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.

7
Oncle Tom

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,
}))
5
mikemaccana