npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

extract-stilr-webpack-plugin

v0.1.1

Published

Extract stilr stylesheets for production use.

Downloads

7

Readme

extract-stilr-webpack-plugin

This plugin works in two quite different ways.

If your entry point exports string property stilrStylesheet, this plugin writes that string into a file of your choice and removes that string from the final output of the JS file (i.e. exports.stilrStylesheet = 'blah'; will turn in to exports.stilrStylesheet = '';).

If your entry point does not export string property stilrStylesheet and exports property stilr, which is assumed to be what is exported by require('stilr'), then this plugin extracts the style rules that are observed in the initial state of the application into a file of your choice. The rules are vendor-prefixed, using Autoprefixer.

Example

Exports stilrStylesheet

Given the following files:

// webpack.config.js

var ExtractStilrPlugin = require('extract-stilr-webpack-plugin');

module.exports = {
  entry: {
    main: './entry' // Note this chunk's name is "main".
  },
  output: {
    path: __dirname + '/dist',
    filename: 'main.js',
    
    // output.libraryTarget MUST BE "umd"!
    // The reason is explained in the next file.
    // If output.libraryTarget is not "umd", this plugin will throw an Error and
    // refuse to run.
    libraryTarget: 'umd'
  },
  plugins: [
    new ExtractStilrPlugin({
      // options
      
      // options.chunkName has to match the name of the chunk that you want to
      // execute Stilr in and extract the rendered stylesheet.
      //
      // If you don't specify this option yourself, the default value is "main".
      chunkName: 'main',
      
      // options.filename defines the file name of the CSS file that is
      // generated.
      //
      // You can use two keywords.
      // [projname] will read in your project's package.json and replace itself
      // with the project name.
      // [hash] will replace itself with the hash of the CSS content.
      //
      // If you don't specify this option yourself, the default value is
      // "[projname].[hash].css".
      filename: '[projname].[hash].css'
    })
  ]
};
// entry.js

// The entry file of your target chunk MUST EXPORT property
// exports.stilrStylesheet, which must be a string.
//
// The plugin will move this string into the filename you specified in the
// webpack configuration.
//
// This is why `output.libraryTarget` has to be "umd" in your webpack config.
// In other library target modes, running the code in entry.js and then
// importing its exports doesn't work.
module.exports.stilrStylesheet = 'blah';

You'll get the following CSS file in your output directory when you run webpack:

/* YourProjName.98v2va09f3j0afw3f.css */

blah

and the following JS file:

// entry.js

module.exports.stilrStylesheet = '';

Exports stilr and does not export stilrStylesheet

Given the following files:

// webpack.config.js

var ExtractStilrPlugin = require('extract-stilr-webpack-plugin');

module.exports = {
  entry: {
    main: './entry' // Note this chunk's name is "main".
  },
  output: {
    path: __dirname + '/dist',
    filename: 'main.js',
    
    // output.libraryTarget MUST BE "umd"!
    // The reason is explained in the next file.
    // If output.libraryTarget is not "umd", this plugin will throw an Error and
    // refuse to run.
    libraryTarget: 'umd'
  },
  plugins: [
    new ExtractStilrPlugin({
      // options
      
      // options.chunkName has to match the name of the chunk that you want to
      // execute Stilr in and extract the rendered stylesheet.
      //
      // If you don't specify this option yourself, the default value is "main".
      chunkName: 'main',
      
      // options.filename defines the file name of the CSS file that is
      // generated.
      //
      // You can use two keywords.
      // [projname] will read in your project's package.json and replace itself
      // with the project name.
      // [hash] will replace itself with the hash of the CSS content.
      //
      // If you don't specify this option yourself, the default value is
      // "[projname].[hash].css".
      filename: '[projname].[hash].css'
    })
  ]
};
// entry.js

var stilr = require('stilr');

stilr.create({
  testClass: {
    alignItems: 'center',
    color: '#a9f23e'
  }
});

// The entry file of your target chunk MUST EXPORT property exports.stilr, which
// must hold a reference to what is returned by `require('stilr')`.
//
// The plugin uses this reference to render the stylesheet.
//
// This is why `output.libraryTarget` has to be "umd" in your webpack config.
// In other library target modes, running the code in entry.js and then
// importing its exports doesn't work.
module.exports.stilr = stilr;

You'll get the following CSS file in your output directory when you run webpack:

/* YourProjName.v0q23f0q39jqp23fj0q.css */

._rEl7H{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;color:#a9f23e;}

What do you mean by "in the initial state of the application"?

This plugin works by actually running your application inside a VM. With that in mind, let's take a look at the following example app code.

class App extends React.Component {
  state = {
    showBlueText: false
  };
  render() {
    var styles = stilr.create({
      topDiv: {
        color: this.state.showBlueText ? 'blue' : 'black'
      }
    });
    return (
      <div
          className={styles.topDiv}
          onClick={() => this.setState({showBlueText: true})}>
        Text
      </div>
    );
  }
}

React.render(<App />, document.body);

In order for this code to work across both states (showBlueText === true and showBlueText === false), you would need to extract both styles: {color: blue;} and {color: black;}. But since this plugin works by running the code once in the initial application state, the state showBlueText === true is never reached, and therefore the style {color: blue;} is never extracted. So the text won't appear blue after being clicked, because of the way this plugin works.

How can we fix that code to make it work with this plugin then? The simple, easy answer is to use style instead of className:

<div style={color: this.state.showBlueText ? 'blue' : 'black'}

This approach works for simple cases such as when all you're defining is color. But what if your style definition were more complex and you wanted to take advantages that this plugin provides: vendor prefixing, faster page rendition, etc.? In this case, what you should do is to define in advance your styles for all possible states:

render() {
  var styles = stilr.create({
    topDiv_blueText: {
      color: 'blue'
    },
    topDiv_noBlueText: {
      color: 'black'
    }
  });
  return (
    <div
        className={this.state.showBlueText ?
          styles.topDiv_blueText : styles.topDiv_noBlueText}
        onClick={() => this.setState({showBlueText: true})}>
      Text
    </div>
  );
}