Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/wessberg/sass-extended-importer

A Custom Sass Import Resolver with included support for Node Module Resolution and additional file extensions
https://github.com/wessberg/sass-extended-importer

algorithm css import importer node-module-resolution resolve sass scss

Last synced: 2 months ago
JSON representation

A Custom Sass Import Resolver with included support for Node Module Resolution and additional file extensions

Awesome Lists containing this project

README

        

Logo

> A Custom Sass Import Resolver with included support for Node Module Resolution, additional file extensions, and path aliases/path mapping

Downloads per month
NPM version
Dependencies
Contributors
code style: prettier
License: MIT
Support on Patreon

## Description

This is an implementation of the [Sass Import Resolve algorithm](https://github.com/sass/dart-sass/blob/0f7f9e69a72e612412b51bfa2fe1384f778e2821/lib/src/importer/utils.dart), with added support for [Node Module Resolution](https://nodejs.org/api/modules.html#modules_all_together), and path mapping/path aliasing.

At the moment, without this Custom importer, to import files via Node Module Resolution, Sass library creators and consumers can:

- Ship `.scss`, `.sass`, or `.css` files via `node_modules`, and let consumers depend on files directly, - but not support hoisted dependencies/monorepos.
- Use [`Eyeglass`](https://github.com/sass-eyeglass/eyeglass)

One major use case for this library is to support path mapping, which can be useful for many things, includiong simplifying import paths or dividing packages in a monorepo.

This implementation follows the convention of existing tooling and similar solutions that paths with a leading `~` will be resolved via [Node Module Resolution](https://nodejs.org/api/modules.html#modules_all_together).

### Features

## Backers

[Become a sponsor/backer](https://github.com/wessberg/sass-extended-importer?sponsor=1) and get your logo listed here.

| Trent Raymond | scrubtheweb |
| -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Trent Raymond](https://changelog.me) | [scrubtheweb](https://scrubtheweb.com/computers/programming/1) |

### Patreon

Patrons on Patreon

## Table of Contents

- [Description](#description)
- [Features](#features)
- [Backers](#backers)
- [Patreon](#patreon)
- [Table of Contents](#table-of-contents)
- [Install](#install)
- [npm](#npm)
- [Yarn](#yarn)
- [pnpm](#pnpm)
- [Usage](#usage)
- [Usage with sass](#usage-with-sass)
- [Usage with node-sass](#usage-with-node-sass)
- [Resolving files within Node Modules](#resolving-files-within-node-modules)
- [Customizing the prefix](#customizing-the-prefix)
- [Path mapping/aliasing](#path-mappingaliasing)
- [Adjusting allowed extensions](#adjusting-allowed-extensions)
- [Customizing the file system](#customizing-the-file-system)
- [Usage with other tools and libraries](#usage-with-other-tools-and-libraries)
- [Contributing](#contributing)
- [Maintainers](#maintainers)
- [FAQ](#faq)
- [License](#license)

## Install

### npm

```
$ npm install sass-extended-importer --save-dev
```

### Yarn

```
$ yarn add sass-extended-importer --dev
```

### pnpm

```
$ pnpm add sass-extended-importer --save-dev
```

## Usage

### Usage with sass

To use it with the primary [`sass`](https://github.com/sass/dart-sass) package (dart-sass), simply import the `createImporter` function from this package and invoke it with the options you want to provide.
Then pass it to `sass` is an import resolver:

```typescript
import {createImporter} from "sass-extended-importer";
import sass from "sass";

sass({
file: "/path/to/your/file.scss",
importer: createImporter({
// options
})
});
```

### Usage with node-sass

To use it with [`node-sass`](https://github.com/sass/node-sass), simply import the `createImporter` function from this package and invoke it with the options you want to provide.
Then pass it to `node-sass` is an import resolver:

```typescript
import {createImporter} from "sass-extended-importer";
import sass from "node-sass";

sass({
file: "/path/to/your/file.scss",
importer: createImporter({
// options
})
});
```

### Resolving files within Node Modules

Prefix the path with a `~` to indicate that the Node Module Resolution algorithm should be used:

```scss
@import "~my-library";
```

The resolve function will use [Node Module Resolution](https://nodejs.org/api/modules.html#modules_all_together) to find the library, and then look at the `main` property within the related `package.json` file.
If it points to a file, for example `index.js`, for which there is an identically named file with an extension of `.scss`, `.sass` , or `.css`, or if the `main`
property directly points to a file with a supported extension, that file will be resolved. Alternatively, if the main property is left out, it will default to looking for a file called `index` with one of the supported extensions directly within the package folder.

This means that all of the following examples will work:

```scss
// Uses the package.json file's main property to look for a file with a supported extension.
// Defaults to looking for a file named `index` with a supported extension
@import "~my-library";

// Specifically looks for a file called 'index' inside the package folder, with a supported extension
@import "~my-library/index";

// Specifically looks for a file with the filename `index.scss`
@import "~my-library/index.scss";

// Looks inside the /foo folder from the package folder and for a file called `bar` with a supported extension
// (or if bar is a folder, a file within it called `index` with a supported extension)
@import "~my-library/foo/bar";
```

#### Customizing the prefix

The default prefix of `~` (tilde) is a convention used by several popular tools and is the general recommendation. However, you can customize it with the `nodeModuleResolutionPrefix` option for the importer:

```typescript
import {createImporter} from "sass-extended-importer";
import sass from "sass";

sass({
// ...
importer: createImporter({
// Use # instead of ~
nodeModuleResolutionPrefix: "#"
})
});
```

### Path mapping/aliasing

You can use path mapping to map import paths to other import paths.
This can be useful to simplify import statements, or if you use sass/scss/css in combination with a build pipeline that performs path mapping on your other application- or library code.
For example, you might be using TypeScript's path mapping feature, and want to make sure the same paths are supported inside the sass/scss/css files you're importing from there.
You can customize it with the `paths` option for the importer:

```typescript
import {createImporter} from "sass-extended-importer";
import sass from "sass";

sass({
// ...
importer: createImporter({
paths: {
"my-alias": ["../other-folder/src/index.scss"],
"my-alias/*": ["../other-folder/src/*"]
}
})
});
```

This allows you do write styles such as:

```scss
@import "my-alias/foo";
```

Which will actually be mapped to `../other-folder/src/foo.scss`.

### Adjusting allowed extensions

You can alter what kind of extensions that can be resolved via the `extensions` option for the importer:

```typescript
import {createImporter} from "sass-extended-importer";
import sass from "sass";

sass({
// ...
importer: createImporter({
// Use # instead of ~
extensions: [".myextension", ".foo", ".bar"]
})
});
```

### Customizing the file system

If you use a virtual file system, such as one that exists within memory, you can pass it in as the `fileSystem` option for the importer. If you don't, it defaults to using the `fs` module:

```typescript
import {createImporter} from "sass-extended-importer";
import sass from "sass";
import path from "path";
import {createFsFromVolume, Volume} from "memfs";

const volume = new Volume();

vol.mkdirSync("/my/directory", {recursive: true});
vol.writeFileSync("/my/directory/foo.scss", "p {color: red}");
const fileSystem = createFsFromVolume(vol);

sass({
// ...
importer: createImporter({
// Use another file system
fileSystem
})
});
```

### Usage with other tools and libraries

The resolve algorithm implemented by this library is also exported as as helper function, `resolve`, that can be used outside of just as a Custom Importer for Sass.
To use it directly, simply import `resolve`:

```typescript
import {resolve} from "sass-extended-importer";

resolve("~my-library", {cwd: "/path/to/directory"});
```

## Contributing

Do you want to contribute? Awesome! Please follow [these recommendations](./CONTRIBUTING.md).

## Maintainers

| Frederik Wessberg |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Frederik Wessberg](mailto:[email protected])
Twitter: [@FredWessberg](https://twitter.com/FredWessberg)
Github: [@wessberg](https://github.com/wessberg)
_Lead Developer_ |

## FAQ

## License

MIT © [Frederik Wessberg](mailto:[email protected]) ([@FredWessberg](https://twitter.com/FredWessberg)) ([Website](https://github.com/wessberg))