Lors de l'utilisation de SASS, comment puis-je importer un fichier d'un répertoire différent?


90

Dans SASS, est-il possible d'importer un fichier d'un autre répertoire? Par exemple, si j'avais une structure comme celle-ci:

- root_directory
    - sub_directory_a
        - _common.scss
        - template.scss
    - sub_directory_b
        - more_styles.scss

template.scss pourrait importer _common.scss en utilisant @import "common"mais est-il possible pour more_styles.scss d'importer _common.scss? J'ai essayé différentes choses, y compris @import "../sub_directory_a/common"et @import "../sub_directory_a/_common.scss"mais rien ne semble fonctionner.

Réponses:


69

On dirait que certaines modifications apportées à SASS ont rendu possible ce que vous avez essayé de faire au départ:

@import "../subdir/common";

Nous avons même fait fonctionner cela pour un dossier totalement indépendant situé dans c:\projects\sass:

@import "../../../../../../../../../../projects/sass/common";

Ajoutez juste assez ../pour être sûr que vous vous retrouverez à la racine du lecteur et que vous êtes prêt à partir.

Bien sûr, cette solution est loin d'être jolie, mais je ne pouvais pas faire fonctionner une importation depuis un dossier totalement différent, sans utiliser I c:\projects\sassni définir la variable d'environnement SASS_PATH(de :: load_paths reference ) à cette même valeur.


9
C'est "loin d'être joli"! Mais cette réponse reçoit beaucoup de votes positifs. Est-ce vraiment considéré comme une meilleure pratique que -I? Si ce chemin change, il y aura beaucoup de recherches et de remplacements; et il nécessite la même structure de dossiers locaux que toute personne partageant le .scss
WiseOldDuck

14
"Ajoutez juste assez ../ pour être sûr que vous vous retrouverez à la racine du lecteur et que vous êtes prêt à partir." Hahaha qui a fait ma journée.
Steve Harrison

4
Je conseille d'ignorer complètement cette réponse. Malheureusement, c'est l'une des nombreuses questions SO à laquelle il est mal répondu par des votes positifs. Si vous voulez que votre code se brise facilement, utilisez-le. Si vous voulez une solution robuste, voyez ma réponse ci-dessous.
adi518

2
@ adi518: Je pourrais discuter de votre déclaration "Si vous voulez que votre code se casse facilement, utilisez-le." La solution donnée fonctionne pour nous depuis (donc presque 4 ans maintenant) et n'a rien cassé. Je pense que c'est l'une de ces solutions qui pourrait être un peu sale, mais faire le travail rapidement et sans creuser trop profondément dans les éléments internes de certains des outils impliqués.
Oliver

2
Sérieusement, ne faites pas ça.
shinzou

34

Vous pouvez utiliser le -Icommutateur de ligne de commande ou l' :load_pathsoption du code Ruby pour ajouter sub_directory_aau chemin de chargement de Sass. Donc, si vous exécutez Sass depuis root_directory, faites quelque chose comme ceci:

sass -I sub_directory_a --watch sub_directory_b:sub_directory_b

Ensuite, vous pouvez simplement utiliser @import "common"dans more_styles.scss.


1
Génial. C'est exactement ce que je voulais savoir. Et je pense que MisterJack est également sur quelque chose, mais il semble que Compass a juste un dossier qui est déjà sur le chemin.
spaaarky21

3
-I Drapeaux de chaîne pour inclure plus d'un répertoire, par exemplesass -I sub_directory_a -I sub_directory_c --watch sub_directory_b:sub_directory_b
bob esponja

19

En utilisant webpack avec sass-loader, je peux utiliser ~pour faire référence au chemin racine du projet. Par exemple, en supposant la structure du dossier OP et que vous êtes dans un fichier dans le sous-répertoire_b:

@import "~sub_directory_a/_common";

Documentation: https://github.com/webpack-contrib/sass-loader#resolving-import-at-rules


8
Cela semble importer de node_modules/et non de la racine du projet.
Splaktar

J'ai dû ajouter "sub_directory_a"à mon includePathset utiliser la @import "common";syntaxe lors de l'utilisation de la CLI angulaire qui inclut sass-loader.
Splaktar

Cela devrait être la réponse approuvée.
shinzou

