项目作者: codebymikey

项目描述 :
A conditional/dynamic importer for node-sass.
高级语言: JavaScript
项目地址: git://github.com/codebymikey/node-sass-conditional-importer.git
创建时间: 2020-11-16T19:06:42Z
项目社区:https://github.com/codebymikey/node-sass-conditional-importer

开源协议:MIT License

下载


node-sass-conditional-importer

A conditional/dynamic importer for node-sass. It provides the ability to @import Sass files dynamically based on
their (environment) extension prefix, similar to React Native’s
platform-specific extensions behaviour.

npm
Codecov Coverage
Release

It reads in a list of environments extension prefixes, which it’ll attempt to use over the default file.

The example use case for this importer is as follows, say you have the following folder structure:

  1. scss
  2. ├── custom
  3. ├── style.custom.scss
  4. ├── style.development.scss
  5. ├── style.production.scss
  6. └── style.scss
  7. └── main.scss

And you want to import a different version of style.scss based on a given build environment/variable.
This is not currently possible easily because Sass does not allow dynamic @imports
using interpolation or in if statements.

This importer allows you to simply pass in your current environment into the importer, and it checks
for whether the environment-specific override file exists before importing it.

The environments will be a list of environments ordered by the priority with which they should be used.

If none of the environment file overrides are available, then it falls back to the original file.

Usage

Configuration options

  • environments: An array of environment extensions to look up. e.g.
    1. // process.env.NODE_ENV = 'production';
    2. // Look for [`${file}.production.scss`, `${file}.fallback.scss`]
    3. [process.env.NODE_ENV, 'fallback']

node-sass

This module hooks into node-sass’s importer api.

  1. var sass = require('node-sass');
  2. var conditionalImporter = require('node-sass-conditional-importer');
  3. sass.render({
  4. file: scssFilename,
  5. importer: [
  6. conditionalImporter({
  7. environments: [
  8. // Search for `*.custom.scss` files first,
  9. // Followed `*.(development|production).scss` files.
  10. 'custom',
  11. process.env.NODE_ENV,
  12. ],
  13. }),
  14. // .. other importers
  15. ],
  16. }, function(err, result) { /*...*/ });

Webpack / sass-loader

Webpack v1

  1. import conditionalImporter from 'node-sass-conditional-importer';
  2. // Webpack config
  3. export default {
  4. module: {
  5. loaders: [{
  6. test: /\.scss$/,
  7. loaders: ['style', 'css', 'sass']
  8. }],
  9. },
  10. sassLoader: {
  11. importer: conditionalImporter({
  12. environments: [
  13. // Import based on the NODE_ENV environment variable.
  14. process.env.NODE_ENV,
  15. ],
  16. })
  17. }
  18. };

Webpack v2

  1. import conditionalImporter from 'node-sass-conditional-importer';
  2. // Webpack config
  3. export default {
  4. module: {
  5. rules: [
  6. {
  7. test: /\.scss$/,
  8. use: [
  9. 'style-loader',
  10. {
  11. loader: 'css-loader',
  12. options: {
  13. importLoaders: 1
  14. },
  15. },
  16. {
  17. loader: 'sass-loader',
  18. options: {
  19. importer: conditionalImporter({
  20. environments: [
  21. // Import based on the NODE_ENV environment variable.
  22. process.env.NODE_ENV,
  23. ],
  24. }),
  25. },
  26. },
  27. ],
  28. },
  29. ],
  30. },
  31. };

Custom resolver

Should you care to resolve paths using some kind of custom logic, for example,
resolving ~/ relative to the project root or some other arbitrary directory,
you can do it using the following:

main.scss:

  1. @import '~/dynamic.scss';
  2. body {
  3. background: $background;
  4. }

custom/dynamic.myenvironment.scss:

  1. $background: red;
  1. var path = require('path');
  2. var sass = require('node-sass');
  3. var conditionalImporter = require('node-sass-conditional-importer');
  4. sass.render({
  5. file: './main.scss',
  6. importer: [
  7. conditionalImporter({
  8. environments: ['myenvironment'],
  9. resolver: function(dir, url) {
  10. return url.startsWith('~/')
  11. ? path.resolve(dir, 'custom', url.substr(2))
  12. : path.resolve(dir, url);
  13. },
  14. })
  15. ],
  16. }, function(err, result) { console.log(err || result.css.toString()) });

Known issues

  • With a folder structure like:

    1. scss
    2. ├── custom
    3. ├── style.custom.scss
    4. ├── style.development.scss
    5. ├── style.production.scss
    6. └── style.scss
    7. └── main.scss

    A file like style.production.scss may not be used to import style.scss as it’ll result in an import loop.

    The recommended solution is to create a shared include file like _style--shared.scss and import that instead.

Thanks to

This importer is inspired by node-sass-json-importer.

📄 License

node-sass-conditional-importer is MIT licensed, as found in the LICENSE file.