Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/dist/
/coverage/
/.nyc_output/
/test/fixtures/
/test/fixtures*/
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,13 @@
"mocha": "^3.2.0",
"nyc": "^10.0.0",
"postcss": "^5.2.9",
"postcss-modules": "^0.6.2",
"sinon": "^1.17.7",
"sinon-chai": "^2.8.0"
"postcss-modules": "^0.6.2"
},
"peerDependencies": {
"postcss": "^5.2.9"
},
"dependencies": {
"deasync": "^0.1.9",
"debug": "^2.6.0",
"postcss-load-config": "^1.1.0"
}
Expand Down
94 changes: 48 additions & 46 deletions src/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,40 @@ import {
dirname,
extname,
resolve,
join,
} from 'path';

import {
execFileSync,
spawn,
} from 'child_process';

// note: socket path is important to keep short as it will be truncated if it
// exceeds certain platform limits. for this reason, we're writing to /tmp
// instead of using os.tmpdir (which can, on platforms like darwin, be quite
// long & per-process).
const projectId = process.cwd().toLowerCase().replace(/[^a-z]/g, '');
const socketName = `bptp-${projectId}.sock`;
const socketPath = join('/tmp', socketName);

const nodeExecutable = process.argv[0];
const clientExcutable = join(__dirname, 'postcss-client.js');
const serverExcutable = join(__dirname, 'postcss-server.js');

let server;

const startServer = () => {
server = spawn(nodeExecutable, [serverExcutable, socketPath], {
env: process.env, // eslint-disable-line no-process-env
stdio: 'inherit',
});

server.unref();
};
import fs from 'fs';
import util from 'util';
import postcss from 'postcss';
import loadConfig from 'postcss-load-config';
import deasync from 'deasync';

const sync = <T>(promise: Promise<T>): T => {
let success: { result: T }, error: Error;

promise.then(
(result: T) => { success = { result }; },
(err: Error) => { error = err; },
);
deasync.loopWhile(() => !(success || error));

const stopServer = () => {
if (!server) { return; }
if (!success) {
throw error;
}

server.kill();
server = null;
process.removeListener('exit', stopServer);
return success.result;
};

const launchServer = () => {
if (server) { return; }
const streams = { stderr: process.stderr }; // overwritable by tests
const error = (...args: any) => {
let prefix = 'babel-plugin-transform-postcss: ';
const message = util.format(...args);

startServer();
if (streams.stderr.isTTY) {
prefix = `\x1b[31m${prefix}\x1b[0m`;
}

process.on('exit', stopServer);
streams.stderr.write(`${prefix}${message}\n`);
};

export default function transformPostCSS({ types: t }: any): any {
Expand All @@ -69,16 +58,30 @@ export default function transformPostCSS({ types: t }: any): any {
const stylesheetExtension = extname(stylesheetPath);

if (extensions.indexOf(stylesheetExtension) !== -1) {
launchServer();

let config, source;
let tokens = {};
const requiringFile = file.opts.filename;
const cssFile = resolve(dirname(requiringFile), stylesheetPath);
const data = JSON.stringify({ cssFile });
const execArgs = [clientExcutable, socketPath, data];
const result = execFileSync(nodeExecutable, execArgs, {
env: process.env, // eslint-disable-line no-process-env
}).toString('utf8');
const tokens = JSON.parse(result || '{}');
const extractModules = (_, resultTokens: any) => {
tokens = resultTokens;
};

try {
config = sync(loadConfig({ extractModules }, dirname(cssFile)));
source = // eslint-disable-next-line no-sync
fs.readFileSync(cssFile, 'utf8');
}
catch (err) {
error(err.stack);

return;
}

const { plugins, postcssOpts } = config;
const runner = postcss(plugins);

sync(runner.process(source, postcssOpts));

const expression = path.findParent((test) => (
test.isVariableDeclaration() ||
Expand All @@ -104,6 +107,5 @@ export default function transformPostCSS({ types: t }: any): any {
}

export {
startServer,
stopServer,
streams as _streams,
};
57 changes: 0 additions & 57 deletions src/postcss-client.js

This file was deleted.

108 changes: 0 additions & 108 deletions src/postcss-server.js

This file was deleted.

2 changes: 0 additions & 2 deletions test/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,5 @@

import chai from 'chai';
import chaiString from 'chai-string';
import sinonChai from 'sinon-chai';

chai.use(chaiString);
chai.use(sinonChai);
1 change: 1 addition & 0 deletions test/fixtures-no-config/require.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
var styles = require('./simple.css');
1 change: 1 addition & 0 deletions test/fixtures/missingcss.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
var styles = require('./nofile.css');
3 changes: 3 additions & 0 deletions test/fixtures/nocss.expected.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use strict';

var styles = require('./simple');
14 changes: 10 additions & 4 deletions test/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import fs from 'fs';
import path from 'path';
import * as babel from 'babel-core';

const fixtures = path.join(__dirname, 'fixtures');

export const transform = (filename: string): Promise<string> => {
export const transform = (
filename: string,
dirname: string='fixtures',
): Promise<string> => {
const fixtures = path.join(__dirname, dirname);
const file = path.join(fixtures, filename);
const options = {
presets: [ ['env', { targets: { node: 'current' } }] ],
Expand All @@ -25,7 +27,11 @@ export const transform = (filename: string): Promise<string> => {
});
};

export const read = (filename: string): Promise<string> => {
export const read = (
filename: string,
dirname: string='fixtures',
): Promise<string> => {
const fixtures = path.join(__dirname, dirname);
const file = path.join(fixtures, filename);
const options = {
encoding: 'utf8',
Expand Down
Loading