3
D'accord avec Splaktar. À partir de la documentation sass-loader: webpack fournit un mécanisme avancé pour résoudre les fichiers. Le chargeur sass utilise la fonction d'importation personnalisée de Sass pour transmettre toutes les requêtes au moteur de résolution Webpack. Ainsi, vous pouvez importer vos modules Sass depuis node_modules. Ajoutez-les simplement avec un ~ pour indiquer à Webpack que ce n'est pas une importation relative ... Il est important de ne l'ajouter que de ~, car ~ / se résout dans le répertoire personnel.
Anthony

Notez que ~/cela ne semble pas faire référence au répertoire personnel pour moi. Ou n'importe quel répertoire que j'ai essayé de tester. Existe-t-il un moyen d'essayer de savoir à quoi cela fait référence?
Douglas Gaskell

8

L'importation d'un .scssfichier ayant une importation imbriquée avec une position relative différente ne fonctionnera pas. la meilleure réponse proposée (en utilisant beaucoup de ../) est juste un sale hack qui fonctionnera tant que vous en avez ajouté suffisamment ../pour atteindre la racine du système d'exploitation de déploiement de votre projet.

  1. Ajoutez le chemin SCSS cible comme cible de recherche pour le compilateur SCSS. Ceci peut être réalisé en ajoutant le dossier des feuilles de style dans le fichier de configuration scss, c'est fonction du framework que vous utilisez,

utiliser :load_pathsà config.rdpour les cadres basés sur des compas (ex. rails)

utilisez le code suivant à scss-config.jsonpourfourseven/meteor-scss

{
  "includePaths": [
    "{}/node_modules/ionicons/dist/scss/"
  ]
}
  1. Utilisez des chemins absolus (par rapport aux chemins relatifs).

Exemple, avec fourseven/meteor-scss, vous pouvez utiliser {}pour mettre en évidence le niveau supérieur de votre projet selon l'exemple suivant

@import "{}/node_modules/module-name/stylesheet";

Rien de spécifique meteor, c'était juste un exemple.
helcode

4

La réponse choisie n'offre pas de solution viable.

La pratique d'OP semble irrégulière. Un fichier partagé / commun vit normalement sous partials, un répertoire standard standard. Vous devez ensuite ajouter un partialsrépertoire à vos chemins d'importation de configuration afin de résoudre les partiels n'importe où dans votre code.

Lorsque j'ai rencontré ce problème pour la première fois, j'ai pensé que SASS vous donnait probablement une variable globale similaire à celle de Node __dirname, qui conserve un chemin absolu vers le répertoire de travail actuel ( cwd). Malheureusement, ce n'est pas le cas et la raison en est que l'interpolation sur une @importdirective n'est pas possible, vous ne pouvez donc pas faire de chemin d'importation dynamique.

Selon les documents SASS .

Vous devez définir :load_pathsdans votre configuration Sass. Puisque OP utilise Compass, je vais suivre cela conformément à la documentation ici .

Vous pouvez utiliser la solution CLI comme prévu, mais pourquoi? il est beaucoup plus pratique de l'ajouter config.rb. Il serait logique d'utiliser CLI pour le remplacement config.rb(par exemple, différents scénarios de construction).

Donc, en supposant que vous soyez config.rbsous la racine du projet, ajoutez simplement la ligne suivante: add_import_path 'sub_directory_a'

Et maintenant @import 'common';fonctionnera très bien n'importe où.

Bien que cela réponde OP, il y a plus.

appendice

Vous êtes susceptible de rencontrer des cas où vous souhaitez importer un fichier CSS de manière intégrée, c'est-à-dire non via la @importdirective vanilla fournie par CSS, mais par une fusion réelle d'un contenu de fichier CSS avec votre SASS. Il y a une autre question à laquelle on ne répond pas de manière concluante (la solution ne fonctionne pas entre environnements). La solution est alors d'utiliser cette extension SASS.

Une fois installé, ajoutez la ligne suivante à votre config: require 'sass-css-importer'puis, quelque part dans votre code:@import 'CSS:myCssFile';

Notez que l'extension doit être omise pour que cela fonctionne.

