Saat menggunakan SASS, bagaimana cara mengimpor file dari direktori yang berbeda?

93

Di SASS, apakah mungkin untuk mengimpor file dari direktori lain? Misalnya, jika saya memiliki struktur seperti ini:

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

template.scss dapat mengimpor _common.scss menggunakan @import "common"tetapi mungkinkah more_styles.scss mengimpor _common.scss? Saya mencoba beberapa hal berbeda termasuk @import "../sub_directory_a/common"dan @import "../sub_directory_a/_common.scss"tetapi tidak ada yang berhasil.

spaaarky21
sumber

Jawaban:

69

Sepertinya beberapa perubahan pada SASS memungkinkan apa yang Anda coba lakukan pada awalnya:

@import "../subdir/common";

Kami bahkan membuat ini berfungsi untuk beberapa folder yang sama sekali tidak terkait yang terletak di c:\projects\sass:

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

Cukup tambahkan secukupnya ../untuk memastikan Anda akan berakhir di root drive dan Anda siap melakukannya.

Tentu saja, solusi ini jauh dari cukup, tetapi saya tidak bisa mengimpor dari folder yang sama sekali berbeda untuk bekerja, tidak menggunakan I c:\projects\sassatau mengatur variabel lingkungan SASS_PATH(dari :: referensi load_paths ) ke nilai yang sama.

Oliver
sumber
9
Ini "jauh dari cantik"! Tapi jawaban ini mendapatkan banyak suara positif. Apakah ini benar-benar dianggap sebagai praktik yang lebih baik daripada -I? Jika nama jalur itu berubah, akan ada banyak pencarian dan penggantian; dan itu membutuhkan struktur folder lokal yang sama dari siapa pun yang berbagi .scss
WiseOldDuck
14
"Tambahkan saja cukup ../ untuk memastikan Anda akan sampai di root drive dan Anda siap melakukannya." Hahaha itu membuat hariku.
Steve Harrison
4
Saya menyarankan untuk mengabaikan jawaban ini sepenuhnya. Sayangnya ini adalah salah satu dari banyak pertanyaan SO, yang dijawab dengan tidak benar dengan suara terbanyak. Jika Anda ingin kode Anda mudah rusak, gunakanlah. Jika Anda menginginkan solusi yang kuat, lihat jawaban saya di bawah.
adi518
2
@ adi518: Saya dapat memperdebatkan pernyataan Anda "Jika Anda ingin kode Anda mudah rusak, gunakanlah." Solusi yang diberikan telah bekerja untuk kami sejak (jadi hampir 4 tahun sekarang) dan tidak merusak apa pun. Saya merasa ini adalah salah satu solusi yang mungkin agak kotor tetapi menyelesaikan pekerjaan dengan cepat dan tanpa menggali terlalu dalam ke bagian dalam dari beberapa alat yang terlibat.
Oliver
2
Serius jangan lakukan ini.
shinzou
34

Anda dapat menggunakan tombol -Ibaris perintah atau :load_pathsopsi dari kode Ruby untuk ditambahkan sub_directory_ake jalur pemuatan Sass. Jadi jika Anda menjalankan Sass root_directory, lakukan sesuatu seperti ini:

sass -I sub_directory_a --watch sub_directory_b:sub_directory_b

Maka Anda hanya dapat menggunakan @import "common"di more_styles.scss.

Miikka
sumber
1
Bagus. Itulah yang ingin saya ketahui. Dan saya pikir MisterJack juga tertarik pada sesuatu, tetapi sepertinya Kompas hanya memiliki folder yang sudah ada di jalurnya.
spaaarky21
3
-I Bendera rantai untuk menyertakan lebih dari satu direktori, misalnyasass -I sub_directory_a -I sub_directory_c --watch sub_directory_b:sub_directory_b
bob esponja
20

Menggunakan webpack dengan sass-loader yang bisa saya gunakan ~untuk merujuk ke jalur root proyek. Misalnya dengan asumsi struktur folder OPs dan Anda berada dalam file di dalam sub_directory_b:

@import "~sub_directory_a/_common";

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

