Wie kann ich bei Verwendung von SASS eine Datei aus einem anderen Verzeichnis importieren?

89

Ist es in SASS möglich, eine Datei aus einem anderen Verzeichnis zu importieren? Wenn ich zum Beispiel eine Struktur wie diese hätte:

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

template.scss könnte _common.scss mit importieren, @import "common"aber ist es möglich, dass more_styles.scss _common.scss importiert? Ich habe versucht , ein paar andere Dinge , einschließlich @import "../sub_directory_a/common"und @import "../sub_directory_a/_common.scss"aber nichts scheint zu funktionieren.

spaaarky21
quelle

Antworten:

69

Anscheinend haben einige Änderungen an SASS das ermöglicht, was Sie ursprünglich versucht haben:

@import "../subdir/common";

Wir haben dies sogar für einen völlig unabhängigen Ordner in c:\projects\sass:

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

../Fügen Sie einfach genug hinzu , um sicherzugehen, dass Sie am Laufwerksstamm landen und loslegen können.

Natürlich ist diese Lösung alles andere als hübsch, aber ich konnte keinen Import aus einem völlig anderen Ordner zum Laufen bringenI c:\projects\sass , ohne die Umgebungsvariable SASS_PATH(von :: load_paths reference ) auf denselben Wert zu setzen oder zu setzen.

Oliver
quelle
9
Es ist "alles andere als hübsch"! Aber diese Antwort bekommt viele positive Stimmen. Ist das wirklich eine bessere Praxis als -I? Wenn sich dieser Pfadname ändert, wird viel gesucht und ersetzt. und es erfordert die gleiche lokale Ordnerstruktur von jedem, der die .scss
WiseOldDuck
14
"Fügen Sie einfach genug hinzu ../, um sicherzugehen, dass Sie am Laufwerksstamm landen und loslegen können." Hahaha, das hat meinen Tag gemacht.
Steve Harrison
4
Ich rate, diese Antwort komplett zu ignorieren. Leider ist es eine von vielen SO-Fragen, die mit Up-Votes falsch beantwortet werden. Wenn Sie möchten, dass Ihr Code leicht beschädigt wird, verwenden Sie ihn. Wenn Sie eine robuste Lösung wünschen, lesen Sie meine Antwort unten.
adi518
2
@ adi518: Ich könnte über Ihre Aussage streiten "Wenn Sie möchten, dass Ihr Code leicht kaputt geht, verwenden Sie ihn." Die gegebene Lösung funktioniert seitdem für uns (also seit fast 4 Jahren) und hat nichts kaputt gemacht. Ich bin der Meinung, dass dies eine dieser Lösungen ist, die möglicherweise etwas schmutzig sind, aber die Arbeit schnell erledigen, ohne zu tief in die Interna einiger der beteiligten Tools einzudringen.
Oliver
2
Im Ernst, tu das nicht.
Shinzou
33

Sie können den -IBefehlszeilenschalter oder die :load_pathsOption aus Ruby-Code verwenden, um sub_directory_aden Ladepfad von Sass zu erweitern. Wenn Sie also Sass ausführen root_directory, gehen Sie wie folgt vor:

sass -I sub_directory_a --watch sub_directory_b:sub_directory_b

Dann können Sie einfach @import "common"in verwenden more_styles.scss.

Miikka
quelle
1
Toll. Genau das wollte ich wissen. Und ich denke, MisterJack ist auch auf etwas, aber es klingt so, als hätte Compass nur einen Ordner, der bereits auf dem Weg ist.
spaaarky21
3
Ketten -I Fahnen mehr als ein Verzeichnis, zBsass -I sub_directory_a -I sub_directory_c --watch sub_directory_b:sub_directory_b
bob esponja
18

Mit Webpack mit Sass-Loader kann ich ~auf den Projektstammpfad verweisen. Angenommen, Sie nehmen die Ordnerstruktur des Betriebssystems an und befinden sich in einer Datei im Unterverzeichnis_b:

@import "~sub_directory_a/_common";

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

Sammi
quelle
8
Dies scheint aus node_modules/und nicht aus dem Stamm des Projekts zu importieren .
Splaktar
Ich musste "sub_directory_a"meine hinzufügen includePathsund die @import "common";Syntax verwenden, wenn ich die Angular-CLI verwendete, die Sass-Loader enthält.
Splaktar
Dies sollte die genehmigte Antwort sein.
Shinzou
3
Stimmen Sie Splaktar zu. Aus Sass-Loader-Dokumenten: Webpack bietet einen erweiterten Mechanismus zum Auflösen von Dateien. Der Sass-Loader verwendet die benutzerdefinierte Importer-Funktion von Sass, um alle Abfragen an die Webpack-Auflösungs-Engine zu übergeben. So können Sie Ihre Sass-Module aus node_modules importieren. Stellen Sie ihnen einfach ein ~ voran, um dem Webpack mitzuteilen, dass dies kein relativer Import ist ... Es ist wichtig, nur ein ~ voranzustellen, da ~ / in das Home-Verzeichnis aufgelöst wird.
Anthony
Beachten Sie, dass ~/sich das für mich nicht auf das Home-Verzeichnis zu beziehen scheint. Oder irgendein Verzeichnis, das ich zu testen versucht habe. Gibt es eine Möglichkeit, tatsächlich herauszufinden, worauf sich dies bezieht?
Douglas Gaskell
8

