Skip to content

Commit

Permalink
[scss] Adds autoprefixer support and improves watcher (#21656)
Browse files Browse the repository at this point in the history
This adds support for autoprefixer which we have been using in Webpack.

Additionally, we have improved the watching functionality and now update builds based directly on their dependencies an not an assumption that the files are children.

Signed-off-by: Tyler Smalley <tyler.smalley@elastic.co>
  • Loading branch information
tylersmalley authored Aug 10, 2018
1 parent d605a9c commit 8769110
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 74 deletions.
2 changes: 2 additions & 0 deletions .browserslistrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
last 2 versions
> 5%
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
"angular-route": "1.4.7",
"angular-sanitize": "1.5.7",
"angular-sortable-view": "0.0.15",
"autoprefixer": "6.5.4",
"autoprefixer": "^9.1.0",
"babel-core": "6.21.0",
"babel-loader": "7.1.2",
"babel-polyfill": "6.20.0",
Expand Down Expand Up @@ -317,6 +317,7 @@
"nock": "8.0.0",
"node-sass": "^4.9.0",
"pixelmatch": "4.0.2",
"postcss": "^7.0.2",
"prettier": "^1.14.0",
"proxyquire": "1.7.11",
"simple-git": "1.37.0",
Expand Down
15 changes: 6 additions & 9 deletions src/dev/build/tasks/transpile_scss_task.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,12 @@ export const TranspileScssTask = {
const { spec$ } = findPluginSpecs({ plugins: { scanDirs, paths: [] } });
const enabledPlugins = await spec$.pipe(toArray()).toPromise();

function onSuccess(builder) {
log.info(`Compiled SCSS: ${builder.source}`);
try {
const bundles = await buildAll(enabledPlugins);
bundles.forEach(bundle => log.info(`Compiled SCSS: ${bundle.source}`));
} catch (error) {
const { message, line, file } = error;
throw new Error(`${message} on line ${line} of ${file}`);
}

function onError(builder, e) {
log.error(`Compiling SCSS failed: ${builder.source}`);
throw e;
}

await buildAll(enabledPlugins, { onSuccess, onError });
}
};
37 changes: 17 additions & 20 deletions src/server/sass/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ import path from 'path';
import { promisify } from 'util';
import fs from 'fs';
import sass from 'node-sass';
import minimatch from 'minimatch';
import autoprefixer from 'autoprefixer';
import postcss from 'postcss';

const renderSass = promisify(sass.render);
const writeFile = promisify(fs.writeFile);

export class Build {
constructor(source, options = {}) {
constructor(source) {
this.source = source;
this.onSuccess = options.onSuccess || (() => {});
this.onError = options.onError || (() => {});
this.includedFiles = [source];
}

outputPath() {
Expand All @@ -46,8 +46,8 @@ export class Build {
return path.join(path.dirname(this.source), '**', '*.s{a,c}ss');
}

async buildIfInPath(path) {
if (minimatch(path, this.getGlob())) {
async buildIfIncluded(path) {
if (this.includedFiles && this.includedFiles.includes(path)) {
await this.build();
return true;
}
Expand All @@ -60,23 +60,20 @@ export class Build {
*/

async build() {
try {
const outFile = this.outputPath();
const outFile = this.outputPath();
const rendered = await renderSass({
file: this.source,
outFile,
sourceMap: true,
sourceMapEmbed: true,
});

const rendered = await renderSass({
file: this.source,
outFile,
sourceMap: true,
sourceMapEmbed: true,
sourceComments: true,
});

await writeFile(outFile, rendered.css);
const prefixed = postcss([ autoprefixer ]).process(rendered.css);

this.onSuccess(this);
} catch(e) {
this.onError(this, e);
}
this.includedFiles = rendered.stats.includedFiles;

await writeFile(outFile, prefixed.css);

return this;
}
Expand Down
1 change: 0 additions & 1 deletion src/server/sass/build.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ describe('SASS builder', () => {
expect(sass.render.mock.calls[0][0]).toEqual({
file: '/foo/style.sass',
outFile: '/foo/style.css',
sourceComments: true,
sourceMap: true,
sourceMapEmbed: true
});
Expand Down
21 changes: 10 additions & 11 deletions src/server/sass/build_all.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,18 @@
import { Build } from './build';
import { collectUiExports } from '../../ui/ui_exports';

export function buildAll(enabledPluginSpecs, { onSuccess, onError }) {
export async function buildAll(enabledPluginSpecs) {
const { uiAppSpecs = [] } = collectUiExports(enabledPluginSpecs);

return Promise.all(uiAppSpecs.reduce((acc, uiAppSpec) => {
const bundles = await Promise.all(uiAppSpecs.map(async uiAppSpec => {
if (!uiAppSpec.styleSheetPath) {
return acc;
return;
}

const builder = new Build(uiAppSpec.styleSheetPath, {
onSuccess,
onError,
});
const bundle = new Build(uiAppSpec.styleSheetPath);
await bundle.build();

return bundle;
}));

return [...acc, builder.build()];
}, []));
}
return bundles.filter(v => v);
}
69 changes: 55 additions & 14 deletions src/server/sass/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,22 @@ export async function sassMixin(kbnServer, server, config) {
}

const { buildAll } = require('./build_all');
let scssBundles = [];
let trackedFiles = new Set();

function onSuccess(builder) {
server.log(['info', 'scss'], `Compiled CSS: ${builder.source}`);
}
try {
scssBundles = await buildAll(kbnServer.pluginSpecs);

function onError(builder, error) {
server.log(['warning', 'scss'], `Compiling CSS failed: ${builder.source}`);
server.log(['warning', 'scss'], error);
}
scssBundles.forEach(bundle => {
bundle.includedFiles.forEach(file => trackedFiles.add(file));
server.log(['info', 'scss'], `Compiled CSS: ${bundle.source}`);
});
} catch(error) {
const { message, line, file } = error;

const scssBundles = await buildAll(kbnServer.pluginSpecs, { onSuccess, onError });
trackedFiles.add(file);
server.log(['warning', 'scss'], `${message} on line ${line} of ${file}`);
}


/**
Expand All @@ -62,15 +67,51 @@ export async function sassMixin(kbnServer, server, config) {
const { FSWatcher } = require('chokidar');
const watcher = new FSWatcher({ ignoreInitial: true });

scssBundles.forEach(bundle => {
watcher.add(bundle.getGlob());
});
watcher.add([...trackedFiles]);

watcher.on('all', async (event, path) => {
for (let i = 0; i < scssBundles.length; i++) {
if (await scssBundles[i].buildIfInPath(path)) {
const currentlyTrackedFiles = new Set();

server.log(['debug', 'scss'], `${path} triggered ${event}`);

// build bundles containing the changed file
await Promise.all(scssBundles.map(async bundle => {
try {
if (await bundle.buildIfIncluded(path)) {
bundle.includedFiles.forEach(file => currentlyTrackedFiles.add(file));
server.log(['info', 'scss'], `Compiled ${bundle.source} due to change in ${path}`);
}
} catch(error) {
const { message, line, file } = error;
currentlyTrackedFiles.add(file);
server.log(['warning', 'scss'], `${message} on line ${line} of ${file}`);
}
}, []));

/**
* update watchers
*/

// un-watch files no longer included in any bundle
trackedFiles.forEach(file => {
if (currentlyTrackedFiles.has(file)) {
return;
}
}

watcher.unwatch(file);
server.log(['debug', 'scss'], `No longer watching ${file}`);
});

// watch files not previously included in any bundle
currentlyTrackedFiles.forEach(file => {
if (trackedFiles.has(file)) {
return;
}

watcher.add(file);
server.log(['debug', 'scss'], `Now watching ${file}`);
});

trackedFiles = currentlyTrackedFiles;
});
}
60 changes: 42 additions & 18 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1109,17 +1109,6 @@ autolinker@~0.15.0:
version "0.15.3"
resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-0.15.3.tgz#342417d8f2f3461b14cf09088d5edf8791dc9832"

autoprefixer@6.5.4:
version "6.5.4"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.5.4.tgz#1386eb6708ccff36aefff70adc694ecfd60af1b0"
dependencies:
browserslist "~1.4.0"
caniuse-db "^1.0.30000597"
normalize-range "^0.1.2"
num2fraction "^1.2.2"
postcss "^5.2.6"
postcss-value-parser "^3.2.3"

autoprefixer@^6.3.1:
version "6.7.7"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014"
Expand All @@ -1131,6 +1120,17 @@ autoprefixer@^6.3.1:
postcss "^5.2.16"
postcss-value-parser "^3.2.3"

autoprefixer@^9.1.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.1.0.tgz#566a70d1148046b96b31efa08090f1999ffb6d8c"
dependencies:
browserslist "^4.0.1"
caniuse-lite "^1.0.30000872"
normalize-range "^0.1.2"
num2fraction "^1.2.2"
postcss "^7.0.2"
postcss-value-parser "^3.2.3"

aws-sign2@~0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
Expand Down Expand Up @@ -2277,11 +2277,13 @@ browserslist@^1.3.6, browserslist@^1.4.0, browserslist@^1.5.2, browserslist@^1.7
caniuse-db "^1.0.30000639"
electron-to-chromium "^1.2.7"

browserslist@~1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.4.0.tgz#9cfdcf5384d9158f5b70da2aa00b30e8ff019049"
browserslist@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.0.1.tgz#61c05ce2a5843c7d96166408bc23d58b5416e818"
dependencies:
caniuse-db "^1.0.30000539"
caniuse-lite "^1.0.30000865"
electron-to-chromium "^1.3.52"
node-releases "^1.0.0-alpha.10"

bser@^2.0.0:
version "2.0.0"
Expand Down Expand Up @@ -2527,10 +2529,14 @@ caniuse-api@^1.5.2:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"

caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000539, caniuse-db@^1.0.30000597, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
version "1.0.30000815"
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000815.tgz#0e218fa133d0d071c886aa041b435258cc746891"

caniuse-lite@^1.0.30000865, caniuse-lite@^1.0.30000872:
version "1.0.30000874"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000874.tgz#a641b1f1c420d58d9b132920ef6ba87bbdcd2223"

capture-stack-trace@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d"
Expand Down Expand Up @@ -4311,6 +4317,10 @@ electron-to-chromium@^1.2.7:
version "1.3.39"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.39.tgz#d7a4696409ca0995e2750156da612c221afad84d"

electron-to-chromium@^1.3.52:
version "1.3.56"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.56.tgz#aad1420d23e9dd8cd2fc2bc53f4928adcf85f02f"

elegant-spinner@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
Expand Down Expand Up @@ -9405,6 +9415,12 @@ node-pre-gyp@^0.6.39:
tar "^2.2.1"
tar-pack "^3.4.0"

node-releases@^1.0.0-alpha.10:
version "1.0.0-alpha.10"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.0-alpha.10.tgz#61c8d5f9b5b2e05d84eba941d05b6f5202f68a2a"
dependencies:
semver "^5.3.0"

node-sass@^4.9.0:
version "4.9.0"
resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.9.0.tgz#d1b8aa855d98ed684d6848db929a20771cc2ae52"
Expand Down Expand Up @@ -10501,7 +10517,7 @@ postcss-zindex@^2.0.1:
postcss "^5.0.4"
uniqs "^2.0.0"

postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.16, postcss@^5.2.6:
postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.16:
version "5.2.18"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5"
dependencies:
Expand All @@ -10518,6 +10534,14 @@ postcss@^6.0.1, postcss@^6.0.2:
source-map "^0.6.1"
supports-color "^5.3.0"

postcss@^7.0.2:
version "7.0.2"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.2.tgz#7b5a109de356804e27f95a960bef0e4d5bc9bb18"
dependencies:
chalk "^2.4.1"
source-map "^0.6.1"
supports-color "^5.4.0"

prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
Expand Down Expand Up @@ -12928,7 +12952,7 @@ supports-color@^4.2.1:
dependencies:
has-flag "^2.0.0"

supports-color@^5.1.0:
supports-color@^5.1.0, supports-color@^5.4.0:
version "5.4.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54"
dependencies:
Expand Down

0 comments on commit 8769110

Please sign in to comment.