Git Product home page Git Product logo

postcss-modules's Introduction

postcss-modules

A PostCSS plugin to use CSS Modules everywhere. Not only at the client side.

What is this?

For example, you have the following CSS:

/* styles.css */
:global .page {
	padding: 20px;
}

.title {
	composes: title from "./mixins.css";
	color: green;
}

.article {
	font-size: 16px;
}

/* mixins.css */
.title {
	color: black;
	font-size: 40px;
}

.title:hover {
	color: red;
}

After the transformation it will become like this:

._title_116zl_1 {
	color: black;
	font-size: 40px;
}

._title_116zl_1:hover {
	color: red;
}

.page {
	padding: 20px;
}

._title_xkpkl_5 {
	color: green;
}

._article_xkpkl_10 {
	font-size: 16px;
}

And the plugin will give you a JSON object for transformed classes:

{
	"title": "_title_xkpkl_5 _title_116zl_1",
	"article": "_article_xkpkl_10"
}

Usage

Saving exported classes

By default, a JSON file with exported classes will be placed next to corresponding CSS. But you have a freedom to make everything you want with exported classes, just use the getJSON callback. For example, save data about classes into a corresponding JSON file:

postcss([
	require("postcss-modules")({
		getJSON: function (cssFileName, json, outputFileName) {
			var path = require("path");
			var cssName = path.basename(cssFileName, ".css");
			var jsonFileName = path.resolve("./build/" + cssName + ".json");
			fs.writeFileSync(jsonFileName, JSON.stringify(json));
		},
	}),
]);

getJSON may also return a Promise.

Generating scoped names

By default, the plugin assumes that all the classes are local. You can change this behaviour using the scopeBehaviour option:

postcss([
	require("postcss-modules")({
		scopeBehaviour: "global", // can be 'global' or 'local',
	}),
]);

To define paths for global modules, use the globalModulePaths option. It is an array with regular expressions defining the paths:

postcss([
  require('postcss-modules')({
    globalModulePaths: [/path\/to\/legacy-styles/, /another\/paths/],
  });
]);

To generate custom classes, use the generateScopedName callback:

postcss([
	require("postcss-modules")({
		generateScopedName: function (name, filename, css) {
			var path = require("path");
			var i = css.indexOf("." + name);
			var line = css.substr(0, i).split(/[\r\n]/).length;
			var file = path.basename(filename, ".css");

			return "_" + file + "_" + line + "_" + name;
		},
	}),
]);

Or just pass an interpolated string to the generateScopedName option (More details here):

postcss([
	require("postcss-modules")({
		generateScopedName: "[name]__[local]___[hash:base64:5]",
	}),
]);

It's possible to add custom hash to generate more unique classes using the hashPrefix option (like in css-loader):

postcss([
	require("postcss-modules")({
		generateScopedName: "[name]__[local]___[hash:base64:5]",
		hashPrefix: "prefix",
	}),
]);

Exporting globals

If you need to export global names via the JSON object along with the local ones, add the exportGlobals option:

postcss([
	require("postcss-modules")({
		exportGlobals: true,
	}),
]);

Loading source files

If you need, you can pass a custom loader (see FileSystemLoader for example):

postcss([
	require("postcss-modules")({
		Loader: CustomLoader,
	}),
]);

You can also pass any needed root path:

postcss([
  require('postcss-modules')({
    root: 'C:\\',
  });
]);

localsConvention

Type: String | (originalClassName: string, generatedClassName: string, inputFile: string) => className: string Default: null

Style of exported classnames, the keys in your json.

Name Type Description
'camelCase' {String} Class names will be camelized, the original class name will not to be removed from the locals
'camelCaseOnly' {String} Class names will be camelized, the original class name will be removed from the locals
'dashes' {String} Only dashes in class names will be camelized
'dashesOnly' {String} Dashes in class names will be camelized, the original class name will be removed from the locals

In lieu of a string, a custom function can generate the exported class names.

Resolve path alias

You can rewrite paths for composes/from by using the resolve option. It's useful when you need to resolve custom path alias.

Parameters:

  • file — a module we want to resolve
  • importer — the file that imports the module we want to resolve

Return value: string | null | Promise<string | null>