Das Importieren einer .scssDatei mit einem verschachtelten Import mit einer anderen relativen Position funktioniert nicht. Die am häufigsten vorgeschlagene Antwort (mit viel ../) ist nur ein schmutziger Hack, der funktioniert, solange Sie genug hinzugefügt haben ../, um die Wurzel des Bereitstellungsbetriebssystems Ihres Projekts zu erreichen.

  1. Fügen Sie den Ziel-SCSS-Pfad als Suchziel für den SCSS-Compiler hinzu. Dies kann durch Hinzufügen des Stylesheets-Ordners zur scss-Konfigurationsdatei erreicht werden. Dies ist eine Funktion des von Ihnen verwendeten Frameworks.

Verwendung :load_pathsbei config.rdfür kompassbasierte Frameworks (Bsp. Schienen)

Verwenden Sie den folgenden Code unter scss-config.jsonfürfourseven/meteor-scss

{
  "includePaths": [
    "{}/node_modules/ionicons/dist/scss/"
  ]
}
  1. Verwenden Sie absolute Pfade (im Vergleich zu relativen Pfaden).

Beispiel: Mit fourseven/meteor-scsskönnen Sie die {}oberste Ebene Ihres Projekts gemäß dem folgenden Beispiel hervorheben

@import "{}/node_modules/module-name/stylesheet";
Helcode
quelle
Nichts spezielles meteor, es war nur ein Beispiel.
Helcode
4

Die ausgewählte Antwort bietet keine praktikable Lösung.

Die Praxis von OP scheint unregelmäßig. Eine gemeinsam genutzte / gemeinsame Datei befindet sich normalerweise in partialseinem Standard-Boilerplate-Verzeichnis. Anschließend sollten Sie partialsIhren Konfigurationsimportpfaden ein Verzeichnis hinzufügen , um Partials an einer beliebigen Stelle in Ihrem Code aufzulösen.

Als ich zum ersten Mal auf dieses Problem stieß, stellte ich fest, dass SASS Ihnen wahrscheinlich eine globale Variable ähnlich der von Node gibt __dirname, die einen absoluten Pfad zum aktuellen Arbeitsverzeichnis ( cwd) beibehält. Dies ist leider nicht der Fall, und der Grund dafür ist, dass eine Interpolation einer @importDirektive nicht möglich ist. Daher können Sie keinen dynamischen Importpfad erstellen.

Laut SASS-Dokumenten .

Sie müssen :load_pathsin Ihrer Sass-Konfiguration einstellen . Da OP Compass verwendet, werde ich dies gemäß der Dokumentation hier befolgen .

Sie können die CLI-Lösung wie vorgesehen verwenden, aber warum? Es ist viel bequemer, es hinzuzufügen config.rb. Es wäre sinnvoll, CLI zum Überschreiben zu verwenden config.rb(z. B. verschiedene Build-Szenarien).

Angenommen, Sie config.rbbefinden sich unter dem Projektstamm, fügen Sie einfach die folgende Zeile hinzu: add_import_path 'sub_directory_a'

Und jetzt @import 'common';wird überall gut funktionieren.

Während dies OP beantwortet, gibt es noch mehr.

Blinddarm

Es ist wahrscheinlich, dass Sie auf Fälle stoßen, in denen Sie eine CSS-Datei auf eingebettete Weise importieren möchten, dh nicht über die Vanilla- @importDirektive, die CSS standardmäßig bereitstellt, sondern über die tatsächliche Zusammenführung eines CSS-Dateiinhalts mit Ihrem SASS. Es gibt noch eine andere Frage , die nicht eindeutig beantwortet wird (die Lösung funktioniert nicht umgebungsübergreifend). Die Lösung besteht dann darin, diese SASS-Erweiterung zu verwenden.

Fügen Sie nach der Installation Ihrer Konfiguration die folgende Zeile hinzu: require 'sass-css-importer'und dann irgendwo in Ihrem Code:@import 'CSS:myCssFile';

Beachten Sie, dass die Erweiterung weggelassen werden muss, damit dies funktioniert.