Cependant, nous rencontrerons le même problème en essayant d'importer un fichier CSS à partir d'un chemin non par défaut et add_import_pathne respectant pas les fichiers CSS. Donc, pour résoudre cela, vous devez ajouter une autre ligne dans votre configuration, qui est naturellement similaire:

add_import_path Sass::CssImporter::Importer.new('sub_directory_a')

Maintenant, tout fonctionnera bien.

PS, j'ai remarqué que la sass-css-importerdocumentation indique qu'un CSS:préfixe est requis en plus d'omettre l' .cssextension. J'ai découvert que cela fonctionne malgré tout. Quelqu'un a lancé un problème , qui est resté sans réponse jusqu'à présent.


2

Gulp fera le travail pour regarder vos fichiers sass et ajouter également les chemins d'autres fichiers avec includePaths. exemple:

gulp.task('sass', function() {
  return gulp.src('scss/app.scss')
    .pipe($.sass({
      includePaths: sassPaths
    })
    .pipe(gulp.dest('css'));
});

7
Vous comprenez que includePaths utilise simplement l' -Ioption de la ligne de commande, non?
cimmanon

2

node-sass(le wrapper SASS officiel pour node.js) fournit une option de ligne de commande --include-pathpour vous aider avec ces exigences.

Exemple:

Dans package.json:

"scripts": {
    "build-css": "node-sass src/ -o src/ --include-path src/",
}

Maintenant, si vous avez un fichier src/styles/common.scssdans votre projet, vous pouvez l'importer @import 'styles/common';n'importe où dans votre projet.

Consultez https://github.com/sass/node-sass#usage-1 pour plus de détails.


1

Pour définir le fichier à importer, il est possible d'utiliser toutes les définitions communes des dossiers. Vous devez juste être conscient que c'est relatif au fichier que vous définissez. En savoir plus sur l'option d'importation avec des exemples, vous pouvez vérifier ici .


1

Si vous utilisez Web Compiler dans Visual Studio, vous pouvez ajouter le chemin d'accès includePathdans compilerconfig.json.defaults. Ensuite, il n'y a pas besoin d'un certain nombre de ../puisque le compilateur utilisera includePath comme emplacement pour rechercher l'importation.

Par exemple:

"includePath": "node_modules/foundation-sites/scss",

0

C'est une demi-réponse.

Découvrez Compass , avec lui, vous pouvez le placer _common.scssdans un partialsdossier, puis l'importer avec @import common, mais cela fonctionne dans tous les fichiers.


Je pense que la réponse de Miikka était vraiment ce que je cherchais, mais maintenant je suis aussi curieux de savoir Compass. Le répertoire des partiels est-il spécifique à un projet particulier? Ou les fichiers placés dans le répertoire des partiels seraient-ils disponibles «globalement», partout où Compass est utilisé?
spaaarky21

4
Cela ne répond pas du tout à la question.
cimmanon

0

J'ai rencontré le même problème. De ma solution, je suis arrivé là-dedans. Voici donc votre code:

- root_directory
    - sub_directory_a
        - _common.scss
        - template.scss
    - sub_directory_b
        - more_styles.scss

Pour autant que je sache, si vous souhaitez importer un scss dans un autre, il doit être partiel. Lorsque vous importez depuis un répertoire différent, nommez votre fichier more_styles.scssvers _more_styles.scss. Puis importez-le dans votre template.scsslike this @import ../sub_directory_b/_more_styles.scss. Cela a fonctionné pour moi. Mais comme vous l'avez mentionné ../sub_directory_a/_common.scssne fonctionne pas. C'est le même répertoire du template.scss. C'est pourquoi cela ne fonctionnera pas.



0

Le meilleur moyen est d'utiliser sass-loader. Il est disponible sous forme de package npm. Il résout tous les problèmes liés au chemin et le rend très facile.


-6

J'ai eu le même problème et j'ai trouvé une solution en ajoutant un chemin d'accès au fichier comme:

@import "C: / xampp / htdocs / Scss_addons / Bootstrap / bootstrap";

@import "C: / xampp / htdocs / Scss_addons / Compass / compass";


1
Bien qu'une réponse similaire ait été donnée plus tôt, le chemin absolu est un peu spécifique au serveur en tant que réponse générale (vous avez dit «j'aime», bien sûr).
dakab
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.