Sammi
sumber
8
Tampaknya ini diimpor dari node_modules/dan bukan dari akar proyek.
Splaktar
Saya harus menambahkan "sub_directory_a"ke saya includePathsdan menggunakan @import "common";sintaks saat menggunakan CLI Angular yang menyertakan sass-loader.
Splaktar
Ini harus menjadi jawaban yang disetujui.
shinzou
4
Setuju dengan Splaktar. Dari dokumen sass-loader: webpack menyediakan mekanisme lanjutan untuk menyelesaikan file. Sass-loader menggunakan fitur importir khusus Sass untuk meneruskan semua kueri ke mesin penyelesaian webpack. Dengan demikian Anda dapat mengimpor modul Sass Anda dari node_modules. Tambahkan saja dengan ~ untuk memberi tahu webpack bahwa ini bukan impor relatif ... Penting untuk hanya menambahkan ~, karena ~ / menyelesaikan direktori home.
Anthony
Perhatikan bahwa ~/bagi saya sepertinya tidak merujuk ke direktori home. Atau direktori mana pun yang telah saya coba uji. Apakah ada cara untuk benar-benar mencoba dan mencari tahu di mana ini mengacu ??
Douglas Gaskell
8

Mengimpor .scssfile yang memiliki impor bersarang dengan posisi relatif berbeda tidak akan berfungsi. jawaban atas yang diusulkan (menggunakan banyak ../) hanyalah peretasan kotor yang akan berfungsi selama Anda menambahkan cukup ../untuk mencapai root OS penerapan proyek Anda.

  1. Tambahkan jalur SCSS target sebagai target penelusuran untuk compiler SCSS. Ini dapat dicapai dengan menambahkan folder stylesheets ke dalam file konfigurasi scss, ini adalah fungsi kerangka kerja yang Anda gunakan,

menggunakan :load_pathspada config.rduntuk kerangka kerja berbasis kompas (Ex. rel)

gunakan kode berikut di scss-config.jsonuntukfourseven/meteor-scss

{
  "includePaths": [
    "{}/node_modules/ionicons/dist/scss/"
  ]
}
  1. Gunakan jalur absolut (vs. jalur relatif).

Contoh, dengan fourseven/meteor-scss, Anda dapat menggunakan {}untuk menyorot tingkat teratas dari proyek Anda sesuai contoh berikut

@import "{}/node_modules/module-name/stylesheet";
helcode
sumber
Tidak ada yang khusus meteor, itu hanya contoh.
helcode
4

Jawaban yang dipilih tidak menawarkan solusi yang layak.

Praktik OP sepertinya tidak teratur. File bersama / umum biasanya berada di bawah partials, direktori boilerplate standar. Anda kemudian harus menambahkan partialsdirektori ke jalur impor konfigurasi Anda untuk menyelesaikan sebagian di mana pun dalam kode Anda.

Ketika saya mengalami masalah ini untuk pertama kalinya, saya pikir SASS mungkin memberi Anda variabel global yang mirip dengan Node __dirname, yang membuat jalur absolut ke direktori kerja saat ini ( cwd). Sayangnya, tidak dan alasannya adalah karena interpolasi pada @importdirektif tidak memungkinkan, maka Anda tidak dapat melakukan jalur impor dinamis.

Menurut dokumen SASS .

Anda perlu mengatur :load_pathskonfigurasi Sass Anda. Karena OP menggunakan Kompas, saya akan mengikuti sesuai dengan dokumentasi di sini .

Anda dapat menggunakan solusi CLI sesuai tujuan, tetapi mengapa? jauh lebih nyaman untuk menambahkannya config.rb. Masuk akal untuk menggunakan CLI untuk menimpa config.rb(Misalnya, skenario build berbeda).

Jadi, dengan asumsi Anda config.rbberada di bawah root proyek, cukup tambahkan baris berikut: add_import_path 'sub_directory_a'

Dan sekarang @import 'common';akan bekerja dengan baik di mana saja.

Sementara ini menjawab OP, masih ada lagi.

Lampiran

Anda cenderung mengalami kasus di mana Anda ingin mengimpor file CSS dengan cara yang disematkan, yaitu, bukan melalui @importarahan vanilla yang disediakan CSS di luar kotak, tetapi penggabungan sebenarnya dari konten file CSS dengan SASS Anda. Ada pertanyaan lain , yang dijawab dengan tidak meyakinkan (solusinya tidak bekerja lintas lingkungan). Solusinya adalah dengan menggunakan ekstensi SASS ini .

Setelah terinstal, tambahkan baris berikut ke konfigurasi Anda: require 'sass-css-importer'dan kemudian, di suatu tempat di kode Anda:@import 'CSS:myCssFile';

Perhatikan ekstensi harus dihilangkan agar ini berfungsi.