Beim Versuch, eine CSS-Datei aus einem nicht standardmäßigen Pfad zu importieren, tritt jedoch dasselbe Problem auf, und add_import_pathCSS-Dateien werden nicht berücksichtigt. Um dies zu lösen, müssen Sie eine weitere Zeile in Ihrer Konfiguration hinzufügen, die natürlich ähnlich ist:

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

Jetzt wird alles gut funktionieren.

PS: Ich habe festgestellt, dass in der sass-css-importerDokumentation angegeben CSS:ist, dass zusätzlich zum Weglassen der .cssErweiterung ein Präfix erforderlich ist . Ich fand heraus, dass es trotzdem funktioniert. Jemand hat ein Problem gestartet , das bisher unbeantwortet blieb.

adi518
quelle
2

Gulp erledigt die Aufgabe, Ihre Sass-Dateien zu überwachen und mit includePaths auch Pfade anderer Dateien hinzuzufügen. Beispiel:

gulp.task('sass', function() {
  return gulp.src('scss/app.scss')
    .pipe($.sass({
      includePaths: sassPaths
    })
    .pipe(gulp.dest('css'));
});
Oshry-Abgabe
quelle
7
Sie verstehen, dass includePaths nur die -IOption über die Befehlszeile verwendet, oder?
Cimmanon
2

node-sass(der offizielle SASS-Wrapper für node.js) bietet eine Befehlszeilenoption --include-path, um bei solchen Anforderungen zu helfen.

Beispiel:

In package.json:

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

Wenn Sie jetzt eine Datei src/styles/common.scssin Ihrem Projekt haben, können Sie diese mit einer @import 'styles/common';beliebigen Stelle in Ihrem Projekt importieren .

Weitere Informationen finden Sie unter https://github.com/sass/node-sass#usage-1 .

Vijay Aggarwal
quelle
1

Um die zu importierende Datei zu definieren, können Sie alle allgemeinen Definitionen der Ordner verwenden. Sie müssen sich nur bewusst sein, dass es sich um eine Datei handelt, die Sie definieren. Weitere Informationen zur Importoption mit Beispielen finden Sie hier .

Nesha Zoric
quelle
1

Wenn Sie Web Compiler in Visual Studio verwenden, können Sie den Pfad includePathin compilerconfig.json.defaults hinzufügen . Dann ist eine gewisse Anzahl nicht erforderlich, ../da der Compiler includePath als Speicherort für den Import verwendet.

Beispielsweise:

"includePath": "node_modules/foundation-sites/scss",
DavGarcia
quelle
0

Dies ist eine halbe Antwort.

Schauen Sie sich Compass an , damit können Sie Ihre _common.scssin einen partialsOrdner legen und dann mit importieren @import common, aber es funktioniert in jeder Datei.

Alessandro Vendruscolo
quelle
Ich denke, Miikkas Antwort war wirklich das, wonach ich gesucht habe, aber jetzt bin ich auch neugierig auf Compass. Ist das Teilverzeichnis irgendwie spezifisch für ein bestimmtes Projekt? Oder wären Dateien, die in das Teilverzeichnis gestellt werden, "global" verfügbar, wo immer Compass verwendet wird?
spaaarky21
4
Dies beantwortet die Frage überhaupt nicht.
Cimmanon
0

Ich bin auf das gleiche Problem gestoßen. Aus meiner Lösung bin ich darauf gekommen. Also hier ist dein Code:

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

Soweit ich weiß, wenn Sie ein scss in ein anderes importieren möchten, muss es ein Teil sein. Wenn Sie von anderem Verzeichnis importieren , benennen Sie more_styles.scsszu _more_styles.scss. Dann importiere es in dein template.scsswie folgt @import ../sub_directory_b/_more_styles.scss. Es hat bei mir funktioniert. Aber wie du schon erwähnt ../sub_directory_a/_common.scssnicht funktioniert. Das ist das gleiche Verzeichnis der template.scss. Deshalb wird es nicht funktionieren.

Sajidur Rahman
quelle
0

Verwenden Sie den Parameter includePaths ...

"Der SASS-Compiler verwendet jeden Pfad in loadPaths, wenn SASS @imports aufgelöst wird."

https://stackoverflow.com/a/33588202/384884

Deejers
quelle
0

Der beste Weg ist, Sass-Loader zu verwenden. Es ist als npm-Paket erhältlich. Es löst alle pfadbezogenen Probleme und macht es super einfach.

Rut Shah
quelle
-6

Ich hatte das gleiche Problem und fand eine Lösung, indem ich einen Pfad zur Datei hinzufügte wie:

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

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

Netix
quelle
1
Obwohl eine ähnliche Antwort bereits früher gegeben wurde, ist der absolute Pfad als allgemeine Antwort für den Server etwas zu spezifisch (Sie haben natürlich "Gefällt mir" gesagt).
Dakab