postcss([
	require("postcss-modules")({
    	resolve: function (file, importer) {
			return path.resolve(
				path.dirname(importer),
				file.replace(/^@/, process.cwd()
			);
    	},
  	}),
]);

Integration with templates

The plugin only transforms CSS classes to CSS modules. But you probably want to integrate these CSS modules with your templates. Here are some examples.

Assume you've saved project's CSS modules in cssModules.json:

{
	"title": "_title_xkpkl_5 _title_116zl_1",
	"article": "_article_xkpkl_10"
}

Pug (ex-Jade)

Let's say you have a Pug template about.jade:

h1(class=css.title) postcss-modules
article(class=css.article) A PostCSS plugin to use CSS Modules everywhere

Render it:

var jade = require("jade");
var cssModules = require("./cssModules.json");
var html = jade.compileFile("about.jade")({ css: cssModules });
console.log(html);

And you'll get the following HTML:

<h1 class="_title_xkpkl_5 _title_116zl_1">postcss-modules</h1>
<article class="_article_xkpkl_10">
	A PostCSS plugin to use CSS Modules everywhere
</article>

HTML

For HTML transformation we'll use PostHTML and PostHTML CSS Modules:

npm install --save posthtml posthtml-css-modules

Here is our template about.html:

<h1 css-module="title">postcss-modules</h1>
<article css-module="article">
	A PostCSS plugin to use CSS Modules everywhere
</article>

Transform it:

var fs = require("fs");
var posthtml = require("posthtml");
var posthtmlCssModules = require("posthtml-css-modules");
var template = fs.readFileSync("./about.html", "utf8");

posthtml([posthtmlCssModules("./cssModules.json")])
	.process(template)
	.then(function (result) {
		console.log(result.html);
	});

(for using other build systems please check the documentation of PostHTML)

And you'll get the following HTML:

<h1 class="_title_xkpkl_5 _title_116zl_1">postcss-modules</h1>
<article class="_article_xkpkl_10">
	A PostCSS plugin to use CSS Modules everywhere
</article>

May I see the plugin in action?

Sure! Take a look at the example.

See PostCSS docs for examples for your environment and don't forget to run

npm install --save-dev postcss postcss-modules

Sponsors

  • Dmitry Olyenyov

postcss-modules's People

Contributors

7rulnik avatar akkuma avatar allocenx avatar drinfiniteexplorer avatar evilebottnawi avatar flying-sheep avatar foxygene avatar fxb avatar glenjamin avatar igor-ribeiro avatar jessethomson avatar joshwnj avatar jquense avatar kamilic avatar kingsora avatar ludofischer avatar lutien avatar madpilot avatar madyankin avatar maltsev avatar origin-master avatar partyka1 avatar pospi avatar sapphi-red avatar srolel avatar tjenkinson avatar trysound avatar yyx990803 avatar zaubernerd avatar zhouwenbin 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

postcss-modules's Issues

Using with nested classes

With given styles of a component:

.handle {
  width:          20px; 
  height:         20px;
  border-radius:  50%;

  background:     cyan;
}

I would like to specify how the .handle component with live inside .handle-parent class:

.handle-parent {
  // ..
  // some parent styles
  // ..

  .handle {
    position:    absolute;
    left:        50%;
  }

}

It doesn't work for me right now since .handle and .handle-parent .handle will obtain different hashes.
Any direction on how to solve the issue? Thanks!

CSS import are overwritten

Making some experiment I've found that getJSON is called only with the the last CSS imported file.

I created a CSS file with two included files, e.g.

@import './styles/first.css'
@import './styles/second.css'

And then I found that getJSON is only called with the mapped names corresponding to second.css. I tried only with the first import (first.css) and I got the mapping for it, but when I added the second.css then I got the mapping for the second.css meanwhile I expected to find all of them.

I also realised that filename received as first parameter in getJSON is always undefined at least for this specific scenario.

Can we get a minimal example?

I want to understand how to use post css having a string in memory and getting the json file back.

Input would be a string that is the css content, regardless of where it came form.
Output would be the json with the class name mappings.

I'm trying to capture the requrie of css files in node and produce the same class names as the webpack loader will produce when bundling a react application, so I can use the generated class names serverside.

Thanks!

Should this plugin inline @imports?

According to the CSS Modules documentation:

All URLs (url(...)) and @imports are in module request format (./xxx and ../xxx means relative, xxx and xxx/yyy means in modules folder, i. e. in node_modules).

I noticed that postcss-modules does not inline @import statements. Is this a bug, or should I be using postcss-import for this?

`postcss-import` config doesn't seem to work with `composes`

E.g. given config such as below... any composes: ... imports don't seem to be configurable to look in e.g. ['node_modules', 'app']

postcss: function(webpack) {
    return [
        require('postcss-import')({
            addDependencyTo: webpack,
            path: ['node_modules', 'app']
        }),
        require('postcss-assets')(),
        require('postcss-url')(),
        require('postcss-modules')(),
        require('postcss-nested')(),
        require('postcss-cssnext')(),
        require('postcss-browser-reporter')(),
        require('postcss-reporter')(),
    ]
},

As far as I can tell there are no config options for postcss-modules that allow this either as the code at https://github.com/outpunk/postcss-modules/blob/master/src/importModules.js#L27 seems to use it's own config anyway.

The error message I'm seeing is along the lines of:

Module build failed: Error: <css input>: Failed to find 'css/typography.css' from /Users/..../my-app
    in [
       /Users/..../my-app
    ]

For e.g.

.message {
    composes: strong from 'css/typography.css';
    composes: icon from 'icon-lib';
}

where 'typography.css' is in app/css/typography.css
and 'icon-lib' is in node_modules/icon-lib

can not work with nested css

For the case below,

.title {
    position: relative;

    &-content {
        position: absolute;
    }
}

it can only generate title related className but title-content.
For setting, I put postcss-modules after postcss-nesting and postcss-nested

Track changes to original class/id names in source-maps?

Feature Request: It'd be great to see the original class/id name in dev tools for easier lookup. I hash all my classes, so class name's like .logo become .A upon build. .A is also currently being used in the source-map and while the line number and file are correct (so it's easy enough to find) it'd be great to see the original class name here.

Should be a way to do not call all postcss processing.

At You get all plugins for later execution. In this case all postcss processing happen twice, and because of this sometimes with specific set of plugins css rulls appeared twice. I understand why this was done (to make imports work), but it could be easy fixed (iirc), just by moving postcss-modules to the end of plugins array.
Easy reproducible example:

const postCssModules = require('postcss-modules');
const postCssAutoreset = require('postcss-autoreset');

const postcss = require('postcss');

const postCssPlugins = [
  postCssAutoreset,
  postCssModules({
    getJSON: function(cssFileName, json) {}
  }),
];

const css = `
.widget_editor {
  display: block;
}
`;

postcss(postCssPlugins)
    .process(css, { from: 'src/app.css', to: 'app.css' })
    .then(function(result) {
      console.log('RESULT', result.css)
    })

You will something like this:

._widget_editor_1w0o5_2,
._widget_editor_1w0o5_2 {
  all: initial;
}
._widget_editor_1w0o5_2 {
  all: initial;
}
._widget_editor_1w0o5_2 {
  display: block;
}

composes providing undefined classname in output json

I'm trying to use composes in my css file with the postcss-modules plugin but the outputted json for tabpanel.css.json includes an undefined class name rather than the button class name I am expecting.

Input tabpanel/tabPanel.css

.tabPanelTab {
	composes: button from "../button/button.css";
	display: inline-block;
	margin: 0;
	border: none;
	border-right: 1px solid black;
}

Input button/button/.css

.button {
	background: red;
	padding: 10px;
	border: 1px solid black;
}

.button:hover {
	background: green;
}

Output tabpanel/tabPanel.css

.button__button__button__3sp2V__1btJf {
	background: red;
	padding: 10px;
	border: 1px solid black;
}
.button__button__button__3sp2V__1btJf:hover {
	background: green;
}
.tabpanel__tabPanelTab__2e0ic {
	display: inline-block;
	margin: 0;
	border: none;
	border-right: 1px solid black;
}

Output tabpanel/tabPanel.css.json JSON

{"tabPanelTab":"tabpanel__tabPanelTab__2e0ic undefined"}

I am using the latest grunt-postcss version along with the latest postcss-modules version.
My grunt config is as follows:

	postcss: {
			options: {
				map: true,
				processors: [
					require('postcss-modules')({
						generateScopedName: '[name]__[local]__[hash:base64:5]'
					})
				]
			},
			dist: {
				files: [ {
					expand: true,
					src: 'dist/umd/**/*.css'
				} ]
			}
		}

** EDIT **
If I manually specify the file order to load the tabPanel.css before button.css the outputted json is as expected. It appears that the reference to the class is lost once the file that is being imported via composes is processed by postCss.

Pug (Jade) better example

Is there better example with Pug(jade), actually how can i use postcss-modules with express, json will be generated but how can i add generated classes to pug?

Doesn't work with other postcss plugins?

I've been trying to add this plugin to a postcss build I've been playing with. I've got it all setup and configured and the build works great with autoprefixer and cssnano. When I add in postcss-modules, everything appears to run fine... but no files are generated and no errors are given.

Here's a gist of my css.js build file. If I add cssmodules to the array on Line 31 it fails silently. If I remove it, it works fine.

Any ideas? Does PostCSS-Modules work with other plugins? Is it a sourcemap issue?

How to use it with css files concat?

/* button.css */
.button { background: grey; }

/* login-button.css */
.login-button {
  composes: button from "button.css";
  background: green;
}

/* logout-button.css */
.logout-button {
  composes: button from "button.css";
  background: red;
}
return gulp.src('**/*.css')
    .pipe(gulpPostcss([
        postcssModules({
            getJSON: saveCssModulesJson
        })
    ]))
    .pipe(gulpConcat('bundle.css'))
._button_aaa {
    background: grey;
}

._login-button_bbb {
    background: green;
}

._button_aaa {
    background: grey;
}

._logout-button_ccc {
    background: red;
}
<button class="_login-button_bbb _button_aaa">Login</button>
<button class="_logout-button_ccc _button_aaa">Logout</button>

Logout button works as expected (red background). But login doesn't: second ._button_aaa selector overrides ._login-button_bbb's background. And login-button has grey background.

Any suggestions?

getJSON and generateScopedName does not work together

I would like to prefix my class names with a constant name. Therefor no JSON need to be exported.

.pipe(postcss([
   modules(
       {
         getJSON: ()=> {
            return;
         }
      }, {generateScopedName: `${data.PROD_CLASS_PREFIX}[local]`}
   ),
]))

This generates no JSON, but the classnames will random pre- or postfixed.

Version for Webpack?

Do you have it as Webpack -loader? If you do, how to use it for both server side and client side rendering in one project?

Doubts in integrating it in other PostCSS plugins

While developing postcss-color-mod as an experiment, I believe I have surfaced an issue in integrating css-modules and uniqueness in other PostCSS plugins.

In postcss-color-mod I had 2 different integration requirements:

  1. I have some cases where I need to create unique names for CSS Custom Properties (aka Variables) so that they never collide;
  2. make sure that naming follows the rules specified by the user for CSS Modules.

If you see at this line I’m accessing Core.scope.generateScopedName from css-modules-loader-core. But his looks brittle because it’s not documented (I copied it by your own usage in the CSS Modules PostCSS plugin) and in the future you could (rightfully!) remove it without notice.

What do you think?

Feature Request: Whitelist classes

It would be great if there would be an option to specify an whitelist for classes.
I got some classes like in my JavaScript like is-active which I use in my CSS as well.
Unfortunately this will break when using postcss-modules with EJS

using composes brings in every style/class definition

if my _typography.css has 100 lines

and then I have a button.css file like so:

.h1{
composes: largest from _typography.css;
}

why does the compiled stylesheet have all 100 lines from _typography.css
when I only needed it to compose 1 style?

am I using or misunderstanding how to use 'composes' correctly?

Cant get json data when i import css file in js code

When i use css-modules, if i use import keyword to load css style file, i will get a json object, it includes the map of className.

import "bootstrap/dist/js/bootstrap.js"
import bootstrapStyle from "bootstrap/dist/css/bootstrap.css"
import appStyle from "app/css/styles.css"
console.log(appStyle); // i can get json data here
export default {
    data: function () {
        return {
            style: this.setStyle(bootstrapStyle, appStyle)
        }
    }
}

this is my webpack config, i use vue.js :)

var webpack = require("webpack");
var ExtractTextPlugin = require("extract-text-webpack-plugin");

var node_lib_dir = __dirname + '/node_modules/';
var app_lib_dir = __dirname + '/static/';

module.exports = {
    debug: true,

    entry: {
        app: './src/main.js',

        vendor: [
            'jquery',
            'bootstrap',
            'jquery_ui',
            'datatables',
            'datatables_bootstrap',
            'tinymce/tinymce'
        ]
    },

    output: {
        path: __dirname + '/build',
        publicPath:"/build",
        filename: 'js/[name].bundle.js',
        chunkFilename: "js/[id].js"
    },

    module: {
        loaders: [
            {
                test: /\.vue$/, // a regex for matching all files that end in `.vue`
                loader: 'vue'   // loader to use for matched files
            },
            {
                test: /\.js$/,
                loader: 'babel-loader', // Enable es6 support by babels
                exclude: /node_modules\//
            },
            // {
            //     test: /\.css$/,
            //     loader: 'style-loader!css-loader'
            // },
            // // Todo has issue, cant load split css file
            {
                test: /\.css$/,
                loader: ExtractTextPlugin.extract(
                    "style-loader",
                    "css-loader!postcss-loader"
                )
            },
            {
                test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
                loader: 'file-loader?name=resource/[name].[ext]'
            },
            {
                test: /\.(png|jpg|gif)$/,
                loader: 'url-loader?prefix=resource/&limit=8192'
            },
            {
                test: require.resolve('tinymce/tinymce'),
                loaders: [
                    'imports?this=>window',
                    'exports?window.tinymce'
                ]
            },
            {
            test: /tinymce\/(themes|plugins)\//,
                loaders: [
                    'imports?this=>window'
                ]
            }
        ]
    },

    postcss: [
        require('postcss-modules') ({
            scopeBehaviour: 'local',
            generateScopedName: '[name]__[local]___[hash:base64:5]'
        })
    ],

    // vue: {
    //     loaders: {
    //         css: ExtractTextPlugin.extract(
    //             "style-loader",
    //             "css-loader?modules&-url&localIdentName=[name]__[local]___[hash:base64:5]"
    //         )
    //     }
    // },

    resolve: {
        alias: {
            app: app_lib_dir,
            bootstrap: node_lib_dir + "bootstrap",
            jquery: node_lib_dir + "jquery",
            jquery_ui: node_lib_dir + "jquery-ui",
            datatables: node_lib_dir + "datatables",
            datatables_bootstrap: node_lib_dir + "datatables-bootstrap"
        }
    },

    plugins: [
        new ExtractTextPlugin("css/[name].css"),

        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery",
            "window.jQuery": "jquery",
            "window.$": "jquery"
        }),

        new webpack.optimize.CommonsChunkPlugin({
            filename: "js/vendor.bundle.js",
            name: 'vendor'
        })
    ],

    babel: {
        presets: ['es2015'],
        plugins: ['transform-runtime']
    }
}

