Giter Club home page Giter Club logo

sass-extract-js's Introduction

sass-extract-js

npm

Plugin for sass-extract to convert Sass global variables into a plain JS object.

Huh? Why?

I work on a team that uses Sass. We've got a shared variables file that gets referenced throughout our styleguide and in our components. I wanted to start using styled-components in some projects and wanted to keep things consistent but I didn't want to have to copy our Sass variables over. Using this plugin with sass-extract, I can simply extract the global variables from our Sass stylesheet and they will be converted into a JS object that gets passed down to my components via styled-components' <ThemeProvider>.

Cool! How do I get it?

You'll need to install sass-extract, sass-extract-loader, node-sass, and this plugin.

$ yarn add sass-extract sass-extract-loader node-sass sass-extract-js

(npm install works too)

Nice! How do I use it?

Assuming you're using webpack, you'll need to use sass-extract-loader to require/transform your sass variables file. Then you can pass the styles as a theme via a ThemeProvider component like this:

// Require your sass variables using sass-extract-loader and specify the plugin
const theme = require('sass-extract-loader?{"plugins":["sass-extract-js"]}!./path/to/vars.scss');

// Pass the vars into your ThemeProvider component
render(
  <ThemeProvider theme={theme}>
    <App />
  </ThemeProvider>
);

Then use themes in your styled components:

import styled from 'styled-components';

const Button = styled.button`
  background-color: ${p => p.theme.primary}
`;

Sweet! What does the output look like?

Given a Sass file with some global variable declarations:

$primary: rgb(255, 202, 77);
$seondary: #1A93C8;
$primary-light: lighten($primary, 20%);
$base-padding: 10px;
$base-margin: 0 1em;
$base-border: 1px solid #ccc;
$font-family-sans: 'Helvetica', 'Arial', sans-serif;
$base-font-size: 16px;
$line-height: $base-font-size * 1.8;

It will yield the following object:

{
  primary: 'rgb(255, 202, 77)',
  seondary: 'rgb(26, 147, 200)',
  primaryLight: 'rgb(255, 232, 179)',
  basePadding: '10px',
  baseMargin: '0 1em',
  baseBorder: '1px solid rgb(204, 204, 204)',
  fontFamilySans: '\'Helvetica\', \'Arial\', sans-serif',
  baseFontSize: '16px',
  lineHeight: '28.8px'
}

Right on! But I need options.

Everybody loves options and we've got one:

Option Name Default Description
camelCase true Should SASS variable names be converted to camelCase

Options Usage

sass-extract Plugin Options

As of sass-extract 2.0.0, options can be passed to plugins. Here's how:

const rendered = sassExtract.renderSync({
  file: './path/to/vars.scss'
}, {
  plugins: [{ plugin: 'sass-extract-js', options: { camelCase: false } }]
});

Plugin Instance

You can also create a plugin instance with your desired options and pass the instance directly inside the plugins array.

// Import the plugin factory directly
import createSassExtractJsPlugin from 'sass-extract-js/lib/plugin';

// Create a plugin instance, passing in your options
const sassExtractJsPlugin = createSassExtractJsPlugin({ camelCase: false });

// Call the `renderSync` function with the path to your Sass file
// and pass the plugin instance in the plugins array
const rendered = sassExtract.renderSync({
  file: './path/to/vars.scss'
}, {
  plugins: [sassExtractJsPlugin]
});

Using transformVars directly

If, for some reason, you don't want to use this package as a sass-extract plugin, you can import the transformVars function directly and use it. This is the main function that gets called in sass-extract's plugin pipeline. It expects as its input an object with extracted SASS variables, as generated by sass-extract. The function also accepts an options object.

// Import the transformVars method directly
import transformVars from 'sass-extract-js/lib/transformVars';

// Call the function, passing in your options
const transformed = transformVars(objectWithExtractedStyles, { camelCase: false });

Wait! What if I don't use styled-components?

No problem! I made this so I could use the extracted JS object as a theme but it's not specific to styled-components. It should work the same with glamorous too. Really you can use this plugin for any scenario where you need to convert Sass vars to JS.

