css-modules-require-hook
Advanced tools
Comparing version 1.0.4 to 1.0.5
@@ -6,8 +6,6 @@ 'use strict'; | ||
}); | ||
exports['default'] = buildOptions; | ||
exports['default'] = setup; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
require('./guard'); | ||
var _hook = require('./hook'); | ||
@@ -17,14 +15,24 @@ | ||
var _postcss = require('postcss'); | ||
var _fs = require('fs'); | ||
var _postcss2 = _interopRequireDefault(_postcss); | ||
var _path = require('path'); | ||
var _fs = require('fs'); | ||
var _utility = require('./utility'); | ||
var _lodashIsplainobject = require('lodash.isplainobject'); | ||
var _lodashAssign = require('lodash.assign'); | ||
var _lodashIsplainobject2 = _interopRequireDefault(_lodashIsplainobject); | ||
var _lodashAssign2 = _interopRequireDefault(_lodashAssign); | ||
var _lodashIdentity = require('lodash.identity'); | ||
var _lodashIdentity2 = _interopRequireDefault(_lodashIdentity); | ||
var _lodashPick = require('lodash.pick'); | ||
var _lodashPick2 = _interopRequireDefault(_lodashPick); | ||
var _postcss = require('postcss'); | ||
var _postcss2 = _interopRequireDefault(_postcss); | ||
var _postcssModulesExtractImports = require('postcss-modules-extract-imports'); | ||
@@ -46,27 +54,37 @@ | ||
var processCss = undefined; | ||
var rootDir = undefined; | ||
var plugins = undefined; | ||
// cache | ||
var importNr = 0; | ||
var tokensByFile = {}; | ||
// processing functions | ||
var preProcess = _lodashIdentity2['default']; | ||
var postProcess = undefined; | ||
// defaults | ||
var lazyResultOpts = {}; | ||
var plugins = [_postcssModulesLocalByDefault2['default'], _postcssModulesExtractImports2['default'], _postcssModulesScope2['default']]; | ||
var rootDir = process.cwd(); | ||
/** | ||
* @param {object} opts | ||
* @param {function} opts.createImportedName | ||
* @param {function} opts.generateScopedName | ||
* @param {function} opts.processCss|.p | ||
* @param {string} opts.rootDir|.root|.d | ||
* @param {array} opts.use|.u | ||
* @param {function} opts.processCss | ||
* @param {string} opts.rootDir | ||
* @param {string} opts.to | ||
* @param {array} opts.use | ||
*/ | ||
function buildOptions() { | ||
function setup() { | ||
var opts = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
if (!(0, _lodashIsplainobject2['default'])(opts)) { | ||
throw new Error('Use plain object'); | ||
} | ||
// clearing cache | ||
importNr = 0; | ||
tokensByFile = {}; | ||
processCss = get(opts, 'processCss|p'); | ||
rootDir = get(opts, 'rootDir|root|d'); | ||
rootDir = rootDir ? (0, _path.resolve)(rootDir) : process.cwd(); | ||
postProcess = (0, _utility.get)('processCss', null, 'function', opts) || null; | ||
rootDir = (0, _utility.get)('rootDir', ['root', 'd'], 'string', opts) || process.cwd(); | ||
// https://github.com/postcss/postcss/blob/master/docs/api.md#processorprocesscss-opts | ||
lazyResultOpts = (0, _lodashPick2['default'])(opts, ['to']); | ||
var customPlugins = get(opts, 'use|u'); | ||
if (Array.isArray(customPlugins)) { | ||
var customPlugins = (0, _utility.get)('use', ['u'], 'array', opts); | ||
if (customPlugins) { | ||
return void (plugins = customPlugins); | ||
@@ -77,75 +95,26 @@ } | ||
plugins.push(opts.mode ? new _postcssModulesLocalByDefault2['default']({ mode: opts.mode }) : _postcssModulesLocalByDefault2['default']); | ||
var mode = (0, _utility.get)('mode', null, 'string', opts); | ||
plugins.push(mode ? new _postcssModulesLocalByDefault2['default']({ mode: opts.mode }) : _postcssModulesLocalByDefault2['default']); | ||
plugins.push(opts.createImportedName ? new _postcssModulesExtractImports2['default']({ createImportedName: opts.createImportedName }) : _postcssModulesExtractImports2['default']); | ||
var createImportedName = (0, _utility.get)('createImportedName', null, 'function', opts); | ||
plugins.push(createImportedName ? new _postcssModulesExtractImports2['default']({ createImportedName: opts.createImportedName }) : _postcssModulesExtractImports2['default']); | ||
plugins.push(opts.generateScopedName ? new _postcssModulesScope2['default']({ generateScopedName: opts.generateScopedName }) : _postcssModulesScope2['default']); | ||
var generateScopedName = (0, _utility.get)('generateScopedName', null, 'function', opts); | ||
plugins.push(generateScopedName ? new _postcssModulesScope2['default']({ generateScopedName: opts.generateScopedName }) : _postcssModulesScope2['default']); | ||
} | ||
var escapedSeparator = _path.sep.replace(/(.)/g, '\\$1'); | ||
var relativePathPattern = new RegExp('^.{1,2}$|^.{1,2}' + escapedSeparator); | ||
var tokensByFile = {}; | ||
var importNr = 0; | ||
/** | ||
* @param {object} object | ||
* @param {string} keys 'a|b|c' | ||
* @return {*} | ||
*/ | ||
function get(object, keys) { | ||
var key = undefined; | ||
keys.split('|').some(function (k) { | ||
if (!object[k]) { | ||
return false; | ||
} | ||
key = k; | ||
return true; | ||
}); | ||
return key ? object[key] : null; | ||
} | ||
/** | ||
* @param {string} pathname | ||
* @return {boolean} | ||
*/ | ||
function isModule(pathname) { | ||
var parsed = (0, _path.parse)(pathname); | ||
return !parsed.root && !relativePathPattern.test(parsed.dir); | ||
} | ||
/** | ||
* @param {string} sourceString The file content | ||
* @param {string} sourcePath | ||
* @param {string} trace | ||
* @param {function} pathFetcher | ||
* @return {object} | ||
*/ | ||
function load(sourceString, sourcePath, trace, pathFetcher) { | ||
var lazyResult = (0, _postcss2['default'])(plugins.concat(new _parser2['default']({ pathFetcher: pathFetcher, trace: trace }))).process(sourceString, { from: sourcePath }); | ||
return { injectableSource: lazyResult.css, exportTokens: lazyResult.root.tokens }; | ||
} | ||
/** | ||
* @param {string} _newPath | ||
* @param {string} _relativeTo | ||
* @param {string} _to Absolute or relative path. Also can be path to the Node.JS module. | ||
* @param {string} _from Absolute path (relative to root). | ||
* @param {string} _trace | ||
* @return {object} | ||
*/ | ||
function fetch(_newPath, _relativeTo, _trace) { | ||
var newPath = _newPath.replace(/^["']|["']$/g, ''); | ||
function fetch(_to, _from, _trace) { | ||
var trace = _trace || String.fromCharCode(importNr++); | ||
var newPath = (0, _utility.removeQuotes)(_to); | ||
// getting absolute path to the processing file | ||
var filename = /\w/.test(newPath[0]) ? require.resolve(newPath) : (0, _path.resolve)((0, _path.dirname)(_from), newPath); | ||
var relativeDir = (0, _path.dirname)(_relativeTo); | ||
var rootRelativePath = (0, _path.resolve)(relativeDir, newPath); | ||
var fileRelativePath = (0, _path.resolve)((0, _path.join)(rootDir, relativeDir), newPath); | ||
if (isModule(newPath)) { | ||
fileRelativePath = require.resolve(newPath); | ||
} | ||
var tokens = tokensByFile[fileRelativePath]; | ||
// checking cache | ||
var tokens = tokensByFile[filename]; | ||
if (tokens) { | ||
@@ -155,24 +124,25 @@ return tokens; | ||
var source = (0, _fs.readFileSync)(fileRelativePath, 'utf-8'); | ||
var rootRelativePath = _path.sep + (0, _path.relative)(rootDir, filename); | ||
var CSSSource = preProcess((0, _fs.readFileSync)(filename, 'utf8')); | ||
var _load = load(source, rootRelativePath, trace, fetch); | ||
var lazyResult = (0, _postcss2['default'])(plugins.concat(new _parser2['default']({ fetch: fetch, filename: filename, trace: trace }))).process(CSSSource, (0, _lodashAssign2['default'])(lazyResultOpts, { from: rootRelativePath })); | ||
var exportTokens = _load.exportTokens; | ||
var injectableSource = _load.injectableSource; | ||
lazyResult.warnings().forEach(function (message) { | ||
return console.warn(message.text); | ||
}); | ||
tokensByFile[fileRelativePath] = exportTokens; | ||
tokens = lazyResult.root.tokens; | ||
// updating cache | ||
tokensByFile[filename] = tokens; | ||
if (typeof processCss === 'function') { | ||
processCss(injectableSource); | ||
if (postProcess) { | ||
postProcess(lazyResult.css); | ||
} | ||
return exportTokens; | ||
return tokens; | ||
} | ||
// setting defaults | ||
buildOptions(); | ||
(0, _hook2['default'])(function (filename) { | ||
return fetch('.' + _path.sep + (0, _path.relative)(rootDir, filename), '/'); | ||
return fetch(filename, filename); | ||
}); | ||
module.exports = exports['default']; |
@@ -20,3 +20,3 @@ 'use strict'; | ||
var depTrace = opts.trace + String.fromCharCode(depNr); | ||
var exports = opts.pathFetcher(file, relativeTo, depTrace); | ||
var exports = opts.fetch(file, opts.filename, depTrace); | ||
@@ -23,0 +23,0 @@ importNode.each(function (decl) { |
{ | ||
"name": "css-modules-require-hook", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"description": "A require hook to compile CSS Modules on the fly", | ||
@@ -10,3 +10,8 @@ "main": "index.js", | ||
"dependencies": { | ||
"lodash.isplainobject": "^3.2.0" | ||
"lodash.assign": "^3.2.0", | ||
"lodash.identity": "^3.0.0", | ||
"lodash.isarray": "^3.0.4", | ||
"lodash.isfunction": "^3.0.6", | ||
"lodash.isstring": "^3.0.1", | ||
"lodash.pick": "^3.1.0" | ||
}, | ||
@@ -23,2 +28,3 @@ "devDependencies": { | ||
"isparta": "^3.0.3", | ||
"lodash": "^3.10.1", | ||
"mocha": "^2.2.5", | ||
@@ -32,6 +38,6 @@ "postcss": "4.x", | ||
"peerDependencies": { | ||
"postcss": "4.x", | ||
"postcss-modules-extract-imports": "0.x", | ||
"postcss-modules-local-by-default": "0.x", | ||
"postcss-modules-scope": "0.x" | ||
"postcss": ">=4.x", | ||
"postcss-modules-extract-imports": ">=0.x", | ||
"postcss-modules-local-by-default": ">=0.x", | ||
"postcss-modules-scope": ">=0.x" | ||
}, | ||
@@ -44,2 +50,3 @@ "scripts": { | ||
"test:cov": "`npm bin`/babel-node `npm bin`/isparta cover --report text --report html `npm bin`/_mocha", | ||
"test:gen": "babel-node generate-tests", | ||
"build": "babel src --out-dir dist", | ||
@@ -46,0 +53,0 @@ "prepublish": "in-publish && npm run -s build || in-install" |
css-modules-require-hook | ||
======================== | ||
Automatically compiles a CSS Module to a low-level interchange format called ICSS or [Interoperable CSS](https://github.com/css-modules/icss). | ||
The require hook compiles [CSS Modules](https://github.com/css-modules/css-modules) in runtime. This is similar to Babel's [babel/register](https://babeljs.io/docs/usage/require/). | ||
One of the ways you can compile [CSS Modules](https://github.com/css-modules/css-modules) to the ICSS format is through the require hook. The require hook will bind itself to node's require and automatically compile files on the fly. This is similar to Babel's [babel/register](https://babeljs.io/docs/usage/require/). | ||
## What is CSS Modules | ||
## Requirements | ||
A **CSS Module** is a CSS file in which all class names and animation names are scoped locally by default. Learn more in the article [CSS Modules - Welcome to the Future](http://glenmaddern.com/articles/css-modules) by Glen Maddern. | ||
To use this tool we require postcss and few plugins to be installed on your project. See the list below: | ||
## Features | ||
- `"postcss": "4.x"` | ||
- `"postcss-modules-extract-imports": "0.x"` | ||
- `"postcss-modules-local-by-default": "0.x"` | ||
- `"postcss-modules-scope": "0.x"` | ||
Compiling in runtime, [universal](https://medium.com/@mjackson/universal-javascript-4761051b7ae9) usage. | ||
## Install | ||
## Usage | ||
```bash | ||
$ npm i css-modules-require-hook | ||
``` | ||
### Requirements | ||
## Usage | ||
To use this tool we require [Node.js v0.12.x](https://github.com/nodejs/node) (or higher) and several modules to be installed. | ||
```javascript | ||
require('css-modules-require-hook'); | ||
``` | ||
- [postcss](https://github.com/postcss/postcss) version 4 or higher | ||
- [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) | ||
## Available options | ||
### Installation | ||
Providing additional options allows you to get advanced experience. See the variants below. | ||
```javascript | ||
var hook = require('css-modules-require-hook'); | ||
hook({ /* options */ }); | ||
```bash | ||
$ npm i css-modules-require-hook | ||
``` | ||
### `rootDir` option | ||
### Tuning (options) | ||
Aliases are `root`, `d`. | ||
* `function` **createImportedName** — short alias for the [postcss-modules-extract-imports](https://github.com/css-modules/postcss-modules-extract-imports) plugin's `createImportedName` option. | ||
* `function` **generateScopedName** — short alias for the [postcss-modules-scope](https://github.com/css-modules/postcss-modules-scope) plugin's option. Helps you to specify the custom way to build generic names for the class selectors. | ||
* `function` **processCss** — in rare cases you may want to get compiled styles in runtime, so providing this option helps. | ||
* `string` **rootDir** — 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. | ||
* `string` **to** — provides `to` option to the [LazyResult instance](https://github.com/postcss/postcss/blob/master/docs/api.md#processorprocesscss-opts). | ||
* `array` **use** — custom subset of postcss plugins. | ||
Absolute path to your project's root directory. This is optional but providing it will result in better generated classnames. 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. | ||
### Examples | ||
### `use` option | ||
Basically you need to load this module before you start loading css-modules. Otherwise you'll get an exception. For example: | ||
Alias is `u`. | ||
*icon.css* | ||
```css | ||
.icon | ||
{ | ||
composes: fa fa-hand-peace-o from 'font-awesome/css/font-awesome.css'; | ||
} | ||
``` | ||
Custom list of plugins. This is optional but helps you to extend list of basic [postcss](https://github.com/postcss/postcss) plugins. Also helps to specify options for particular plugins. | ||
*server.js* | ||
```javascript | ||
require('css-modules-require-hook'); | ||
### `createImportedName` option | ||
var styles = require('./icon.css'); | ||
var html = '<i class="' + styles.icon + '"></i>'; | ||
// send it somehow :) | ||
``` | ||
Alias for the `createImportedName` option from the [postcss-modules-extract-imports](https://github.com/css-modules/postcss-modules-extract-imports) plugin. This is optional. Won't work if you `use` option. | ||
You'll get: | ||
### `generateScopedName` option | ||
```html | ||
<i class="_icon_font-awesome-css-font-awesome__fa _icon_font-awesome-css-font-awesome__fa-hand-peace-o"></i>' | ||
``` | ||
Custom function to generate class names. This is optional. Alias for the `generateScopedName` option from the [postcss-modules-scope](https://github.com/css-modules/postcss-modules-scope) plugin. Won't work if you `use` option. | ||
In rare cases you may want to tune the require hook for better experience. | ||
### `mode` option | ||
```javascript | ||
var hook = require('css-modules-require-hook'); | ||
var path = require('path'); | ||
Alias for the `mode` option from the [postcss-modules-local-by-default](https://github.com/css-modules/postcss-modules-local-by-default) plugin. This is optional. Won't work if you `use` option. | ||
hook({ | ||
// setting root to the parent directory | ||
rootDir: path.join(__dirname, '..') | ||
}); | ||
``` | ||
## Examples | ||
If you want to add any postcss plugins to the pipeline - you should use the `use` option. | ||
If you want to add custom functionality, for example [CSS Next](http://cssnext.io/setup/#as-a-postcss-plugin) plugin, you should provide the `use` option. | ||
```javascript | ||
@@ -67,0 +82,0 @@ var hook = require('css-modules-require-hook'); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
101068
25
625
96
10
16
+ Addedlodash.assign@^3.2.0
+ Addedlodash.identity@^3.0.0
+ Addedlodash.isarray@^3.0.4
+ Addedlodash.isfunction@^3.0.6
+ Addedlodash.isstring@^3.0.1
+ Addedlodash.pick@^3.1.0
+ Addedcssesc@3.0.0(transitive)
+ Addedicss-utils@5.1.0(transitive)
+ Addedlodash._baseassign@3.2.0(transitive)
+ Addedlodash._basecopy@3.0.1(transitive)
+ Addedlodash._baseflatten@3.1.4(transitive)
+ Addedlodash._bindcallback@3.0.1(transitive)
+ Addedlodash._createassigner@3.1.1(transitive)
+ Addedlodash._getnative@3.9.1(transitive)
+ Addedlodash._isiterateecall@3.0.9(transitive)
+ Addedlodash._pickbyarray@3.0.2(transitive)
+ Addedlodash._pickbycallback@3.0.0(transitive)
+ Addedlodash.assign@3.2.0(transitive)
+ Addedlodash.identity@3.0.0(transitive)
+ Addedlodash.isfunction@3.0.9(transitive)
+ Addedlodash.isstring@3.0.1(transitive)
+ Addedlodash.keys@3.1.2(transitive)
+ Addedlodash.pick@3.1.0(transitive)
+ Addedlodash.restparam@3.6.1(transitive)
+ Addednanoid@3.3.8(transitive)
+ Addedpicocolors@1.1.1(transitive)
+ Addedpostcss@8.4.49(transitive)
+ Addedpostcss-modules-extract-imports@3.1.0(transitive)
+ Addedpostcss-modules-local-by-default@4.2.0(transitive)
+ Addedpostcss-modules-scope@3.2.1(transitive)
+ Addedpostcss-selector-parser@7.0.0(transitive)
+ Addedpostcss-value-parser@4.2.0(transitive)
+ Addedsource-map-js@1.2.1(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
- Removedlodash.isplainobject@^3.2.0
- Removedamdefine@1.0.1(transitive)
- Removedcss-selector-tokenizer@0.5.4(transitive)
- Removedcssesc@0.1.0(transitive)
- Removedes6-promise@2.3.0(transitive)
- Removedfastparse@1.1.2(transitive)
- Removedjs-base64@2.1.9(transitive)
- Removedlodash.isplainobject@3.2.0(transitive)
- Removedpostcss@4.1.16(transitive)
- Removedpostcss-modules-extract-imports@0.0.6(transitive)
- Removedpostcss-modules-local-by-default@0.0.12(transitive)
- Removedpostcss-modules-scope@0.0.8(transitive)
- Removedsource-map@0.4.4(transitive)