Skip to content

Commit c51e66a

Browse files
committed
.
0 parents  commit c51e66a

File tree

9 files changed

+241
-0
lines changed

9 files changed

+241
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules/
2+
coverage/
3+
tmp/
4+
npm-debug.log*
5+
.DS_Store

.travis.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_js:
2+
- "0.12"
3+
- "4"
4+
sudo: false
5+
language: node_js
6+
script: "npm run test:cov"
7+
after_script: "npm i -g codecov.io && cat ./coverage/lcov.info | codecov"

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2016 Yoshua Wuyts
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# css-extract [![stability][0]][1]
2+
[![npm version][2]][3] [![build status][4]][5] [![test coverage][6]][7]
3+
[![downloads][8]][9] [![js-standard-style][10]][11]
4+
5+
Looks up `require('insert-css')` calls to extract CSS from a browserify bundle
6+
to a file. Useful with `sheetify` or any other package / transform that uses
7+
`insert-css`.
8+
9+
## Command line
10+
```sh
11+
$ browserify -t sheetify/transform -p [ css-extract -o bundle.css ] index.js \
12+
-o bundle.js
13+
```
14+
15+
## JS api
16+
```js
17+
const browserify = require('browserify')
18+
19+
browserify()
20+
.transform('sheetify/transform')
21+
.plugin('css-extract', { out: 'bundle.css' })
22+
.bundle()
23+
```
24+
25+
```js
26+
const browserify = require('browserify')
27+
28+
browserify()
29+
.transform('sheetify/transform')
30+
.plugin('css-extract', { out: createWriteStream })
31+
.bundle()
32+
33+
function createWriteStream () {
34+
return process.stdout
35+
}
36+
```
37+
38+
## Options
39+
- `-o` / `--out`: specify an outfile, defaults to `bundle.css`. Can also be a
40+
function that returns a writable stream from the JavaScript API.
41+
42+
## Installation
43+
```sh
44+
$ npm install css-extract
45+
```
46+
47+
## See Also
48+
- [sheetify](https://github.com/stackcss/sheetify)
49+
- [insert-css](https://github.com/substack/insert-css)
50+
51+
## License
52+
[MIT](https://tldrlegal.com/license/mit-license)
53+
54+
[0]: https://img.shields.io/badge/stability-experimental-orange.svg?style=flat-square
55+
[1]: https://nodejs.org/api/documentation.html#documentation_stability_index
56+
[2]: https://img.shields.io/npm/v/css-extract.svg?style=flat-square
57+
[3]: https://npmjs.org/package/css-extract
58+
[4]: https://img.shields.io/travis/stackcss/css-extract/master.svg?style=flat-square
59+
[5]: https://travis-ci.org/stackcss/css-extract
60+
[6]: https://img.shields.io/codecov/c/github/stackcss/css-extract/master.svg?style=flat-square
61+
[7]: https://codecov.io/github/stackcss/css-extract
62+
[8]: http://img.shields.io/npm/dm/css-extract.svg?style=flat-square
63+
[9]: https://npmjs.org/package/css-extract
64+
[10]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square
65+
[11]: https://github.com/feross/standard

index.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
const isRequire = require('is-require')()
2+
const through = require('through2')
3+
const falafel = require('falafel')
4+
const assert = require('assert')
5+
const fs = require('fs')
6+
7+
module.exports = cssExtract
8+
9+
// Extract CSS from a browserify bundle
10+
// obj -> null
11+
function cssExtract (bundle, opts) {
12+
opts = opts || {}
13+
14+
var outFile = opts.out || opts.o || 'bundle.css'
15+
16+
assert.equal(typeof bundle, 'object', 'bundle should be an object')
17+
assert.equal(typeof opts, 'object', 'opts should be an object')
18+
19+
// every time .bundle is called, attach hook
20+
bundle.on('reset', addHooks)
21+
addHooks()
22+
23+
function addHooks () {
24+
// run before the "debug" step in browserify pipeline
25+
bundle.pipeline.get('debug').unshift(through.obj(write, flush))
26+
const writeStream = (typeof outFile === 'function')
27+
? outFile()
28+
: fs.createWriteStream(outFile)
29+
30+
function write (chunk, enc, cb) {
31+
const css = extract(chunk)
32+
writeStream.write(css)
33+
cb(null, chunk)
34+
}
35+
36+
// close stream and signal end
37+
function flush (cb) {
38+
writeStream.end()
39+
cb()
40+
}
41+
}
42+
}
43+
44+
// extract css from chunks
45+
// obj -> str
46+
function extract (chunk) {
47+
const css = []
48+
const ast = falafel(chunk.source, { ecmaVersion: 6 }, walk)
49+
chunk.source = ast.toString()
50+
return css.join('\n')
51+
52+
function walk (node) {
53+
if (!isRequire(node)) return
54+
if (!node.arguments) return
55+
if (!node.arguments[0]) return
56+
if (node.arguments[0].value !== 'insert-css') return
57+
css.push(node.parent.arguments[0].value)
58+
node.parent.update('0')
59+
}
60+
}

package.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"name": "css-extract",
3+
"version": "1.0.0",
4+
"description": "Extract CSS from a browserify bundle",
5+
"main": "index.js",
6+
"scripts": {
7+
"deps": "dependency-check . && dependency-check . --extra --no-dev",
8+
"test": "standard && npm run deps && NODE_ENV=test node test",
9+
"test:cov": "standard && npm run deps && NODE_ENV=test istanbul cover ./test/index.js"
10+
},
11+
"repository": "stackcss/css-extract",
12+
"keywords": [
13+
"css",
14+
"extract",
15+
"browserify",
16+
"plugin",
17+
"transform",
18+
"sheetify",
19+
"css-modules"
20+
],
21+
"license": "MIT",
22+
"dependencies": {
23+
"falafel": "^1.2.0",
24+
"is-require": "0.0.1",
25+
"through2": "^2.0.1"
26+
},
27+
"devDependencies": {
28+
"bl": "^1.1.2",
29+
"browserify": "^13.0.0",
30+
"dependency-check": "^2.5.1",
31+
"insert-css": "^0.2.0",
32+
"istanbul": "^0.4.2",
33+
"sheetify": "^4.1.0",
34+
"standard": "^6.0.7",
35+
"tape": "^4.5.0"
36+
},
37+
"files": [
38+
"index.js",
39+
"bin/*"
40+
]
41+
}

test/expected.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
._32de081b h1 {
2+
font-family: sans-serif;
3+
}

test/index.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const browserify = require('browserify')
2+
const path = require('path')
3+
const test = require('tape')
4+
const bl = require('bl')
5+
const fs = require('fs')
6+
7+
const cssExtract = require('../')
8+
9+
test('css-extract', function (t) {
10+
t.test('should assert input types', function (t) {
11+
t.plan(2)
12+
t.throws(cssExtract, /object/)
13+
t.throws(cssExtract.bind(null, {}), 123, /object/)
14+
})
15+
16+
t.test('should extract css', function (t) {
17+
t.plan(2)
18+
browserify(path.join(__dirname, 'source.js'))
19+
.transform('sheetify/transform')
20+
.plugin(cssExtract, { out: createWs })
21+
.bundle()
22+
23+
function createWs () {
24+
return bl(function (err, data) {
25+
t.ifError(err, 'no error')
26+
const exPath = path.join(__dirname, './expected.css')
27+
const expected = fs.readFileSync(exPath, 'utf8').trim()
28+
t.equal(String(data), expected, 'extracted all the CSS')
29+
})
30+
}
31+
})
32+
})

test/source.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const sf = require('sheetify')
2+
3+
sf`
4+
h1 {
5+
font-family: sans-serif;
6+
}
7+
`

0 commit comments

Comments
 (0)