Help! It's not working for me.

This project is open source. I've tried to make sure it works for a lot of use cases (read: mine) but if I missed yours, feel free to open an issue. Better yet, submit a PR! Seriously, any feedback and help is welcome.

License

MIT

sass-extract-js's People

Contributors

adamgruber avatar marksy avatar shinytang6 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

sass-extract-js's Issues

Include separate export for transformStyles method

It may be useful for some to be able to use this package outside the confines of a plugin. Exporting/bundling the transformStyles method separately would allow users to include it like this:

import transformStyles from 'sass-extract-js/transformStyles'

CLI

Would be useful to have a CLI as follows:

sass-extract-js ./path/to/scss ./path/to/output

Or perhaps a separate project that provided the CLI.

Specify to not convert keys when used through sass-extract-loader

I'm currently using this in this form but its creating a dictionary of camel case keys.
How could I tell it to keep the variables case "as is" the same way they are defined in the sass file (which are mostly kebab case in this case).

const importedVars = require('sass-extract-loader?{"plugins": ["sass-extract-js"]}!./../styles/scss/');

Thank you!

Dependency issue

I have this:

import React from "react";
import ReactDOM from "react-dom";
import { renderSync } from 'sass-extract';

const theme = renderSync(
    { file: './theme.scss' },
    { plugins: ['sass-extract-js'] }
).vars;

My theme.scss file exists and just has one variable defined in it. When I try to start my project I get this:

./node_modules/node-sass/lib/binding.js
19:9-37 Critical dependency: the request of a dependency is an expression

./node_modules/sass-extract/lib/pluggable.js
52:17-32 Critical dependency: the request of a dependency is an expression

This seems to happen with sass-extract version 2 and 1.0.1.

Am I missing something? Any help or assistance would be much appreciated!

DeprecationWarning: Module Chunks

I'm getting the following warning/error when parsing a bootstrap _variable.scss file. My setup is it's based on next.js

 ERROR  Failed to compile with 5 errors

This dependency was not found:

* fs in ./node_modules/mkdirp/index.js, ./node_modules/node-sass/lib/extensions.js and 3 others

To install it, you can run: npm install --save fs
(node:9903) DeprecationWarning: Module.chunks: Use Module.forEachChunk/mapChunks/getNumberOfChunks/isInChunk/addChunk/removeChunk instead

I'm not really whether if is related to this specific module or the sass-extract module, so I raised the same issue there.

Jest = Can not find module

Hello,

I have a problem with Jest, when I run a test I have this error:

Cannot find module 'sass-extract-loader?{"plugins": ["sass-extract-js"]}!./theme/variables.scss' from 'index.tsx'

My code :

const theme = require('sass-extract-loader?{"plugins": ["sass-extract-js"]}!./theme/variables.scss')

ReactDOM.render(
  <ThemeProvider theme={theme}>
    ...
  </ThemeProvider>
)

Add an option to skip camel casing keys

The default behavior of this plugin is to camelCase variable keys during the transform.

$my-variable-name: 10px //=> myVariableName: '10px'

This may be undesirable for some so an option to skip this part of the transform would be a good idea.

Suggestions for Refactor

I had a use case which called for pulling in SASS variables from a design system to populate the "knob" options in a storybook app for a component library I authored. After trying out sass-extract I started writing a parser for the SASS AST when I stumbled across this library. After trying out the lib a few things jumped out at me.

It seems strange to bundle this as a webpack plugin since it has a hard dependency on sass-extract not sass-extract-loader. If this was bundled to only export transformStyles it might provide more utility to the community.

Also, the remapping of map keys to camelCase is lossy and prevents keys from being used in meaningful way such as populating the dropdown "knob" options for component libraries using storybook.

Include doc comments

I find this plugin great for documentation purposes (used in Storybook pages). Would it be possible to somehow add doc comments found in the preceding lines? Eg:
Screenshot 2020-11-15 at 16 02 32
So object for this variable would also include {... comments: ['Color for emphasized texts']}
This would enable us to keep documentation together with code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.