Skip to content

Commit 7b8632a

Browse files
committedFeb 13, 2017
move cli to standalone package (css/csso-cli)
1 parent ab28815 commit 7b8632a

File tree

5 files changed

+91
-716
lines changed

5 files changed

+91
-716
lines changed
 

‎README.md

+90-265
Original file line numberDiff line numberDiff line change
@@ -9,169 +9,40 @@ CSSO (CSS Optimizer) is a CSS minifier. It performs three sort of transformation
99
[![Originated by Yandex](https://cdn.rawgit.com/css/csso/8d1b89211ac425909f735e7d5df87ee16c2feec6/docs/yandex.svg)](https://www.yandex.com/)
1010
[![Sponsored by Avito](https://cdn.rawgit.com/css/csso/8d1b89211ac425909f735e7d5df87ee16c2feec6/docs/avito.svg)](https://www.avito.ru/)
1111

12-
## Usage
13-
14-
```
15-
npm install -g csso
16-
```
17-
18-
Or try out CSSO [right in your browser](http://css.github.io/csso/csso.html) (web interface).
19-
20-
### Runners
21-
12+
<!-- MarkdownTOC -->
13+
14+
- [Ready to use](#ready-to-use)
15+
- [Install](#install)
16+
- [API](#api)
17+
- [minify\(source\[, options\]\)](#minifysource-options)
18+
- [minifyBlock\(source\[, options\]\)](#minifyblocksource-options)
19+
- [compress\(ast\[, options\]\)](#compressast-options)
20+
- [Source maps](#source-maps)
21+
- [Usage data](#usage-data)
22+
- [Selector filtering](#selector-filtering)
23+
- [Scopes](#scopes)
24+
- [Debugging](#debugging)
25+
- [License](#license)
26+
27+
<!-- /MarkdownTOC -->
28+
29+
## Ready to use
30+
31+
- [Web interface](http://css.github.io/csso/csso.html)
32+
- CLI: [csso-cli](https://github.com/css/csso-cli)
2233
- Gulp: [gulp-csso](https://github.com/ben-eb/gulp-csso)
2334
- Grunt: [grunt-csso](https://github.com/t32k/grunt-csso)
2435
- Broccoli: [broccoli-csso](https://github.com/sindresorhus/broccoli-csso)
2536
- PostCSS: [postcss-csso](https://github.com/lahmatiy/postcss-csso)
2637
- Webpack: [csso-loader](https://github.com/sandark7/csso-loader)
2738

28-
### Command line
29-
30-
```
31-
csso [input] [output] [options]
32-
33-
Options:
34-
35-
--comments <value> Comments to keep: exclamation (default), first-exclamation or none
36-
--debug [level] Output intermediate state of CSS during compression
37-
-h, --help Output usage information
38-
-i, --input <filename> Input file
39-
--input-map <source> Input source map: none, auto (default) or <filename>
40-
-m, --map <destination> Generate source map: none (default), inline, file or <filename>
41-
-o, --output <filename> Output file (result outputs to stdout if not set)
42-
--restructure-off Turns structure minimization off
43-
--stat Output statistics in stderr
44-
-u, --usage <filenane> Usage data file
45-
-v, --version Output version
46-
```
47-
48-
Some examples:
49-
50-
```
51-
> csso in.css
52-
...output result in stdout...
53-
54-
> csso in.css --output out.css
55-
56-
> echo '.test { color: #ff0000; }' | csso
57-
.test{color:red}
58-
59-
> cat source1.css source2.css | csso | gzip -9 -c > production.css.gz
60-
```
61-
62-
### Source maps
63-
64-
Source map doesn't generate by default. To generate map use `--map` CLI option, that can be:
65-
66-
- `none` (default) – don't generate source map
67-
- `inline` – add source map into result CSS (via `/*# sourceMappingURL=application/json;base64,... */`)
68-
- `file` – write source map into file with same name as output file, but with `.map` extension (in this case `--output` option is required)
69-
- any other values treat as filename for generated source map
70-
71-
Examples:
39+
## Install
7240

7341
```
74-
> csso my.css --map inline
75-
> csso my.css --output my.min.css --map file
76-
> csso my.css --output my.min.css --map maps/my.min.map
77-
```
78-
79-
Use `--input-map` option to specify input source map if needed. Possible values for option:
80-
81-
- `auto` (default) - attempt to fetch input source map by follow steps:
82-
- try to fetch inline map from input
83-
- try to fetch source map filename from input and read its content
84-
- (when `--input` is specified) check file with same name as input file but with `.map` extension exists and read its content
85-
- `none` - don't use input source map; actually it's using to disable `auto`-fetching
86-
- any other values treat as filename for input source map
87-
88-
Generally you shouldn't care about the input source map since defaults behaviour (`auto`) covers most use cases.
89-
90-
> NOTE: Input source map is using only if output source map is generating.
91-
92-
### Usage data
93-
94-
`CSSO` can use data about how `CSS` is using for better compression. File with this data (`JSON` format) can be set using `--usage` option. Usage data may contain follow sections:
95-
96-
- `tags` – white list of tags
97-
- `ids` – white list of ids
98-
- `classes` – white list of classes
99-
- `scopes` – groups of classes which never used with classes from other groups on single element
100-
101-
All sections are optional. Value of `tags`, `ids` and `classes` should be array of strings, value of `scopes` should be an array of arrays of strings. Other values are ignoring.
102-
103-
#### Selector filtering
104-
105-
`tags`, `ids` and `classes` are using on clean stage to filter selectors that contains something that not in list. Selectors are filtering only by those kind of simple selector which white list is specified. For example, if only `tags` list is specified then type selectors are checking, and if selector hasn't any type selector (or even any type selector) it isn't filter.
106-
107-
> `ids` and `classes` names are case sensitive, `tags` – is not.
108-
109-
Input CSS:
110-
111-
```css
112-
* { color: green; }
113-
ul, ol, li { color: blue; }
114-
UL.foo, span.bar { color: red; }
115-
```
116-
117-
Usage data:
118-
119-
```json
120-
{
121-
"tags": ["ul", "LI"]
122-
}
123-
```
124-
125-
Result CSS:
126-
127-
```css
128-
*{color:green}ul,li{color:blue}ul.foo{color:red}
129-
```
130-
131-
#### Scopes
132-
133-
Scopes is designed for CSS scope isolation solutions such as [css-modules](https://github.com/css-modules/css-modules). Scopes are similar to namespaces and defines lists of class names that exclusively used on some markup. This information allows the optimizer to move rulesets more agressive. Since it assumes selectors from different scopes can't to be matched on the same element. That leads to better ruleset merging.
134-
135-
Suppose we have a file:
136-
137-
```css
138-
.module1-foo { color: red; }
139-
.module1-bar { font-size: 1.5em; background: yellow; }
140-
141-
.module2-baz { color: red; }
142-
.module2-qux { font-size: 1.5em; background: yellow; width: 50px; }
143-
```
144-
145-
It can be assumed that first two rules are never used with the second two on the same markup. But we can't know that for sure without markup. The optimizer doesn't know it either and will perform safe transformations only. The result will be the same as input but with no spaces and some semicolons:
146-
147-
```css
148-
.module1-foo{color:red}.module1-bar{font-size:1.5em;background:#ff0}.module2-baz{color:red}.module2-qux{font-size:1.5em;background:#ff0;width:50px}
149-
```
150-
151-
But with usage data `CSSO` can get better output. If follow usage data is provided:
152-
153-
```json
154-
{
155-
"scopes": [
156-
["module1-foo", "module1-bar"],
157-
["module2-baz", "module2-qux"]
158-
]
159-
}
160-
```
161-
162-
New result (29 bytes extra saving):
163-
164-
```css
165-
.module1-foo,.module2-baz{color:red}.module1-bar,.module2-qux{font-size:1.5em;background:#ff0}.module2-qux{width:50px}
42+
npm install -g csso
16643
```
16744

168-
If class name doesn't specified in `scopes` it belongs to default "scope". `scopes` doesn't affect `classes`. If class name presents in `scopes` but missed in `classes` (both sections specified) it will be filtered.
169-
170-
Note that class name can't be specified in several scopes. Also selector can't has classes from different scopes. In both cases an exception throws.
171-
172-
Currently the optimizer doesn't care about out-of-bounds selectors order changing safety (i.e. selectors that may be matched to elements with no class name of scope, e.g. `.scope div` or `.scope ~ :last-child`) since assumes scoped CSS modules doesn't relay on it's order. It may be fix in future if to be an issue.
173-
174-
### API
45+
## API
17546

17647
```js
17748
var csso = require('csso');
@@ -209,7 +80,7 @@ console.log(result.map.toString());
20980
// '{ .. source map content .. }'
21081
```
21182

212-
#### minify(source[, options])
83+
### minify(source[, options])
21384

21485
Minify `source` CSS passed as `String`.
21586

@@ -238,7 +109,7 @@ console.log(result.css);
238109
// > .test{color:red}
239110
```
240111

241-
#### minifyBlock(source[, options])
112+
### minifyBlock(source[, options])
242113

243114
The same as `minify()` but for style block. Usually it's a `style` attribute content.
244115

@@ -249,44 +120,7 @@ console.log(result.css);
249120
// > color:red
250121
```
251122

252-
#### parse(source[, options])
253-
254-
Parse CSS to AST.
255-
256-
> NOTE: Currenly parser omit redundant separators, spaces and comments (except exclamation comments, i.e. `/*! comment */`) on AST build, since those things are removing by compressor anyway.
257-
258-
Options:
259-
260-
- context `String` – parsing context, useful when some part of CSS is parsing (see below)
261-
- positions `Boolean` – should AST contains node position or not, store data in `info` property of nodes (`false` by default)
262-
- filename `String` – filename of source that adds to info when `positions` is true, uses for source map generation (`<unknown>` by default)
263-
- line `Number` – initial line number, useful when parse fragment of CSS to compute correct positions
264-
- column `Number` – initial column number, useful when parse fragment of CSS to compute correct positions
265-
266-
Contexts:
267-
268-
- `stylesheet` (default) – regular stylesheet, should be suitable in most cases
269-
- `atrule` – at-rule (e.g. `@media screen, print { ... }`)
270-
- `atruleExpression` – at-rule expression (`screen, print` for example above)
271-
- `ruleset` – rule (e.g. `.foo, .bar:hover { color: red; border: 1px solid black; }`)
272-
- `selector` – selector group (`.foo, .bar:hover` for ruleset example)
273-
- `simpleSelector` – selector (`.foo` or `.bar:hover` for ruleset example)
274-
- `block` – block content w/o curly braces (`color: red; border: 1px solid black;` for ruleset example)
275-
- `declaration` – declaration (`color: red` or `border: 1px solid black` for ruleset example)
276-
- `value` – declaration value (`red` or `1px solid black` for ruleset example)
277-
278-
```js
279-
// simple parsing with no options
280-
var ast = csso.parse('.example { color: red }');
281-
282-
// parse with options
283-
var ast = csso.parse('.foo.bar', {
284-
context: 'simpleSelector',
285-
positions: true
286-
});
287-
```
288-
289-
#### compress(ast[, options])
123+
### compress(ast[, options])
290124

291125
Does the main task – compress AST.
292126

@@ -303,104 +137,95 @@ Options:
303137
- usage `Object` - usage data for advanced optimisations (see [Usage data](#usage-data) for details)
304138
- logger `Function` - function to track every step of transformations
305139

306-
#### clone(ast)
140+
### Source maps
307141

308-
Make an AST node deep copy.
142+
> TODO
309143
310-
```js
311-
var orig = csso.parse('.test { color: red }');
312-
var copy = csso.clone(orig);
144+
### Usage data
313145

314-
csso.walk(copy, function(node) {
315-
if (node.type === 'Class') {
316-
node.name = 'replaced';
317-
}
318-
});
146+
`CSSO` can use data about how `CSS` is using for better compression. File with this data (`JSON` format) can be set using `usage` option. Usage data may contain follow sections:
319147

320-
console.log(csso.translate(orig));
321-
// .test{color:red}
322-
console.log(csso.translate(copy));
323-
// .replaced{color:red}
324-
```
148+
- `tags` – white list of tags
149+
- `ids` – white list of ids
150+
- `classes` – white list of classes
151+
- `scopes` – groups of classes which never used with classes from other groups on single element
325152

326-
#### translate(ast)
153+
All sections are optional. Value of `tags`, `ids` and `classes` should be array of strings, value of `scopes` should be an array of arrays of strings. Other values are ignoring.
327154

328-
Converts AST to string.
155+
#### Selector filtering
329156

330-
```js
331-
var ast = csso.parse('.test { color: red }');
332-
console.log(csso.translate(ast));
333-
// > .test{color:red}
157+
`tags`, `ids` and `classes` are using on clean stage to filter selectors that contains something that not in list. Selectors are filtering only by those kind of simple selector which white list is specified. For example, if only `tags` list is specified then type selectors are checking, and if selector hasn't any type selector (or even any type selector) it isn't filter.
158+
159+
> `ids` and `classes` names are case sensitive, `tags` – is not.
160+
161+
Input CSS:
162+
163+
```css
164+
* { color: green; }
165+
ul, ol, li { color: blue; }
166+
UL.foo, span.bar { color: red; }
334167
```
335168

336-
#### translateWithSourceMap(ast)
169+
Usage data:
337170

338-
The same as `translate()` but also generates source map (nodes should contain positions in `info` property).
171+
```json
172+
{
173+
"tags": ["ul", "LI"]
174+
}
175+
```
339176

340-
```js
341-
var ast = csso.parse('.test { color: red }', {
342-
filename: 'my.css',
343-
positions: true
344-
});
345-
console.log(csso.translateWithSourceMap(ast));
346-
// { css: '.test{color:red}', map: SourceMapGenerator {} }
177+
Result CSS:
178+
179+
```css
180+
*{color:green}ul,li{color:blue}ul.foo{color:red}
347181
```
348182

349-
#### walk(ast, handler)
183+
#### Scopes
184+
185+
Scopes is designed for CSS scope isolation solutions such as [css-modules](https://github.com/css-modules/css-modules). Scopes are similar to namespaces and defines lists of class names that exclusively used on some markup. This information allows the optimizer to move rulesets more agressive. Since it assumes selectors from different scopes can't to be matched on the same element. That leads to better ruleset merging.
186+
187+
Suppose we have a file:
350188

351-
Visit all nodes of AST and call handler for each one. `handler` receives three arguments:
189+
```css
190+
.module1-foo { color: red; }
191+
.module1-bar { font-size: 1.5em; background: yellow; }
352192

353-
- node – current AST node
354-
- item – node wrapper when node is a list member; this wrapper contains references to `prev` and `next` nodes in list
355-
- list – reference to list when node is a list member; it's useful for operations on list like `remove()` or `insert()`
193+
.module2-baz { color: red; }
194+
.module2-qux { font-size: 1.5em; background: yellow; width: 50px; }
195+
```
356196

357-
Context for handler an object, that contains references to some parent nodes:
197+
It can be assumed that first two rules are never used with the second two on the same markup. But we can't know that for sure without markup. The optimizer doesn't know it either and will perform safe transformations only. The result will be the same as input but with no spaces and some semicolons:
358198

359-
- root – refers to `ast` or root node
360-
- stylesheet – refers to closest `StyleSheet` node, it may be a top-level or at-rule block stylesheet
361-
- atruleExpression – refers to `AtruleExpression` node if current node inside at-rule expression
362-
- ruleset – refers to `Rule` node if current node inside a ruleset
363-
- selector – refers to `Selector` node if current node inside a selector
364-
- declaration – refers to `Declaration` node if current node inside a declaration
365-
- function – refers to closest `Function` or `FunctionalPseudo` node if current node inside one of them
199+
```css
200+
.module1-foo{color:red}.module1-bar{font-size:1.5em;background:#ff0}.module2-baz{color:red}.module2-qux{font-size:1.5em;background:#ff0;width:50px}
201+
```
366202

367-
```js
368-
// collect all urls in declarations
369-
var csso = require('./lib/index.js');
370-
var urls = [];
371-
var ast = csso.parse(`
372-
@import url(import.css);
373-
.foo { background: url('foo.jpg'); }
374-
.bar { background-image: url(bar.png); }
375-
`);
376-
377-
csso.walk(ast, function(node) {
378-
if (this.declaration !== null && node.type === 'Url') {
379-
var value = node.value;
380-
381-
if (value.type === 'Raw') {
382-
urls.push(value.value);
383-
} else {
384-
urls.push(value.value.substr(1, value.value.length - 2));
385-
}
386-
}
387-
});
203+
But with usage data `CSSO` can get better output. If follow usage data is provided:
388204

389-
console.log(urls);
390-
// [ 'foo.jpg', 'bar.png' ]
205+
```json
206+
{
207+
"scopes": [
208+
["module1-foo", "module1-bar"],
209+
["module2-baz", "module2-qux"]
210+
]
211+
}
391212
```
392213

393-
#### walkRules(ast, handler)
214+
New result (29 bytes extra saving):
215+
216+
```css
217+
.module1-foo,.module2-baz{color:red}.module1-bar,.module2-qux{font-size:1.5em;background:#ff0}.module2-qux{width:50px}
218+
```
394219

395-
Same as `walk()` but visits `Rule` and `Atrule` nodes only.
220+
If class name doesn't specified in `scopes` it belongs to default "scope". `scopes` doesn't affect `classes`. If class name presents in `scopes` but missed in `classes` (both sections specified) it will be filtered.
396221

397-
#### walkRulesRight(ast, handler)
222+
Note that class name can't be specified in several scopes. Also selector can't has classes from different scopes. In both cases an exception throws.
398223

399-
Same as `walkRules()` but visits nodes in reverse order (from last to first).
224+
Currently the optimizer doesn't care about out-of-bounds selectors order changing safety (i.e. selectors that may be matched to elements with no class name of scope, e.g. `.scope div` or `.scope ~ :last-child`) since assumes scoped CSS modules doesn't relay on it's order. It may be fix in future if to be an issue.
400225

401-
## More reading
226+
### Debugging
402227

403-
- [Debugging](docs/debugging.md)
228+
> TODO
404229
405230
## License
406231

‎bin/csso

-16
This file was deleted.

‎docs/debugging.md

-94
This file was deleted.

‎lib/cli.js

-338
This file was deleted.

‎package.json

+1-3
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@
5252
"prepublish": "npm run browserify"
5353
},
5454
"dependencies": {
55-
"clap": "^1.0.9",
56-
"css-tree": "csstree/csstree",
57-
"source-map": "^0.5.3"
55+
"css-tree": "csstree/csstree"
5856
},
5957
"devDependencies": {
6058
"browserify": "^13.0.0",

0 commit comments

Comments
 (0)
Please sign in to comment.