Skip to content

Commit

Permalink
Merge pull request #15 from styled-components/minify-css
Browse files Browse the repository at this point in the history
Minify css
  • Loading branch information
vdanchenkov authored Dec 20, 2016
2 parents 69192f9 + 126b045 commit eee3523
Show file tree
Hide file tree
Showing 24 changed files with 186 additions and 28 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,22 @@ If you don't need server-side rendering, you can disable it with the `ssr` optio
}
```

### Minify styles

By default, plugin minifies styles in template literals. This operation may potentially break your styles in some rare cases, so we recommend to keep this option enabled in development if it's enabled in the production build. You will not see the effect of minification in generated style tags, it solely affects the presentation of styles inside js code.

You can disable minification if you don't need it with minify option:

```JSON
{
"plugins": [
["styled-components", {
"minify": false
}]
]
}
```

## License

Licensed under the MIT License, Copyright © 2016 Vladimir Danchenkov and Maximilian Stoiber.
Expand Down
49 changes: 33 additions & 16 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import hash from './utils/hash'
import getTarget from './utils/get-target'
import getName from './utils/get-name'
import minify from './utils/minify'

const blockName = (file) => {
return file.opts.basename !== 'index' ?
Expand All @@ -18,23 +19,39 @@ export default function({ types: t }) {
return {
visitor: {
Program(path, state) {
// Default imported variable name to "styled", adjust based on import below
let importedVariableName = 'styled'
const importedVariableNames = {
default: 'styled',
css: 'css',
keyframes: 'keyframes'
}

const isStyled = (tag) => (
(t.isMemberExpression(tag) && tag.object.name === importedVariableNames.default) ||
(t.isCallExpression(tag) && tag.callee.name === importedVariableNames.default)
)

const isStyled = (tag) => (tag.object && tag.object.name === importedVariableName) || (tag.callee && tag.callee.name === importedVariableName)
const isHelper = (tag) => (
t.isIdentifier(tag) && (
tag.name === importedVariableNames.css ||
tag.name === importedVariableNames.keyframes
)
)

path.traverse({
ImportDeclaration(path) {
// Is the styled-components import!
if (path.node.source.value === 'styled-components') {
// If the default is imported it's at defaultImport[0], otherwise defaultImport is empty
const defaultImport = path.get('specifiers').find((specifier) => {
return specifier.isImportDefaultSpecifier() || specifier.isImportSpecifier() && specifier.node.imported.name === 'default'
path.get('specifiers').forEach((specifier) => {
let importedName
if (specifier.isImportDefaultSpecifier()) {
importedName = 'default'
} else if (specifier.isImportSpecifier()) {
importedName = specifier.node.imported.name
}
if (importedVariableNames.hasOwnProperty(importedName)) {
importedVariableNames[importedName] = specifier.node.local.name
}
})
if (defaultImport) {
// Save the imported name
importedVariableName = defaultImport.node.local.name
}
}
}
})
Expand All @@ -43,17 +60,17 @@ export default function({ types: t }) {
displayName: getOption(state.opts, 'displayName'),
ssr: getOption(state.opts, 'ssr'),
fileName: getOption(state.opts, 'fileName'),
}

if (!options.ssr && !options.displayName) {
return
minify: getOption(state.opts, 'minify')
}

path.traverse({
TaggedTemplateExpression(path, { file }) {
const tag = path.node.tag
if (options.minify && (isStyled(tag) || isHelper(tag))) {
minify(path.node.quasi)
}

if (!isStyled(tag)) return
if (!(isStyled(tag) && (options.ssr || options.displayName))) return

// Get target
const target = getTarget(path.node.tag)
Expand Down Expand Up @@ -81,7 +98,7 @@ export default function({ types: t }) {
}

const call = t.callExpression(
t.identifier(importedVariableName),
t.identifier(importedVariableNames.default),
[ t.objectExpression(styledCallProps) ]
)

Expand Down
8 changes: 8 additions & 0 deletions src/utils/minify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as t from 'babel-types'

export default (teplateLiteral) => {
for (let element of teplateLiteral.quasis) {
element.value.raw = element.value.raw.replace(/(\\r|\\n|\r|\n)\s*/g, '')
element.value.cooked = element.value.cooked.replace(/[\r\n]\s*/g, '')
}
}
2 changes: 1 addition & 1 deletion test/fixtures/01-add-display-names/after.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const Test = styled({
target: 'div',
displayName: 'Test'
})` width: 100%;`;
})`width: 100%;`;
const Test2 = styled({
target: 'div',
displayName: 'Test2'
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/01-add-display-names/before.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const Test = styled.div` width: 100%;`;
const Test = styled.div`width: 100%;`;
const Test2 = styled('div')``;
const Test3 = true ? styled.div`` : styled.div``;
const styles = { One: styled.div`` }
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/02-add-identifier/after.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const Test = styled({
target: "div",
identifier: "Test-137hlza"
})` width: 100%;`;
})`width: 100%;`;
const Test2 = true ? styled({
target: "div",
identifier: "Test2-bjbly"
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/02-add-identifier/before.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const Test = styled.div` width: 100%;`;
const Test = styled.div`width: 100%;`;
const Test2 = true ? styled.div`` : styled.div``;
const styles = { One: styled.div`` }
let Component;
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/03-add-identifier-and-display-name/after.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const Test = styled({
target: "div",
displayName: "Test",
identifier: "Test-18z24ew"
})` width: 100%;`;
})`width: 100%;`;
const Test2 = true ? styled({
target: "div",
displayName: "Test2",
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/03-add-identifier-and-display-name/before.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const Test = styled.div` width: 100%;`;
const Test = styled.div`width: 100%;`;
const Test2 = true ? styled.div`` : styled.div``;
const styles = { One: styled.div`` }
let Component;
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/04-track-the-imported-variable/after.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const Test = s({
target: "div",
displayName: "Test",
identifier: "Test-62sgar"
})` width: 100%;`;
})`width: 100%;`;
const Test2 = true ? s({
target: "div",
displayName: "Test2",
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/04-track-the-imported-variable/before.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import s from "styled-components";

const Test = s.div` width: 100%;`;
const Test = s.div`width: 100%;`;
const Test2 = true ? s.div`` : s.div``;
const styles = { One: s.div`` }
let Component;
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/05-use-file-name/after.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const Test = styled({
target: "div",
displayName: "before__Test",
identifier: "before__Test-102oti6"
})` color: red;`;
})`color: red;`;
styled({
target: "div",
displayName: "before",
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/05-use-file-name/before.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import styled from "styled-components";

const Test = styled.div` color: red;`;
const Test = styled.div`color: red;`;
styled.div``;
export default styled.button``;
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ const Test = s({
target: 'div',
displayName: 'before__Test',
identifier: 'before__Test-1ex1ta1'
})` width: 100%;`;
})`width: 100%;`;
import { default as s, css } from 'styled-components';
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
const Test = s.div` width: 100%;`;
const Test = s.div`width: 100%;`;
import { default as s, css } from 'styled-components';
11 changes: 11 additions & 0 deletions test/fixtures/08-minify-css-to-use-with-transpilation/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"presets": [
"es2015"
],
"plugins": [
["../../../src", {
"ssr": false,
"displayName": false
}]
]
}
26 changes: 26 additions & 0 deletions test/fixtures/08-minify-css-to-use-with-transpilation/after.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

var _templateObject = _taggedTemplateLiteral(['width: 100%;'], ['width: 100%;']),
_templateObject2 = _taggedTemplateLiteral(['content: " ', ' ";'], ['content: " ', ' ";']),
_templateObject3 = _taggedTemplateLiteral(['content: " ', ' ";color: red;'], ['content: " ', ' ";color: red;']),
_templateObject4 = _taggedTemplateLiteral(['&:hover {color: blue;}'], ['&:hover {color: blue;}']);

var _styledComponents = require('styled-components');

var _styledComponents2 = _interopRequireDefault(_styledComponents);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }

var Simple = _styledComponents2.default.div(_templateObject);

var Interpolation = _styledComponents2.default.div(_templateObject2, function (props) {
return props.text;
});

var SpecialCharacters = _styledComponents2.default.div(_templateObject3, function (props) {
return props.text;
});

var Parens = _styledComponents2.default.div(_templateObject4);
19 changes: 19 additions & 0 deletions test/fixtures/08-minify-css-to-use-with-transpilation/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import styled from 'styled-components';

const Simple = styled.div`
width: 100%;
`;

const Interpolation = styled.div`
content: " ${props => props.text} ";
`;

const SpecialCharacters = styled.div`
content: " ${props => props.text} ";\n color: red;
`;

const Parens = styled.div`
&:hover {
color: blue;
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"plugins": [
["../../../src", {
"ssr": false,
"displayName": false
}]
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import styled from 'styled-components';

const Simple = styled.div`width: 100%;`;

const Interpolation = styled.div`content: " ${ props => props.text } ";`;

const SpecialCharacters = styled.div`content: " ${ props => props.text } ";color: red;`;

const Parens = styled.div`&:hover {color: blue;}color: red;`;
20 changes: 20 additions & 0 deletions test/fixtures/09-minify-css-to-use-without-transpilation/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import styled from 'styled-components';

const Simple = styled.div`
width: 100%;
`;

const Interpolation = styled.div`
content: " ${props => props.text} ";
`;

const SpecialCharacters = styled.div`
content: " ${props => props.text} ";\n color: red;
`;

const Parens = styled.div`
&:hover {
color: blue;
}
color: red;
`;
8 changes: 8 additions & 0 deletions test/fixtures/10-minify-css-in-helpers/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"plugins": [
["../../../src", {
"ssr": false,
"displayName": false
}]
]
}
5 changes: 5 additions & 0 deletions test/fixtures/10-minify-css-in-helpers/after.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { css, keyframes } from 'styled-components';

const key = keyframes`to {transform: rotate(360deg);}`;

const color = css`color: ${ theColor };`;
11 changes: 11 additions & 0 deletions test/fixtures/10-minify-css-in-helpers/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { css, keyframes } from 'styled-components';

const key = keyframes`
to {
transform: rotate(360deg);
}
`;

const color = css`
color: ${theColor};
`;

0 comments on commit eee3523

Please sign in to comment.