Namun, kami akan mengalami masalah yang sama saat mencoba mengimpor file CSS dari jalur non-default dan add_import_pathtidak mematuhi file CSS. Jadi untuk mengatasinya, Anda perlu menambahkan, baris lain di konfigurasi Anda, yang secara alami serupa:

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

Sekarang semuanya akan bekerja dengan baik.

PS, saya perhatikan sass-css-importerdokumentasi menunjukkan CSS:awalan diperlukan selain menghilangkan .cssekstensi. Saya menemukan itu berhasil. Seseorang memulai masalah , yang sejauh ini masih belum terjawab.

adi518
sumber
2

Gulp akan melakukan pekerjaan untuk mengawasi file sass Anda dan juga menambahkan jalur file lain dengan includePaths. contoh:

gulp.task('sass', function() {
  return gulp.src('scss/app.scss')
    .pipe($.sass({
      includePaths: sassPaths
    })
    .pipe(gulp.dest('css'));
});
oshry retribusi
sumber
7
Anda memahami bahwa includePaths hanya menggunakan -Iopsi dari baris perintah, bukan?
cimmanon
2

node-sass(pembungkus SASS resmi untuk node.js) menyediakan opsi baris perintah --include-pathuntuk membantu dengan persyaratan tersebut.

Contoh:

Masuk package.json:

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

Sekarang, jika Anda memiliki file src/styles/common.scssdi proyek Anda, Anda dapat mengimpornya @import 'styles/common';di mana saja di proyek Anda.

Lihat https://github.com/sass/node-sass#usage-1 untuk lebih jelasnya.

Vijay Aggarwal
sumber
1

Untuk menentukan file yang akan diimpor, dimungkinkan untuk menggunakan semua folder definisi umum. Anda hanya perlu menyadari bahwa ini relatif terhadap file yang Anda definisikan. Lebih lanjut tentang opsi impor dengan contoh yang dapat Anda periksa di sini .

Nesha Zoric
sumber
1

Jika menggunakan Web Compiler di Visual Studio Anda dapat menambahkan path ke includePathcompilerconfig.json.defaults. Maka tidak perlu beberapa nomor ../karena kompilator akan menggunakan includePath sebagai lokasi untuk mencari impor.

Sebagai contoh:

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

Ini adalah jawaban setengah.

Lihat Kompas , dengan itu Anda dapat menempatkan Anda _common.scssdi dalam partialsfolder, dan kemudian mengimpornya dengan @import common, tetapi berfungsi di setiap file.

Alessandro Vendruscolo
sumber
Saya pikir tanggapan Miikka benar-benar apa yang saya cari, tetapi sekarang saya juga ingin tahu tentang Kompas. Apakah direktori parsial spesifik untuk proyek tertentu? Atau apakah file yang dimasukkan ke direktori parsial akan tersedia "secara global", di mana pun Kompas digunakan?
spaaarky21
4
Ini sama sekali tidak menjawab pertanyaan itu.
cimmanon
0

Saya mengalami masalah yang sama. Dari solusi saya, saya datang ke ini. Jadi inilah kode Anda:

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

Sejauh yang saya tahu jika Anda ingin mengimpor satu scss ke yang lain itu harus parsial. Saat Anda mengimpor dari direktori yang berbeda, beri nama more_styles.scsske _more_styles.scss. Kemudian impor ke template.scss@import seperti ini ../sub_directory_b/_more_styles.scss. Itu berhasil untuk saya. Tapi seperti yang Anda sebutkan ../sub_directory_a/_common.scsstidak berfungsi. Itu direktori yang sama dari template.scss. Itulah mengapa itu tidak akan berhasil.

Sajidur Rahman
sumber
0

Pertimbangkan untuk menggunakan parameter includePaths ...

"Kompiler SASS menggunakan setiap jalur di loadPaths saat menyelesaikan SASS @imports."

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

Deejers
sumber
0

Cara terbaik adalah dengan menggunakan sass-loader. Ini tersedia sebagai paket npm. Ini menyelesaikan semua masalah terkait jalur dan membuatnya sangat mudah.

Rut Shah
sumber
-6

Saya memiliki masalah yang sama dan saya menemukan solusi dengan menambahkan jalur ke file seperti:

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

@import "C: / xampp / htdocs / Scss_addons / Kompas / kompas";

Netix
sumber
1
Sementara jawaban serupa telah diberikan sebelumnya, jalur absolut agak spesifik ke server sebagai jawaban umum (Anda memang mengatakan "suka", tentu saja).
dakab