Skip to content

Commit

Permalink
External StyleSheets: add support for commonjs modules
Browse files Browse the repository at this point in the history
  • Loading branch information
giuseppeg committed Mar 27, 2017
1 parent 9c420ca commit 9962373
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 17 deletions.
16 changes: 12 additions & 4 deletions src/_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,20 @@ export const validateExpression = (expr, scope) => (
expr.traverse(validateExpressionVisitor, scope)
)

export const getExternalReference = (path, imports) => {
export const getExternalReference = (path, {imports, requires}) => {
const {node} = path
if (!t.isIdentifier(node)) {
return null
}

const requireExpr = requires.filter(path => (
path.get('id').node.name === node.name
))[0]

if (requireExpr) {
return requireExpr.get('init').get('arguments')[0].node.value
}

const importExpr = imports.filter(path => {
const specifiers = path.get('specifiers')
if (specifiers.length !== 1) {
Expand Down Expand Up @@ -230,15 +238,15 @@ export const generateAttribute = (name, value) => (
)
)

export const isValidCss = (str) => {
export const isValidCss = str => {
try {
parseCss(str)
return true
} catch (e) {}
} catch (err) {}
return false
}

export const makeSourceMapGenerator = (file) => {
export const makeSourceMapGenerator = file => {
const filename = file.opts.sourceFileName
const generator = new SourceMapGenerator({
file: filename,
Expand Down
35 changes: 29 additions & 6 deletions src/babel-external.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,24 @@ import {
getExpressionText,
restoreExpressions,
makeStyledJsxCss,
globalCss,
isValidCss,
makeSourceMapGenerator,
addSourceMaps
} from './_utils'

export const exportDefaultDeclarationVisitor = ({
path: entryPath,
const visitor = ({
path,
styleId,
types: t,
validate = false,
state
}) => {
const path = entryPath.get('declaration')
if (!path.isTemplateLiteral() || path.isStringLiteral()) {
return
}
const css = getExpressionText(path)
const prefix = `[${MARKUP_ATTRIBUTE_EXTERNAL}~="${styleId}"]`
const isTemplateLiteral = css.modified
const isTemplateLiteral = Boolean(css.modified)
const useSourceMaps = Boolean(state.file.opts.sourceMaps)

let globalCss = css.modified || css
Expand Down Expand Up @@ -54,7 +52,7 @@ export const exportDefaultDeclarationVisitor = ({
filename
)
} else {
localCss = localCss = transform(
localCss = transform(
prefix,
css.modified || css
)
Expand Down Expand Up @@ -85,6 +83,20 @@ export const exportDefaultDeclarationVisitor = ({
)
}

export const exportDefaultDeclarationVisitor = ({path, ...rest}) => (
visitor({
path: path.get('declaration'),
...rest
})
)

export const moduleExportsVisitor = ({path, ...rest}) => (
visitor({
path: path.get('right'),
...rest
})
)

export default function ({types}) {
return {
visitor: {
Expand All @@ -95,6 +107,17 @@ export default function ({types}) {
types,
state
})
},
AssignmentExpression(path, state) {
if (path.get('left').getSource() !== 'module.exports') {
return
}
moduleExportsVisitor({
path,
styleId: hash(state.file.opts.filename),
types,
state
})
}
}
}
Expand Down
35 changes: 32 additions & 3 deletions src/babel.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import hash from 'string-hash'

// Ours
import transform from '../lib/style-transform'
import {exportDefaultDeclarationVisitor} from './babel-external'
import {
exportDefaultDeclarationVisitor,
moduleExportsVisitor
} from './babel-external'

import {
isGlobalEl,
Expand Down Expand Up @@ -34,7 +37,17 @@ export default function ({types: t}) {
inherits: jsx,
visitor: {
ImportDeclaration(path, state) {
state.imports = (state.imports || []).concat(path)
state.imports = (state.imports || []).concat([path])
},
VariableDeclarator(path, state) {
const subpath = path.get('init')
if (
!subpath.isCallExpression() ||
subpath.get('callee').node.name !== 'require'
) {
return
}
state.requires = (state.requires || []).concat([path])
},
JSXOpeningElement(path, state) {
const el = path.node
Expand Down Expand Up @@ -132,7 +145,10 @@ export default function ({types: t}) {
const expression = child.get('expression')

if (t.isIdentifier(expression)) {
let externalSourcePath = getExternalReference(expression, state.imports)
let externalSourcePath = getExternalReference(expression, {
imports: state.imports,
requires: state.requires
})
if (externalSourcePath) {
externalSourcePath = resolvePath(externalSourcePath, state.file.opts.filename)
state.externalStyles.push([
Expand Down Expand Up @@ -299,6 +315,19 @@ export default function ({types: t}) {
validate: true,
state
})
},
AssignmentExpression(path, state) {
if (path.get('left').getSource() !== 'module.exports') {
return
}
const filename = state.file.opts.filename
moduleExportsVisitor({
path,
styleId: hash(filename),
types: t,
validate: true,
state
})
}
}
}
Expand Down
8 changes: 7 additions & 1 deletion test/external.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,14 @@ const transform = (file, opts = {}) => (
test('transpiles external stylesheets', async t => {
const {code} = await transform(
'./fixtures/styles.js',
{ sourceMaps: true }
{sourceMaps: true}
)
const out = await read('./fixtures/styles.out.js')
t.is(code, out.trim())
})

test('transpiles external stylesheets (CommonJS modules)', async t => {
const {code} = await transform('./fixtures/styles2.js')
const out = await read('./fixtures/styles2.out.js')
t.is(code, out.trim())
})
2 changes: 1 addition & 1 deletion test/fixtures/external-stylesheet.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import styles from './styles'
import styles2 from './styles2'
const styles2 = require('./styles2')

export default () => (
<div>
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/external-stylesheet.out.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import _JSXStyle from 'styled-jsx/style';
import styles from './styles';
import styles2 from './styles2';
const styles2 = require('./styles2');

export default (() => <div data-jsx={1144769207} data-jsx-ext={"626947301"}>
<p data-jsx={1144769207} data-jsx-ext={"626947301"}>test</p>
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/styles2.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export default `
module.exports = `
div { font-size: 3em }
`

0 comments on commit 9962373

Please sign in to comment.