UNPKG

11.4 kBMarkdownView Raw
1# node-sass-magic-importer
2
3[![Patreon](https://img.shields.io/badge/patreon-donate-blue.svg)](https://www.patreon.com/maoberlehner)
4[![Donate](https://img.shields.io/badge/Donate-PayPal-blue.svg)](https://paypal.me/maoberlehner)
5[![Build Status](https://travis-ci.org/maoberlehner/node-sass-magic-importer.svg?branch=master)](https://travis-ci.org/maoberlehner/node-sass-magic-importer)
6[![Coverage Status](https://coveralls.io/repos/github/maoberlehner/node-sass-magic-importer/badge.svg?branch=master)](https://coveralls.io/github/maoberlehner/node-sass-magic-importer?branch=master)
7[![GitHub stars](https://img.shields.io/github/stars/maoberlehner/node-sass-magic-importer.svg?style=social&label=Star)](https://github.com/maoberlehner/node-sass-magic-importer)
8
9Custom node-sass importer for selector specific imports, node importing, module importing, globbing support and importing files only once.
10
11## Install
12
13```bash
14npm install node-sass-magic-importer --save-dev
15```
16
17## Features
18
19This importer enables several comfort functions for importing SASS files more easily.
20
21- [Selector filtering](#selector-filtering): import only specific selectors from a file.
22 (Uses the [node-sass-selector-importer](https://github.com/maoberlehner/node-sass-selector-importer) module.)
23- [Node filtering](#node-filtering): import only specific nodes from a file.
24 (Uses the [node-sass-filter-importer](https://github.com/maoberlehner/node-sass-filter-importer) module.)
25- [Module importing](#module-importing): import modules from `node_modules` without specifying the full path.
26 (Uses the [node-sass-package-importer](https://github.com/maoberlehner/node-sass-package-importer) module.)
27- [Globbing](#globbing): use globbing (e.g. `@import: 'scss/**/*.scss'`) to import multiple files at once.
28 (Uses the [node-sass-glob-importer](https://github.com/maoberlehner/node-sass-glob-importer) module.)
29
30By default every file is only imported once even if you `@import` the same file multiple times in your code (except if you are using filters).
31
32### Selector filtering
33
34With selector filtering, it is possible to import only certain CSS selectors form a file. This is especially useful if you want to import only a few CSS classes from a huge library or framework.
35
36```scss
37// Example:
38@import '{ .btn, .btn-alert } from style.scss';
39```
40
41```scss
42// Result:
43.btn { }
44.btn-alert { }
45```
46
47#### Transform imported selectors
48
49```scss
50// Example:
51@import '{ .btn as .button, .btn-alert as .button--alert } from style.scss';
52```
53
54```scss
55// Result:
56.button { }
57.button--alert { } // Transformed to match BEM syntax.
58```
59
60#### RegEx
61
62```scss
63// Example:
64@import '{ /^\..+-alert/ } from style.scss';
65```
66
67```scss
68// Result:
69.box-alert { }
70.btn-alert { }
71```
72
73```scss
74// Example:
75@import '{ /^\.btn(.*)/ as .button$1 } from style.scss';
76```
77
78```scss
79// Result:
80.button { }
81.button-alert { }
82```
83
84#### Usage with Bootstrap
85
86Bootstrap is a mighty and robust framework but most of the time you use only certain parts of it. There is the possibility to [customize](http://getbootstrap.com/customize/) Bootstrap to your needs but this can be annoying and you still end up with more code than you need. Also you might want to use just some specific parts of Bootstrap but your project uses the BEM syntax for writing class names.
87
88```scss
89// This example uses the v4 dev version of the Bootstrap `alert` component:
90// https://github.com/twbs/bootstrap/blob/v4-dev/scss/_alert.scss
91@import 'bootstrap/scss/variables';
92@import 'bootstrap/scss/mixins/border-radius';
93@import 'bootstrap/scss/mixins/alert';
94@import '{
95 .alert,
96 .alert-dismissible as .alert--dismissible,
97 .close as .alert__close
98} from bootstrap/scss/alert';
99```
100
101```scss
102// Result:
103.alert {
104 padding: 15px;
105 margin-bottom: 1rem;
106 border: 1px solid transparent;
107 border-radius: 0.25rem;
108}
109
110.alert--dismissible {
111 padding-right: 35px;
112}
113
114.alert--dismissible .alert__close {
115 position: relative;
116 top: -2px;
117 right: -21px;
118 color: inherit;
119}
120```
121
122### Node filtering
123
124Filter certain elements from SCSS code.
125
126```scss
127// Example:
128@import '[variables, mixins] from style.scss';
129```
130
131```scss
132// style.scss:
133$variable1: 'value';
134$variable2: 'value';
135.selector { }
136@mixin mixin() { }
137
138// Result:
139$variable1: 'value';
140$variable2: 'value';
141@mixin mixin() { }
142```
143
144#### Filters
145
146- **at-rules**: `@media`, `@supports`, `@mixin`,...
147- **functions**: `@function`
148- **mixins**: `@mixin`
149- **rules**: `.class-selector`, `#id-selector`,...
150- **silent**: Extract only nodes that do not compile to CSS code (mixins, placeholder selectors, variables,...)
151- **variables**: `$variable`
152- **make-your-own**: Define custom filters
153
154### Module importing
155
156In modern day web development, modules and packages are everywhere. There is no way around [npm](https://www.npmjs.com/) if you are a JavaScript developer. More and more CSS and SASS projects move to npm but it can be annoying to find a convenient way of including them into your project. Module importing makes this a little easier.
157
158```scss
159// Import the file that is specified in the `package.json` file of the module.
160// In the case of bootstrap, the following file is loaded:
161// https://github.com/twbs/bootstrap/blob/v4-dev/scss/bootstrap.scss
162@import '~bootstrap';
163```
164
165```scss
166// Import only specific files:
167@import '~bootstrap/scss/variables';
168@import '~bootstrap/scss/mixins/border-radius';
169@import '~bootstrap/scss/mixins/alert';
170@import '~bootstrap/scss/alert';
171```
172
173The "~" is mandatory and marks the import path as module.
174
175#### Path resolving
176
177If only the module name is given (e.g. `@import '~bootstrap'`) the importer looks in the `package.json` file of the module for the following keys: "sass", "scss", "style", "css", "main.sass", "main.scss", "main.style", "main.css" and "main". The first key that is found is used for resolving the path and importing the file into your sass code.
178
179To load only a certain file from a module you can specify the file in the import url (e.g. `@import '~bootstrap/scss/_alert.scss'`). The `node-sass-magic-importer` also supports partial file name resolving so you can import files by only specifying their base name without prefix and extension (e.g. `@import '~bootstrap/scss/alert'`). Sadly bootstrap and most other frameworks do not load their dependencies directly in the concerned files. So you have to load all dependencies of a file manually like in the example above. I recommend you to do better and to import dependencies directly in the files that are using them.
180
181### Globbing
182
183Globbing allows pattern matching operators to be used to match multiple files at once.
184
185```scss
186// Import all files inside the `scss` directory and subdirectories.
187@import: 'scss/**/*.scss';
188```
189
190## Usage
191
192```js
193var sass = require('node-sass');
194var magicImporter = require('node-sass-magic-importer');
195
196sass.render({
197 ...
198 importer: magicImporter()
199 ...
200});
201```
202
203### Options
204
205```js
206const sass = require('node-sass');
207const magicImporter = require('node-sass-magic-importer');
208
209const options = {
210 // Defines the path in which your node_modules directory is found.
211 cwd: process.cwd(),
212 // Define the package.json keys and in which order to search for them.
213 packageKeys: [
214 'sass',
215 'scss',
216 'style',
217 'css',
218 'main.sass',
219 'main.scss',
220 'main.style',
221 'main.css',
222 'main'
223 ],
224 // You can set the special character for indicating a module resolution.
225 packagePrefix: '~',
226 // Disable console warnings.
227 disableWarnings: false,
228 // Disable importing files only once.
229 disableImportOnce: false,
230 // Add custom node filters.
231 customFilters: undefined
232};
233
234sass.render({
235 ...
236 importer: magicImporter(options)
237 ...
238});
239```
240
241#### Custom filters
242
243```js
244const sass = require('node-sass');
245const magicImporter = require('node-sass-magic-importer');
246
247const options = {
248 customFilters: {
249 // Add a node filter for a specific min-width media query.
250 customMediaWidth: [
251 [
252 { property: 'type', value: 'atrule' },
253 { property: 'name', value: 'media' },
254 { property: 'params', value:'(min-width: 42em)' }
255 ]
256 ],
257 // Add a node filter for print media queries.
258 customMediaPrint: [
259 [
260 { property: 'type', value: 'atrule' },
261 { property: 'name', value: 'media' },
262 { property: 'params', value: 'print' }
263 ]
264 ]
265 }
266};
267
268sass.render({
269 ...
270 importer: magicImporter(options)
271 ...
272});
273```
274
275```scss
276// Sass file which implements filter importing.
277@import '[custom-media-width, custom-media-print] from file/with/at/rules';
278```
279
280```scss
281// file/with/at/_rules.scss
282@media (min-width: 42em) {
283 .custom-1-mq {
284 content: 'Custom 1 mq';
285 }
286}
287
288@media (min-width: 43em) {
289 .custom-2-mq {
290 content: 'Custom 1 mq';
291 }
292}
293
294@media print {
295 .custom-print-mq {
296 content: 'Custom print mq';
297 }
298}
299```
300
301```scss
302// CSS output – the `min-width: 43em` media query gets not imported.
303@media (min-width: 42em) {
304 .custom-1-mq {
305 content: 'Custom 1 mq';
306 }
307}
308
309@media print {
310 .custom-print-mq {
311 content: 'Custom print mq';
312 }
313}
314```
315
316### webpack
317
318```js
319// webpack.config.js
320const magicImporter = require('node-sass-magic-importer');
321const MiniCssExtractPlugin = require('mini-css-extract-plugin');
322
323module.exports = {
324 module: {
325 rules: [
326 {
327 test: /\.scss$/,
328 use: [
329 {
330 loader: MiniCssExtractPlugin.loader,
331 },
332 {
333 loader: 'css-loader'
334 },
335 {
336 loader: 'sass-loader',
337 options: {
338 sassOptions: {
339 importer: magicImporter()
340 }
341 }
342 }
343 ]
344 }
345 ]
346 },
347 plugins: [
348 new MiniCssExtractPlugin({
349 filename: 'style.css'
350 })
351 ]
352}
353```
354
355### Gulp
356
357```js
358const gulp = require('gulp');
359const sass = require('gulp-sass');
360const magicImporter = require('node-sass-magic-importer');
361
362gulp.task('sass', function () {
363 return gulp.src('./**/*.scss')
364 .pipe(sass({ importer: magicImporter() }).on('error', sass.logError))
365 .pipe(gulp.dest('./css'));
366});
367```
368
369### CLI
370
371```bash
372node-sass --importer node_modules/node-sass-magic-importer/dist/cli.js -o dist src/index.scss
373```
374
375## Upgrade from 4.x.x to 5.x.x
376
377- It is not possible anymore to set the `includePaths` option when initializing the importer. Use the [node-sass includePaths option](https://github.com/sass/node-sass#includepaths) instead.
378- The `prefix` option was renamed to `packagePrefix`.
379
380## Known issues
381
382### Multi level filtering
383
384Node filtering and selector filtering goes only one level deep. This means, if you're importing a file with selector or node filtering which is importing other files, those files are not filtered but imported as is. On a technical level, there is no good solution for this problem. One possibility would be to just pass the filters to all imports in the line but this carries the risk of filtering selectors or nodes on which one of the imported files might depend and therefore break the import. I might add this as an optional feature (which can be activated on demand) in the future – let me know if you're interested in multi level filter imports.
385
386## About
387
388### Author
389
390Markus Oberlehner
391Website: https://markus.oberlehner.net
392Twitter: https://twitter.com/MaOberlehner
393PayPal.me: https://paypal.me/maoberlehner
394Patreon: https://www.patreon.com/maoberlehner
395
396### License
397
398MIT