diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..3c078e9
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,5 @@
+{
+ "presets": [
+ "es2015"
+ ]
+}
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..c270cfa
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+# cheat sheet: http://EditorConfig.org
diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index 925e6af..0000000
--- a/.eslintignore
+++ /dev/null
@@ -1,8 +0,0 @@
-dist
-coverage
-node_modules
-
-generate-tests.js
-test/cases/webpack/*
-test/common-test-cases.js
-webpack.config.js
diff --git a/.eslintrc b/.eslintrc
deleted file mode 100644
index 515956c..0000000
--- a/.eslintrc
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "extends": "eslint-config-airbnb-lite",
- "env": {
- "es6": true,
- "mocha": true
- },
- "rules": {
- "key-spacing": [2, {"align": "value"}],
- "no-use-before-define": [2, "nofunc"]
- }
-}
diff --git a/.gitignore b/.gitignore
index 7b2bf1d..905f8e6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,6 +28,3 @@ node_modules/*
# added automatically by precommit-hook as defaults
.jshint*
-
-dist/
-!node_modules/awesome-theme
diff --git a/.npmignore b/.npmignore
index 8e053ed..8daaae1 100644
--- a/.npmignore
+++ b/.npmignore
@@ -1,10 +1,7 @@
-# Generated by dmn (https://github.com/inikulin/dmn)
-
-.git*
+.babelrc
+.editorconfig
+.gitignore
.npmignore
.travis.yml
-generate-tests.js
-src/
-test/
-utils/
-webpack.config.js
+coverage
+demo
diff --git a/.travis.yml b/.travis.yml
index b71507b..ca8e5dd 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,3 @@
language: node_js
node_js:
- - "4.1"
- - "0.12"
+ - "4.3"
diff --git a/README.md b/README.md
index d2cf103..d3047dd 100644
--- a/README.md
+++ b/README.md
@@ -14,13 +14,7 @@ Compiling in runtime, [universal](https://medium.com/@mjackson/universal-javascr
## Requirements
-To use this tool we require [Node.js v0.12.x](https://github.com/nodejs/node) (or higher) and several modules to be installed.
-
-- [postcss](https://github.com/postcss/postcss) version 5 or higher
-- [postcss-modules-values](https://github.com/css-modules/postcss-modules-values)
-- [postcss-modules-extract-imports](https://github.com/css-modules/postcss-modules-extract-imports)
-- [postcss-modules-local-by-default](https://github.com/css-modules/postcss-modules-local-by-default)
-- [postcss-modules-scope](https://github.com/css-modules/postcss-modules-scope)
+To use this tool we require [Node.js v0.12.x](https://github.com/nodejs/node) (or higher).
## Installation
@@ -30,28 +24,45 @@ $ npm i css-modules-require-hook
## Usage
-In this section I've tried to cover the common cases of usage.
+Now, there are two ways to attach hook: manually or using preset file.
-### Development mode
+The first one allows you to pass options manually after module was required. Example:
-Usually, Node.js caches all the `require` calls by default. In order to invalidate cache for the purpose of development you should set the environment variable `NODE_ENV` to `development`. For example:
+```javascript
+const hook = require('css-modules-require-hook');
-```bash
-$ NODE_ENV=development node server.js
-```
+hook({
+ generateScopedName: '[name]__[local]___[hash:base64:5]',
+});
-Still you can use `devMode` option (see below) to override behavior which is imposed by environment variable.
+// const styles = require('./icon.css');
+```
-### Basic example
+The second one allows you to move options to the separate file `cmrh.conf.js`. Config file should be located in the same directory where executor is or in its ancestor directories. In that case hook will be attached right after the `css-modules-require-hook/preset` module will be required. Example:
-Basically to attach the require hook you need to require this module. If you need to adjust it see the tuning section below.
+```javascript
+// cmrh.conf.js
+module.exports = {
+ generateScopedName: '[name]__[local]___[hash:base64:5]',
+};
+```
```javascript
-require('css-modules-require-hook');
+require('css-modules-require-hook/preset');
-// var styles = require('./icon.css');
+// const styles = require('./icon.css');
```
+### Development mode
+
+Usually, Node.js caches all the `require` calls by default. In order to invalidate cache for the purpose of development you should set the environment variable `NODE_ENV` to `development`. For example:
+
+```bash
+$ NODE_ENV=development node server.js
+```
+
+Still you can use `devMode` option (see below) to override behavior which is imposed by environment variable.
+
### Adding custom PostCSS plugins
```javascript
@@ -166,6 +177,10 @@ hook({
Attach the require hook to additional file extensions (for example `['.scss']`).
+### `ignore` function|regex|string
+
+Provides possibility to exclude particular files from processing. Supports glob and regular expressions syntax. Also you may provide custom function.
+
### `rootDir` string
Provides absolute path to the project directory. Providing this will result in better generated class names. It can be obligatory, if you run require hook and build tools (like [css-modulesify](https://github.com/css-modules/css-modulesify)) from different working directories.
@@ -213,6 +228,7 @@ Short alias for the [postcss-modules-local-by-default](https://github.com/css-mo
[debug](https://www.npmjs.com/package/debug) package is used for debugging. So to turn it on simply specify the **DEBUG** environment variable:
- `DEBUG=css-modules:fetch` — to see resolved paths to the files.
+- `DEBUG=css-modules:preset` — to see whether config was found or not.
- `DEBUG=css-modules:setup` — to see the new options list.
- `DEBUG=css-modules:*` — to see everything.
diff --git a/demo/.babelrc b/demo/.babelrc
new file mode 100644
index 0000000..3c45d73
--- /dev/null
+++ b/demo/.babelrc
@@ -0,0 +1,7 @@
+{
+ "presets": [
+ "es2015",
+ "react",
+ "stage-0"
+ ]
+}
diff --git a/demo/.csscomb.json b/demo/.csscomb.json
new file mode 100644
index 0000000..a28b676
--- /dev/null
+++ b/demo/.csscomb.json
@@ -0,0 +1,401 @@
+{
+ "exclude": [
+ ".git/**",
+ ".reports/**",
+ "configs-package/**",
+ "debian/**",
+ "hooks/**",
+ "node_modules/**",
+ "server/**",
+ "static/desktop.blocks.test/**",
+ "static/desktop.bundles/**",
+ "static/.enb/**",
+ "static/.reports/**",
+ "static/.tanker/**",
+ "static/models/**",
+ "static/modules/**",
+ "static/modules.tests/**",
+ "static/node_modules/**",
+ "static/vendors/**",
+ "tasks/**",
+ "www/**"
+ ],
+ "remove-empty-rulesets": true,
+ "always-semicolon": true,
+ "color-case": "lower",
+ "block-indent": " ",
+ "color-shorthand": true,
+ "element-case": "lower",
+ "eof-newline": true,
+ "leading-zero": false,
+ "quotes": "single",
+ "sort-order-fallback": "abc",
+ "space-before-colon": "",
+ "space-after-colon": " ",
+ "space-before-combinator": " ",
+ "space-after-combinator": " ",
+ "space-between-declarations": "\n",
+ "space-before-opening-brace": "\n",
+ "space-after-opening-brace": "\n",
+ "space-after-selector-delimiter": "\n",
+ "space-before-selector-delimiter": "",
+ "space-before-closing-brace": "\n",
+ "strip-spaces": true,
+ "tab-size": true,
+ "unitless-zero": true,
+ "vendor-prefix-align": true,
+ "sort-order": [
+ [
+ "position",
+ "z-index",
+ "top",
+ "right",
+ "bottom",
+ "left"
+ ],
+ [
+ "display",
+ "visibility",
+ "float",
+ "clear",
+ "overflow",
+ "overflow-x",
+ "overflow-y",
+ "-ms-overflow-x",
+ "-ms-overflow-y",
+ "-webkit-overflow-scrolling",
+ "clip",
+ "zoom",
+ "-webkit-flex-direction",
+ "-ms-flex-direction",
+ "flex-direction",
+ "-webkit-flex-wrap",
+ "-ms-flex-wrap",
+ "flex-wrap",
+ "-webkit-flex-flow",
+ "-ms-flex-flow",
+ "flex-flow",
+ "-webkit-order",
+ "-ms-flex-order",
+ "order",
+ "-webkit-justify-content",
+ "-ms-flex-pack",
+ "justify-content",
+ "-webkit-align-content",
+ "-ms-flex-line-pack",
+ "align-content",
+ "-webkit-align-items",
+ "-ms-flex-align",
+ "align-items",
+ "-webkit-align-self",
+ "-ms-flex-item-align",
+ "align-self"
+ ],
+ [
+ "-webkit-flex-grow",
+ "-ms-flex-positive",
+ "flex-grow",
+ "-webkit-flex-shrink",
+ "-ms-flex-negative",
+ "flex-shrink",
+ "-webkit-flex-basis",
+ "-ms-flex-preferred-size",
+ "flex-basis",
+ "-webkit-flex",
+ "-ms-flex",
+ "flex"
+ ],
+ [
+ "-webkit-box-sizing",
+ "-moz-box-sizing",
+ "box-sizing",
+ "width",
+ "min-width",
+ "max-width",
+ "height",
+ "min-height",
+ "max-height",
+ "margin",
+ "margin-top",
+ "margin-right",
+ "margin-bottom",
+ "margin-left",
+ "padding",
+ "padding-top",
+ "padding-right",
+ "padding-bottom",
+ "padding-left"
+ ],
+ [
+ "table-layout",
+ "empty-cells",
+ "caption-side",
+ "border-spacing",
+ "border-collapse",
+ "list-style",
+ "list-style-position",
+ "list-style-type",
+ "list-style-image"
+ ],
+ [
+ "content",
+ "quotes",
+ "counter-reset",
+ "counter-increment",
+ "resize",
+ "cursor",
+ "-webkit-user-select",
+ "-moz-user-select",
+ "-ms-user-select",
+ "user-select",
+ "nav-index",
+ "nav-up",
+ "nav-right",
+ "nav-down",
+ "nav-left",
+ "-webkit-transition",
+ "-moz-transition",
+ "-ms-transition",
+ "-o-transition",
+ "transition",
+ "-webkit-transition-delay",
+ "-moz-transition-delay",
+ "-ms-transition-delay",
+ "-o-transition-delay",
+ "transition-delay",
+ "-webkit-transition-timing-function",
+ "-moz-transition-timing-function",
+ "-ms-transition-timing-function",
+ "-o-transition-timing-function",
+ "transition-timing-function",
+ "-webkit-transition-duration",
+ "-moz-transition-duration",
+ "-ms-transition-duration",
+ "-o-transition-duration",
+ "transition-duration",
+ "-webkit-transition-property",
+ "-moz-transition-property",
+ "-ms-transition-property",
+ "-o-transition-property",
+ "transition-property",
+ "-webkit-transform",
+ "-moz-transform",
+ "-ms-transform",
+ "-o-transform",
+ "transform",
+ "-webkit-transform-origin",
+ "-moz-transform-origin",
+ "-ms-transform-origin",
+ "-o-transform-origin",
+ "transform-origin",
+ "-webkit-animation",
+ "-moz-animation",
+ "-ms-animation",
+ "-o-animation",
+ "animation",
+ "-webkit-animation-name",
+ "-moz-animation-name",
+ "-ms-animation-name",
+ "-o-animation-name",
+ "animation-name",
+ "-webkit-animation-duration",
+ "-moz-animation-duration",
+ "-ms-animation-duration",
+ "-o-animation-duration",
+ "animation-duration",
+ "-webkit-animation-play-state",
+ "-moz-animation-play-state",
+ "-ms-animation-play-state",
+ "-o-animation-play-state",
+ "animation-play-state",
+ "-webkit-animation-timing-function",
+ "-moz-animation-timing-function",
+ "-ms-animation-timing-function",
+ "-o-animation-timing-function",
+ "animation-timing-function",
+ "-webkit-animation-delay",
+ "-moz-animation-delay",
+ "-ms-animation-delay",
+ "-o-animation-delay",
+ "animation-delay",
+ "-webkit-animation-iteration-count",
+ "-moz-animation-iteration-count",
+ "-ms-animation-iteration-count",
+ "-o-animation-iteration-count",
+ "animation-iteration-count",
+ "-webkit-animation-iteration-count",
+ "-moz-animation-iteration-count",
+ "-ms-animation-iteration-count",
+ "-o-animation-iteration-count",
+ "animation-iteration-count",
+ "-webkit-animation-direction",
+ "-moz-animation-direction",
+ "-ms-animation-direction",
+ "-o-animation-direction",
+ "animation-direction",
+ "text-align",
+ "-webkit-text-align-last",
+ "-moz-text-align-last",
+ "-ms-text-align-last",
+ "text-align-last",
+ "vertical-align",
+ "white-space",
+ "text-decoration",
+ "text-emphasis",
+ "text-emphasis-color",
+ "text-emphasis-style",
+ "text-emphasis-position",
+ "text-indent",
+ "-ms-text-justify",
+ "text-justify",
+ "text-transform",
+ "letter-spacing",
+ "word-spacing",
+ "-ms-writing-mode",
+ "text-outline",
+ "text-transform",
+ "text-wrap",
+ "text-overflow",
+ "-ms-text-overflow",
+ "text-overflow-ellipsis",
+ "text-overflow-mode",
+ "-ms-word-wrap",
+ "word-wrap",
+ "word-break",
+ "-ms-word-break",
+ "-moz-tab-size",
+ "-o-tab-size",
+ "tab-size",
+ "-webkit-hyphens",
+ "-moz-hyphens",
+ "hyphens",
+ "pointer-events"
+ ],
+ [
+ "opacity",
+ "filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
+ "-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
+ "-ms-interpolation-mode",
+ "color",
+ "border",
+ "border-collapse",
+ "border-width",
+ "border-style",
+ "border-color",
+ "border-top",
+ "border-top-width",
+ "border-top-style",
+ "border-top-color",
+ "border-right",
+ "border-right-width",
+ "border-right-style",
+ "border-right-color",
+ "border-bottom",
+ "border-bottom-width",
+ "border-bottom-style",
+ "border-bottom-color",
+ "border-left",
+ "border-left-width",
+ "border-left-style",
+ "border-left-color",
+ "-webkit-border-radius",
+ "-moz-border-radius",
+ "border-radius",
+ "-webkit-border-top-left-radius",
+ "-moz-border-radius-topleft",
+ "border-top-left-radius",
+ "-webkit-border-top-right-radius",
+ "-moz-border-radius-topright",
+ "border-top-right-radius",
+ "-webkit-border-bottom-right-radius",
+ "-moz-border-radius-bottomright",
+ "border-bottom-right-radius",
+ "-webkit-border-bottom-left-radius",
+ "-moz-border-radius-bottomleft",
+ "border-bottom-left-radius",
+ "-webkit-border-image",
+ "-moz-border-image",
+ "-o-border-image",
+ "border-image",
+ "-webkit-border-image-source",
+ "-moz-border-image-source",
+ "-o-border-image-source",
+ "border-image-source",
+ "-webkit-border-image-slice",
+ "-moz-border-image-slice",
+ "-o-border-image-slice",
+ "border-image-slice",
+ "-webkit-border-image-width",
+ "-moz-border-image-width",
+ "-o-border-image-width",
+ "border-image-width",
+ "-webkit-border-image-outset",
+ "-moz-border-image-outset",
+ "-o-border-image-outset",
+ "border-image-outset",
+ "-webkit-border-image-repeat",
+ "-moz-border-image-repeat",
+ "-o-border-image-repeat",
+ "border-image-repeat",
+ "outline",
+ "outline-width",
+ "outline-style",
+ "outline-color",
+ "outline-offset",
+ "background",
+ "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
+ "background-color",
+ "background-image",
+ "background-repeat",
+ "background-attachment",
+ "background-position",
+ "background-position-x",
+ "-ms-background-position-x",
+ "background-position-y",
+ "-ms-background-position-y",
+ "-webkit-background-clip",
+ "-moz-background-clip",
+ "background-clip",
+ "background-origin",
+ "-webkit-background-size",
+ "-moz-background-size",
+ "-o-background-size",
+ "background-size",
+ "box-decoration-break",
+ "-webkit-box-shadow",
+ "-moz-box-shadow",
+ "box-shadow",
+ "-webkit-box-shadow",
+ "-moz-box-shadow",
+ "box-shadow",
+ "-webkit-box-shadow",
+ "-moz-box-shadow",
+ "box-shadow",
+ "-webkit-box-shadow",
+ "-moz-box-shadow",
+ "box-shadow",
+ "filter:progid:DXImageTransform.Microsoft.gradient",
+ "-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
+ "text-shadow"
+ ],
+ [
+ "font",
+ "font-family",
+ "font-size",
+ "font-weight",
+ "font-style",
+ "font-variant",
+ "font-size-adjust",
+ "font-stretch",
+ "font-effect",
+ "font-emphasize",
+ "font-emphasize-position",
+ "font-emphasize-style",
+ "font-smooth",
+ "line-height"
+ ],
+ [
+ "composes"
+ ]
+ ]
+}
diff --git a/demo/.editorconfig b/demo/.editorconfig
new file mode 100644
index 0000000..c270cfa
--- /dev/null
+++ b/demo/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+# cheat sheet: http://EditorConfig.org
diff --git a/demo/.gitignore b/demo/.gitignore
new file mode 100644
index 0000000..fe86a60
--- /dev/null
+++ b/demo/.gitignore
@@ -0,0 +1,35 @@
+static/
+
+# Logs
+logs
+*.log
+
+# Runtime data
+pids
+*.pid
+*.seed
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (http://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directory
+# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
+node_modules/*
+
+# added automatically by precommit-hook as defaults
+.jshint*
+
+dist/
+!node_modules/awesome-theme
diff --git a/demo/app/browser.js b/demo/app/browser.js
new file mode 100644
index 0000000..90196cc
--- /dev/null
+++ b/demo/app/browser.js
@@ -0,0 +1 @@
+import Button from '../components/Button';
diff --git a/demo/app/view-engine.js b/demo/app/view-engine.js
new file mode 100644
index 0000000..23b1e82
--- /dev/null
+++ b/demo/app/view-engine.js
@@ -0,0 +1,38 @@
+'use strict';
+
+const babel = require('babel-core/register');
+const lodash = require('lodash');
+const React = require('react');
+const ReactDOM = require('react-dom/server');
+
+const doctype = '';
+
+function dropCache(view) {
+ const detectView = new RegExp(`^${view}`);
+
+ lodash.forEach(require.cache, (view, identity) => {
+ detectView.test(view.filename)
+ && delete require.cache[identity];
+ });
+}
+
+babel({
+ only: /components/,
+});
+
+module.exports = function viewEngine(file, opts, cb) {
+ let markup = doctype;
+
+ try {
+ let component = require(file).default;
+ markup += ReactDOM.renderToStaticMarkup(
+ React.createElement(component, opts)
+ );
+ } catch (e) {
+ dropCache(opts.settings.views);
+ return void cb(e);
+ }
+
+ dropCache(opts.settings.views);
+ cb(null, markup);
+};
diff --git a/demo/app/worker.js b/demo/app/worker.js
new file mode 100644
index 0000000..ccf27dd
--- /dev/null
+++ b/demo/app/worker.js
@@ -0,0 +1,24 @@
+'use strict';
+
+const express = require('express');
+const hook = require('css-modules-require-hook');
+const path = require('path');
+const viewEngine = require('./view-engine');
+
+const config = require('../package').config;
+const app = express();
+
+hook({
+ generateScopedName: config.css,
+});
+
+// setting rendering engine
+app.engine('js', viewEngine);
+app.set('views', path.join(__dirname, '../components'));
+app.set('view engine', 'js');
+
+app.use(express.static(path.join(__dirname, '../static')));
+
+app.get('/', (req, res) => res.render('Page'));
+
+app.listen(config.port, _ => console.log(`listening ${config.port}`));
diff --git a/demo/components/Button/Button.css b/demo/components/Button/Button.css
new file mode 100644
index 0000000..1f768c8
--- /dev/null
+++ b/demo/components/Button/Button.css
@@ -0,0 +1,18 @@
+.common
+{
+ padding: 0 13px;
+
+ cursor: pointer;
+ user-select: none;
+ text-align: center;
+ white-space: nowrap;
+
+ border: none;
+ border-radius: 3px;
+ outline: none;
+ background: #ffdb4d;
+
+ font-family: arial, sans-serif;
+ font-size: 13px;
+ line-height: 28px;
+}
diff --git a/demo/components/Button/index.js b/demo/components/Button/index.js
new file mode 100644
index 0000000..b302af6
--- /dev/null
+++ b/demo/components/Button/index.js
@@ -0,0 +1,6 @@
+import React from 'react';
+import base from './Button.css';
+
+export default ({ styles = base, ..._ }) => (
+