Skip to content

Commit 92998c1

Browse files
m90goto-bus-stop
authored andcommitted
Add support for transpiled code (#141)
* setup babel and test * add basic extraction of template strings in babelized code * add support for code transpiled by buble * remove irrelevant section from README * do not use rc file for babel, properly join array of strings * remove block scoped variables
1 parent 6e3b3d0 commit 92998c1

5 files changed

Lines changed: 125 additions & 19 deletions

File tree

README.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -248,14 +248,6 @@ Options:
248248
-t, --transform Consume a sheetify transform
249249
```
250250

251-
## FAQ
252-
### Help, why isn't my inline CSS being transformed?
253-
Well, that might be because you're running `babelify` before running
254-
`sheetify`. `sheetify` looks for template strings in your code and then
255-
transforms them as inline stylesheets. If these are caught and transformed to
256-
ES5 strings by `babelify` then `sheetify` ends up sad. So try running
257-
`sheetify` before `babelify` and you should be good, we hope.
258-
259251
## Installation
260252
```sh
261253
$ npm install sheetify

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@
3636
"xtend": "^4.0.1"
3737
},
3838
"devDependencies": {
39+
"babel-core": "^6.26.0",
40+
"babel-preset-env": "^1.6.1",
41+
"babelify": "^8.0.0",
3942
"browserify": "^13.0.0",
43+
"bubleify": "^1.1.0",
4044
"codecov.io": "^0.1.6",
4145
"concat-stream": "^1.5.1",
4246
"css-extract": "^1.1.2",

test/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ require('./plugins')
44
require('./json')
55
require('./noparse')
66
require('./transform-package')
7+
require('./transpilers')

test/transpilers.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const fs = require('fs')
2+
const browserify = require('browserify')
3+
const test = require('tape')
4+
const path = require('path')
5+
const concat = require('concat-stream')
6+
const through = require('through2')
7+
const babelify = require('babelify')
8+
const bubleify = require('bubleify')
9+
10+
const sheetify = require('..')
11+
12+
test('transpilers', function (t) {
13+
const exPath = path.join(__dirname, 'fixtures/prefix-inline-expected.css')
14+
const bPath = path.join(__dirname, 'fixtures/prefix-inline-source.js')
15+
const expected = fs.readFileSync(exPath, 'utf8').trim()
16+
const bOpts = { browserField: false }
17+
18+
t.test('with babel', function (t) {
19+
t.plan(2)
20+
21+
const ws = concat(function (buf) {
22+
const res = String(buf).trim()
23+
t.equal(res, expected, 'css is equal')
24+
})
25+
26+
function outFn () {
27+
return ws
28+
}
29+
30+
browserify(bPath, bOpts)
31+
.transform(babelify, { presets: ['env'] })
32+
.transform(sheetify)
33+
.transform(function (file) {
34+
return through(function (buf, enc, next) {
35+
const str = buf.toString('utf8')
36+
this.push(str.replace(/sheetify\/insert/, 'insert-css'))
37+
next()
38+
})
39+
})
40+
.plugin('css-extract', { out: outFn })
41+
.bundle(function (err, src) {
42+
t.error(err, 'no error')
43+
})
44+
})
45+
46+
t.test('with buble', function (t) {
47+
t.plan(2)
48+
49+
const ws = concat(function (buf) {
50+
const res = String(buf).trim()
51+
t.equal(res, expected, 'css is equal')
52+
})
53+
54+
function outFn () {
55+
return ws
56+
}
57+
58+
browserify(bPath, bOpts)
59+
.transform(bubleify, { transforms: { dangerousTaggedTemplateString: true } })
60+
.transform(sheetify)
61+
.transform(function (file) {
62+
return through(function (buf, enc, next) {
63+
const str = buf.toString('utf8')
64+
this.push(str.replace(/sheetify\/insert/, 'insert-css'))
65+
next()
66+
})
67+
})
68+
.plugin('css-extract', { out: outFn })
69+
.bundle(function (err, src) {
70+
t.error(err, 'no error')
71+
})
72+
})
73+
})

transform.js

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ const sheetify = require('./index')
1313

1414
module.exports = transform
1515

16+
function isBabelTemplateDefinition (node) {
17+
return node.type === 'CallExpression' &&
18+
node.callee.type === 'Identifier' && node.callee.name === '_taggedTemplateLiteral'
19+
}
20+
1621
// inline sheetify transform for browserify
1722
// obj -> (str, opts) -> str
1823
function transform (filename, options) {
@@ -55,6 +60,7 @@ function transform (filename, options) {
5560
// but tough times call for tough measure. Please don't
5661
// judge us too harshly, we'll work on perf ✨soon✨ -yw
5762
const nodes = []
63+
const babelTemplateObjects = {}
5864
const src = Buffer.concat(bufs).toString('utf8')
5965
var mname = null
6066
var ast
@@ -103,27 +109,57 @@ function transform (filename, options) {
103109
}
104110

105111
function extractTemplateNodes (node) {
106-
if (node.type !== 'TemplateLiteral') return
107-
if (!node.parent || !node.parent.tag) return
108-
if (node.parent.tag.name !== mname) return
112+
var css
113+
var elements
114+
115+
if (node.type === 'VariableDeclarator' && node.init && isBabelTemplateDefinition(node.init)) {
116+
// Babel generates helper calls like
117+
// _taggedTemplateLiteral([":host .class { color: hotpink; }"], [":host .class { color: hotpink; }"])
118+
// we only keep the "cooked" part
119+
babelTemplateObjects[node.id.name] = node.init.arguments[0]
120+
}
109121

110-
const css = [ node.quasis.map(cooked) ]
111-
.concat(node.expressions.map(expr)).join('').trim()
122+
if (node.type === 'TemplateLiteral' && node.parent && node.parent.tag) {
123+
if (node.parent.tag.name !== mname) return
112124

113-
const val = {
114-
css: css,
115-
filename: filename,
116-
opts: xtend(opts),
117-
node: node.parent
125+
css = [ node.quasis.map(cooked) ]
126+
.concat(node.expressions.map(expr)).join('').trim()
127+
128+
nodes.push({
129+
css: css,
130+
filename: filename,
131+
opts: xtend(opts),
132+
node: node.parent
133+
})
118134
}
119135

120-
nodes.push(val)
136+
if (node.type === 'CallExpression' && node.callee.type === 'Identifier' && node.callee.name === mname) {
137+
if (node.arguments[0] && node.arguments[0].type === 'ArrayExpression') {
138+
// Buble generates code like
139+
// sheetify([":host .class { color: hotpink; }"])
140+
elements = node.arguments[0].elements
141+
} else if (node.arguments[0] && node.arguments[0].type === 'Identifier') {
142+
// Babel generates code like
143+
// sheetify(_templateObject)
144+
elements = babelTemplateObjects[node.arguments[0].name].elements
145+
}
146+
147+
if (elements) {
148+
nodes.push({
149+
css: elements.map(function (part) { return part.value }).join(''),
150+
filename: filename,
151+
opts: xtend(opts),
152+
node: node
153+
})
154+
}
155+
}
121156
}
122157

123158
function extractImportNodes (node) {
124159
if (node.type !== 'CallExpression') return
125160
if (!node.callee || node.callee.type !== 'Identifier') return
126161
if (node.callee.name !== mname) return
162+
if (!node.arguments[0] || !node.arguments[0].value) return
127163
var pathOpts = { basedir: path.dirname(filename) }
128164
try {
129165
var resolvePath = cssResolve(node.arguments[0].value, pathOpts)

0 commit comments

Comments
 (0)