├── .gitignore ├── package.json ├── LICENSE ├── README.md └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | coverage/ 3 | tmp/ 4 | npm-debug.log* 5 | .DS_Store -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vueify-extract-css", 3 | "version": "0.2.0", 4 | "description": "Browserify plugin to extract css when using vueify. Derived from stackcss/css-extract", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": "rawcreative/vueify-extract-css", 10 | "keywords": [ 11 | "vueify", 12 | "extract-css", 13 | "css", 14 | "extract", 15 | "browserify", 16 | "plugin", 17 | "transform" 18 | ], 19 | "author": "T. Debo ", 20 | "license": "MIT", 21 | "dependencies": { 22 | "falafel": "^1.2.0", 23 | "is-require": "0.0.1", 24 | "through2": "^2.0.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Original work Copyright (c) 2016 Yoshua Wuyts 4 | Modified work Copyright 2016 Tim Debo 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vueify-extract-css [![stability][0]][1] 2 | 3 | Looks up `require('vueify-insert-css')` calls to extract CSS from a browserify bundle 4 | to a file. 5 | 6 | ## Command line 7 | ```sh 8 | $ browserify -t vueify -p [ vueify-extract-css -o bundle.css ] index.js \ 9 | -o bundle.js 10 | ``` 11 | 12 | ## JS api 13 | ```js 14 | const browserify = require('browserify') 15 | 16 | browserify() 17 | .transform('vueify') 18 | .plugin('vueify-extract-css', { out: 'bundle.css' }) 19 | .bundle() 20 | ``` 21 | 22 | ```js 23 | const browserify = require('browserify') 24 | 25 | browserify() 26 | .transform('vueify') 27 | .plugin('vueify-extract-css', { out: createWriteStream }) 28 | .bundle() 29 | 30 | function createWriteStream () { 31 | return process.stdout 32 | } 33 | ``` 34 | 35 | ## Laravel Elixir 36 | In your gulpfile, along with laravel-elixir-vueify: 37 | ```js 38 | var elixir = require('laravel-elixir'); 39 | require('laravel-elixir-vueify'); 40 | 41 | elixir.config.js.browserify.plugins.push({ 42 | name: 'vueify-extract-css', 43 | options: { 44 | out: 'path/to/extracted/bundle.css' 45 | } 46 | }); 47 | ``` 48 | 49 | 50 | ## Options 51 | - `-o` / `--out`: specify an outfile, defaults to `bundle.css`. Can also be a 52 | function that returns a writable stream from the JavaScript API. 53 | 54 | ## Installation 55 | ```sh 56 | $ npm install vueify-extract-css 57 | ``` 58 | 59 | ## See Also 60 | - [vueify](https://github.com/vuejs/vueify) 61 | - [insert-css](https://github.com/substack/insert-css) 62 | 63 | ## License 64 | [MIT](https://tldrlegal.com/license/mit-license) 65 | 66 | [0]: https://img.shields.io/badge/stability-experimental-orange.svg?style=flat-square 67 | [1]: https://nodejs.org/api/documentation.html#documentation_stability_index 68 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 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 | function cssExtract(bundle, opts) { 10 | opts = opts || {} 11 | 12 | var outFile = opts.out || opts.o || 'bundle.css' 13 | 14 | assert.equal(typeof bundle, 'object', 'bundle should be an object') 15 | assert.equal(typeof opts, 'object', 'opts should be an object') 16 | 17 | bundle.on('reset', addHooks) 18 | addHooks() 19 | 20 | function addHooks() { 21 | // add before pack step as it's the earliest vueify adds the calls to insert css 22 | bundle.pipeline.get('pack').unshift(through.obj(write, flush)) 23 | const writeStream = (typeof outFile === 'function') ? outFile() : fs.createWriteStream(outFile) 24 | 25 | function write(chunk, enc, cb) { 26 | const css = extract(chunk) 27 | writeStream.write(css) 28 | cb(null, chunk) 29 | } 30 | 31 | // close stream and signal end 32 | function flush(cb) { 33 | writeStream.end() 34 | cb() 35 | } 36 | } 37 | } 38 | 39 | 40 | function extract(chunk) { 41 | 42 | if (chunk.source.indexOf('__vueify_insert__') === -1) return '' 43 | 44 | const css = [] 45 | 46 | const ast = falafel(chunk.source, { 47 | ecmaVersion: 6 48 | }, function(node) { 49 | 50 | if(node.type !== 'CallExpression') return 51 | 52 | if(!node.callee.object) return 53 | 54 | if(!node.callee.object.name || node.callee.object.name !== '__vueify_insert__') return 55 | 56 | if (!node.arguments) return 57 | 58 | if (!node.arguments[0]) return 59 | 60 | css.push(node.arguments[0].value) 61 | node.update('0') 62 | }); 63 | 64 | chunk.source = ast.toString() 65 | 66 | return css.join('\n') 67 | } 68 | --------------------------------------------------------------------------------