i really need get json data at runtime, are there some way to finish it?

Underscore and integer being appended to localIdentName.

I'm loving CSS Modules with Vue.js but am having an issue dealing with a static export for server side rendering. I've been using the following for my localIdentName in webpack config:

cssModules: { localIdentName: '[name]-[local]' },

However, all of my classnames are generating with an _0 at the end and I cannot figure out how to remove it. Any help would be greatly appreciated. Please refer to the attached image:

screen shot 2017-05-17 at 4 46 48 pm

es2015 export

babel6 uses exports default module value in property and this plugin can't work regular in node without es2015 modules support

require('postcss-moduels').default()

You can fix it by using regular module.exports in src/index.js

compatibility issues

Not sure what's going on.

Lack of documentation, lack of compatibility or I am just stupid.

I spend the entire day trying to get this plugin to work.

Here's a MVP of my attempt. https://github.com/pixelass/doesnt-work

Here's the integration:

https://github.com/pixelass/doesnt-work/blob/master/scripts/run-build.js#L75-L79

Look at the readme of that repo for a list of errors

Reference: (readme.md)

Look inside scripts/run-build L75

I added cssModules but it returns an error:

Your current PostCSS version is 5.1.2, but postcss-modules uses 5.2.15. Perhaps this is the source of the error below.
errorify: Error: ENOENT: no such file or directory, open '/src/hello-world/style.css.json' while parsing file: <PROJECT_FOLDER>/src/hello-world/style.css

