Skip to content

Commit

Permalink
Create CSS typings before build. Fixes GoogleChromeLabs#251. (GoogleC…
Browse files Browse the repository at this point in the history
…hromeLabs#350)

* Create CSS typings before build

* Let's try this.

* Adding comment

* Remove hack from travis
  • Loading branch information
jakearchibald authored Nov 28, 2018
1 parent d562272 commit 9afaf3e
Show file tree
Hide file tree
Showing 6 changed files with 386 additions and 52 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ node_js:
- 10
- 8
cache: npm
script: npm run build || npm run build # scss ts definitions need to be generated before an actual build
script: npm run build
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ npm install
npm run build
```

You'll get an error on first build because of [a stupid bug we haven't fixed
yet](https://github.com/GoogleChromeLabs/squoosh/issues/251).

You can run the development server with:

```sh
Expand Down
74 changes: 74 additions & 0 deletions config/add-css-types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const DtsCreator = require('typed-css-modules');
const chokidar = require('chokidar');
const util = require('util');
const sass = require('node-sass');

const sassRender = util.promisify(sass.render);

async function sassToCss(path) {
const result = await sassRender({ file: path });
return result.css;
}

/**
* @typedef {Object} Opts
* @property {boolean} watch Watch for changes
*/
/**
* Create typing files for CSS & SCSS.
*
* @param {string[]} rootPaths Paths to search within
* @param {Opts} [opts={}] Options.
*/
function addCssTypes(rootPaths, opts = {}) {
return new Promise((resolve) => {
const { watch = false } = opts;

const paths = [];
const preReadyPromises = [];
let ready = false;

for (const rootPath of rootPaths) {
// Look for scss & css in each path.
paths.push(rootPath + '/**/*.scss');
paths.push(rootPath + '/**/*.css');
}

// For simplicity, the watcher is used even if we're not watching.
// If we're not watching, we stop the watcher after the initial files are found.
const watcher = chokidar.watch(paths, {
// Avoid processing already-processed files.
ignored: '*.d.*',
// Without this, travis and netlify builds never complete. I'm not sure why, but it might be
// related to https://github.com/paulmillr/chokidar/pull/758
persistent: watch,
});

function change(path) {
const promise = (async function() {
const creator = new DtsCreator({ camelCase: true });
const result = path.endsWith('.scss') ?
await creator.create(path, await sassToCss(path)) :
await creator.create(path);

await result.writeFile();
})();

if (!ready) preReadyPromises.push(promise);
}

watcher.on('change', change);
watcher.on('add', change);

// 'ready' is when events have been fired for file discovery.
watcher.on('ready', () => {
ready = true;
// Wait for the current set of processing to finish.
Promise.all(preReadyPromises).then(resolve);
// And if we're not watching, close the watcher.
if (!watch) watcher.close();
});
})
}

module.exports = addCssTypes;
Loading

0 comments on commit 9afaf3e

Please sign in to comment.