Skip to content

Commit

Permalink
Output dir support (#583)
Browse files Browse the repository at this point in the history
* Output dir support for babel plugin

* fix support for outputdir

* Update tests

* update docs

* Review fixes

* Fix unit tests

* Fix for babel 7
  • Loading branch information
wardpeet authored and Kye Hohenberger committed Mar 7, 2018
1 parent 954f175 commit 4cd357b
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 24 deletions.
7 changes: 7 additions & 0 deletions packages/babel-plugin-emotion/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ _Defaults Shown_
"autoLabel": false,
"labelFormat": "[local]",
"extractStatic": false,
"outputDir": '',
"importedNames": {
"styled": "styled",
"css": "css",
Expand Down Expand Up @@ -287,6 +288,12 @@ This option enables the following:

[**Documentation**](https://emotion.sh/docs/extract-static)

### `outputDir`

`string`, defaults to `''`

This option only works when `extractStatic` is set to true. This option allows `babel-plugin-emotion` to set a different directory to where the extracted css files are saved to.

### `importedNames`

`object`, defaults to
Expand Down
1 change: 1 addition & 0 deletions packages/babel-plugin-emotion/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"convert-source-map": "^1.5.0",
"emotion-utils": "^9.0.1",
"find-root": "^1.1.0",
"mkdirp": "^0.5.1",
"source-map": "^0.5.7",
"touch": "^1.0.0"
},
Expand Down
45 changes: 36 additions & 9 deletions packages/babel-plugin-emotion/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import fs from 'fs'
import nodePath from 'path'
import findRoot from 'find-root'
import mkdirp from 'mkdirp'
import { touchSync } from 'touch'
import { addSideEffect } from '@babel/helper-module-imports'
import {
Expand Down Expand Up @@ -495,19 +496,45 @@ export default function(babel: Babel) {
exit(path: BabelPath, state: EmotionBabelPluginPass) {
if (state.staticRules.length !== 0) {
const toWrite = state.staticRules.join('\n').trim()
const filenameArr = path.hub.file.opts.filename.split('.')
filenameArr.pop()
filenameArr.push('emotion', 'css')
const cssFilename = filenameArr.join('.')
const exists = fs.existsSync(cssFilename)
addSideEffect(path, './' + nodePath.basename(cssFilename))
let cssFilename = path.hub.file.opts.generatorOpts
? path.hub.file.opts.generatorOpts.sourceFileName
: path.hub.file.opts.sourceFileName
let cssFileOnDisk
let importPath

const cssFilenameArr = cssFilename.split('.')
// remove the extension
cssFilenameArr.pop()
// add emotion.css as an extension
cssFilenameArr.push('emotion.css')

cssFilename = cssFilenameArr.join('.')

if (state.opts.outputDir) {
const relativeToSourceDir = nodePath.relative(
nodePath.dirname(cssFilename),
state.opts.outputDir
)
importPath = nodePath.join(relativeToSourceDir, cssFilename)
cssFileOnDisk = nodePath.resolve(cssFilename, '..', importPath)
} else {
importPath = `./${nodePath.basename(cssFilename)}`
cssFileOnDisk = nodePath.resolve(cssFilename)
}

const exists = fs.existsSync(cssFileOnDisk)
addSideEffect(path, importPath)
if (
exists ? fs.readFileSync(cssFilename, 'utf8') !== toWrite : true
exists ? fs.readFileSync(cssFileOnDisk, 'utf8') !== toWrite : true
) {
if (!exists) {
touchSync(cssFilename)
if (state.opts.outputDir) {
mkdirp.sync(nodePath.dirname(cssFileOnDisk))
}

touchSync(cssFileOnDisk)
}
fs.writeFileSync(cssFilename, toWrite)
fs.writeFileSync(cssFileOnDisk, toWrite)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ exports[`babel plugin fs creates and writes to the css file when it does not exi
\\"css-1yfv4zm\\";"
`;
exports[`babel plugin fs creates and writes to the custom output dir when it does not exist 1`] = `".css-1yfv4zm{margin:12px 48px;color:#ffffff;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;color:blue;name:class;}"`;
exports[`babel plugin fs creates and writes to the custom output dir when it does not exist 2`] = `
"require(\\"tmpdir/fs.test.emotion.css\\");
\\"css-1yfv4zm\\";"
`;
exports[`babel plugin fs does not write to the css file when it is the same as is already written 1`] = `
"require(\\"./fs.test.emotion.css\\");
Expand Down
63 changes: 48 additions & 15 deletions packages/babel-plugin-emotion/test/fs.test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
// @flow
import { transform } from 'babel-core'
import fs from 'fs'
import path from 'path'
import mkdirp from 'mkdirp'
import touch from 'touch'
import plugin from 'babel-plugin-emotion'

jest.mock('fs').mock('touch')
fs.statSync.mockReturnValue({ isFile: () => false })
jest
.mock('fs')
.mock('mkdirp')
.mock('touch')

const basic = `
css\`
Expand All @@ -18,28 +22,57 @@ css\`
\``

let output

const filenameArr = __filename.split('.')
filenameArr.pop()
filenameArr.push('emotion', 'css')
const cssFilename = filenameArr.join('.')
const cssFilepath = path.resolve(
process.cwd(),
path.basename(filenameArr.join('.'))
)

describe('babel plugin fs', () => {
beforeEach(() => {
jest.clearAllMocks()
fs.statSync.mockReturnValue({ isFile: () => false })
})

test('creates and writes to the css file when it does not exist', () => {
fs.existsSync.mockReturnValueOnce(false)
const { code } = transform(basic, {
plugins: [[plugin, { extractStatic: true }]],
filename: __filename,
babelrc: false
})
expect(fs.existsSync).toBeCalledWith(cssFilename)
expect(touch.sync).toBeCalledWith(cssFilename)

expect(fs.existsSync).toBeCalledWith(cssFilepath)
expect(mkdirp.sync).not.toBeCalledWith()
expect(touch.sync).toBeCalledWith(cssFilepath)
expect(fs.writeFileSync).toHaveBeenCalled()
expect(fs.writeFileSync.mock.calls[0][0]).toBe(cssFilename)
expect(fs.writeFileSync.mock.calls[0][0]).toBe(cssFilepath)
expect(fs.writeFileSync.mock.calls[0][1]).toMatchSnapshot()
output = fs.writeFileSync.mock.calls[0][1]
expect(code).toMatchSnapshot()
})

test('creates and writes to the custom output dir when it does not exist', () => {
const ABSOLUTE_PATH = './tmpdir'
fs.existsSync.mockReturnValueOnce(false)
const { code } = transform(basic, {
plugins: [[plugin, { extractStatic: true, outputDir: ABSOLUTE_PATH }]],
filename: __filename,
babelrc: false
})

const newFilePath = path.resolve(ABSOLUTE_PATH, path.basename(cssFilepath))
expect(fs.existsSync).toBeCalledWith(newFilePath)
expect(mkdirp.sync).toBeCalledWith(path.dirname(newFilePath))
expect(touch.sync).toBeCalledWith(newFilePath)
expect(fs.writeFileSync).toHaveBeenCalled()
expect(fs.writeFileSync.mock.calls[0][0]).toBe(newFilePath)
expect(fs.writeFileSync.mock.calls[0][1]).toMatchSnapshot()
expect(code).toMatchSnapshot()
})

test('writes to the css file when it does exist ', () => {
fs.existsSync.mockReturnValueOnce(true)
fs.readFileSync.mockReturnValueOnce('')
Expand All @@ -48,11 +81,11 @@ describe('babel plugin fs', () => {
filename: __filename,
babelrc: false
})
expect(fs.existsSync).toBeCalledWith(cssFilename)
expect(touch.sync).toHaveBeenCalledTimes(1)
expect(fs.writeFileSync).toHaveBeenCalledTimes(2)
expect(fs.writeFileSync.mock.calls[1][0]).toBe(cssFilename)
expect(fs.writeFileSync.mock.calls[1][1]).toMatchSnapshot()
expect(fs.existsSync).toBeCalledWith(cssFilepath)
expect(touch.sync).not.toHaveBeenCalled()
expect(fs.writeFileSync).toHaveBeenCalledTimes(1)
expect(fs.writeFileSync.mock.calls[0][0]).toBe(cssFilepath)
expect(fs.writeFileSync.mock.calls[0][1]).toMatchSnapshot()
expect(code).toMatchSnapshot()
})
test('does not write to the css file when it is the same as is already written', () => {
Expand All @@ -63,9 +96,9 @@ describe('babel plugin fs', () => {
filename: __filename,
babelrc: false
})
expect(fs.existsSync).toBeCalledWith(cssFilename)
expect(touch.sync).toHaveBeenCalledTimes(1)
expect(fs.writeFileSync).toHaveBeenCalledTimes(2)
expect(fs.existsSync).toBeCalledWith(cssFilepath)
expect(touch.sync).not.toHaveBeenCalled()
expect(fs.writeFileSync).not.toHaveBeenCalled()
expect(code).toMatchSnapshot()
})
})

0 comments on commit 4cd357b

Please sign in to comment.