If I overwrite the getJSON function and log the JSON I get an empty object.

Since the documentation of postcss-modules lacks information about compatibility and whagtnots I created this repo as a reference.

I have no idea why the error occurs. 'postcss-modules' is the only postcss plugin: https://github.com/pixelass/doesnt-work/blob/master/package.json#L59

Support: build time issue

This is more of a support question than an actual issue.

I wanted to adopt css modules, but without webpack, so I wanted to generate the json map to each file, which I could later use to reference the original classesnames.
Now, my original setup was to have a folder, in which there's only one main.less file, which includes everything else in the folder.
Only this main got compiled, which also imported dependencies (like bootstrap grid, variables, etc...)

In order to make css modules work, I need to run the compilation process for each file, and have the files @import their dependencies.
Then I would have the json for each file, and at the end I could just concatenate everything together.

Unfortunately as I suspected this significantly increased build times, from ~200ms to ~2s.

My question is whether there's a better solution to achieve the same?
Am I approaching the problem completely wrong?
Because as it is the impact on dev experience might be too great for me to adopt this otherwise great project. :/

Allow glob composes

This is a pretty big change and duplicates some work in postcss-easy-import (glob import). Maybe postcss-modules, postcss-import and postcss-easy-import should be merged (or based off one another) as postcss-modules is basically a class based @import with optional mapping to localized classes.

Consider

.title {
	composes: * from './prefix*.css';
}

composes: seems to convert relative path to absolute

apologies if I'm being stupid or this is a dupe of other issues referencing import stuff, but I'm bit stuck.

just trying to get the example running, and given the following:

  • node v6.5.0
  • postcss 5.2.0
  • postcss-modules 0.5.2
index.js
src
├── input.css
└── mixins.css
// index.js
const fs = require('fs');
const postcss = require('postcss');
const modules = require('postcss-modules');

(async () => {
    const moduled = await postcss([
        modules({
            getJSON: (cssFileName, json) => {
                console.log('module map\n', json);
            }
        })
    ]).process(fs.readFileSync('./src/input.css', 'utf8'));
    console.log('module CSS\n', moduled.css);
})();
/* src/input.css */
.x {
    composes: x from "./mixins.css";
}
/* src/mixins.css */
.x {
    color: black;
}

Whenever I run index.js, I keep getting:

{ Error: ENOENT: no such file or directory, open '/mixins.css'
    at Error (native)
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: '/mixins.css' }

"./mixins.css", "mixins.css" all error with '/mixins.css'. even "../src/mixins.css" errors with no such file or directory, open '/src/mixins.css'.

am I missing something?

how can you get globals on the exported object?

I don't see why globals can't be exported just like locals, thereby giving you a consistent API in your components, i.e. so you don't have to juggle between using keys on a styles object and className strings.

Configure lookup paths for composes/from

I'm still wrapping my head around the standard patterns for how PostCSS plugins consume configuration, but it doesn't look like there's currently a way to pass configuration through to postcss-import to configure the root and search path(s) for composes foo from 'bar' lookups.

Is this something that it would make sense to add, or am I missing something fundamental? I'm also happy to put together a PR if you have a form factor in mind for how you might want to consume such configuration.

postcss-modules v0.6.2 fails on node v6

I recently tried to upgrade postcss-modules to latest (v0.6.2) but encountered a problem building when running on node v6.9.4. Looks like the issue is that Object.values in behaviours.js wasn't added until node v7.0.0.

I rolled back to v0.5.2 and that works fine (for those that run into the same problem).

    ERROR in ./~/css-loader!./~/postcss-loader!./src/styles.css
    Module build failed: TypeError: Object.values is not a function
        at isValidBehaviour (/home/ubuntu/PROJECT/node_modules/postcss-modules/build/behaviours.js:34:17)
        at getDefaultScopeBehaviour (/home/ubuntu/PROJECT/node_modules/postcss-modules/build/index.js:36:63)

Better Usage description

I tried using this plugin and felt like a total noob.

IMHO there is too much information about css-modules itslef and integration but close to none about this plugin.

Given the code below:

function getJSON(cssFileName, json) {
  const cssName = path.basename(cssFileName, '.css');
  const jsonFileName  = path.resolve('./build', `${ cssName }.json`);
  fs.writeFileSync(jsonFileName, JSON.stringify(json));
}
cssModules({getJSON})

I get the following error.

errorify: Error: ENOENT: no such file or directory, open '<PROJECT_FOLDER>/build/styles.json' while parsing file: '<PROJECT_FOLDER>/src/components/foo/styles.css'

Looks like I'm too dumb to use this?

Multiple instances with generateScopedName

Creating multiple instances of this plugin that specify distinct generateScopedName functions causes unexpected behaviour as the provided function is effectively set as global.

This causes the last instantiated plugin's generateScopedName function to be used for all instances of the plugin, which in my case is very difficult to work around.

const pluginOne = postcssModules({
  generateScopedName: function(nodeName, fileName, css) {
    return "one";
  },
});

const pluginTwo = postcssModules({
  generateScopedName: function(nodeName, fileName, css) {
    return "two";
  },
});

//Using pluginOne now will result in all classes being named "two"

Expected behaviour would be for the provided function to be used for only the instance of plugin that is constructed with it.

Feature request: set character range

It would be could if there would be an option to set the unicode range which will be used to generate class names.
I would love to see some emojis in my source code. It does look quite funny and will save a lot of bytes over the wire.

Either use a range or specify them via array

Options:

require(postcss-modules)({
  unicodes: "1F601-1F567"
});

Input:

<div class="container">…</div>

.container { … }

Output:

<div class="💩">…</div>

.💩  { … }

Any plans on doing something like that?

Use postcss-modules generated css repeated

HI,
Q1 I want to use postcss-modules compile my css files, but out of the css generated duplicate.

1. common.css
.row { width : 100%; height : 100px; margin : 0; padding : 0; background-color : #000000; }

2. subCommon.css
.row { composes : row from './components.css'; background-color : #ff0430; }
3. webpack config
{ test : /\.css$/, loader: ExtractTextPlugin.extract("style-loader", ["css-loader?postcss-modules&importLoaders=1&sourceMap", "postcss-loader?parser=postcss-scss"]) }
4. postcss-modules config
postcss: function () { return [ psmodules({ generateScopedName: '[local]_[hash:base64:8]', getJSON : function (cssFileName, json) {} }), // cssnano(nanoConfig), ];

5 Compiled main.css file
.row_3hpoIFeb { width : 100%; height : 2.66667rem; margin : 0; padding : 0; background-color : #000000; } .row_3hpoIFeb { width : 100%; height : 2.66667rem; margin : 0; padding : 0; background-color : #000000; } .row_3D79gLaJ { background-color : #ff0430; }

common.css the row => [row_3hpoIFeb] is compiled twice!

Q2 Postcss-modules and cssnano can not be used together, compile exception!?

Webpack + React Support

I'm trying to use this package on a React app powered/bundled with webpack.

Through the following declaration in webpack, I'm able to generate a style.css file which appears to be working as the resulting css produces hashed names for classes...

        { test:    /\.css$/
        , loader: ExtractTextPlugin.extract('style-loader', 'css-loader!postcss-loader')
        , exclude: [/node_modules/]
        }

However, within a React component, a <p className={styles.element}>...</p> for example, does not inject the name of the css-module class ._element_1119m_1 for example.

Do you have any experience or knowledge of React compatibility?

Add option for not doing :local by default.

In order to ramp up a repo to use local scoped classes, it would be nice to do it incrementally.

Right now, the "local-by-default" plugin is hardcoded in postcss-modules index file, meaning without manually updating every css file to be :global, it's difficult to do this for large projects.

It would be very helpful to have an option to not include that plugin, so that projects could be incremental about module support.

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.