Skip to content

Commit 149675d

Browse files
committed
Initial Commit
0 parents  commit 149675d

27 files changed

+382
-0
lines changed

.editorconfig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# http://editorconfig.org
2+
3+
root = true
4+
5+
[*]
6+
charset = utf-8
7+
end_of_line = lf
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
max_line_length = 80
11+
indent_style = tab
12+
indent_size = 4
13+
14+
[*.md]
15+
indent_style = space
16+
17+
[COMMIT_EDITMSG]
18+
trim_trailing_whitespace = false
19+
max_line_length = 72
20+
indent_style = space

.eslintrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
root: true
2+
extends: fnd

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/node_modules
2+
/.eslintcache
3+
4+
/samples/css.json
5+
/samples/output/
6+
/package-lock.json

.travis.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
language: node_js
2+
node_js:
3+
- 6
4+
- 8
5+
- 10
6+
7+
script:
8+
- npm test

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# faucet-pipeline-css
2+
[![npm](https://img.shields.io/npm/v/faucet-pipeline-css.svg)](https://www.npmjs.com/package/faucet-pipeline-css)
3+
[![Build Status](https://travis-ci.org/faucet-pipeline/faucet-pipeline-css.svg?branch=master)](https://travis-ci.org/faucet-pipeline/faucet-pipeline-css)
4+
[![Greenkeeper badge](https://badges.greenkeeper.io/faucet-pipeline/faucet-pipeline-css.svg)](https://greenkeeper.io)
5+
6+
You can find the documentation [here](http://www.faucet-pipeline.org).
7+
8+
## License
9+
10+
faucet-pipeline-css is licensed under Apache 2.0 License.

lib/index.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
let { abort } = require("faucet-pipeline-core/lib/util");
2+
let path = require("path");
3+
let makePostCSS = require("./make-postcss");
4+
5+
module.exports = (config, assetManager, { browsers, compact, sourcemaps } = {}) => {
6+
let bundlers = config.map(bundleConfig =>
7+
makeBundler(bundleConfig, assetManager, { browsers, compact, sourcemaps }));
8+
9+
return filepaths => Promise.all(bundlers.map(bundle => bundle(filepaths)));
10+
};
11+
12+
function makeBundler(config, assetManager, { browsers, compact, sourcemaps } = {}) {
13+
let { browserslist, fingerprint } = config;
14+
15+
if(!config.source || !config.target) {
16+
abort("ERROR: CSS configuration requires both target and source");
17+
}
18+
19+
let source = assetManager.resolvePath(config.source);
20+
let target = assetManager.resolvePath(config.target, { enforceRelative: true });
21+
22+
if(browserslist === false) {
23+
browsers = null;
24+
} else if(browserslist) {
25+
browsers = browsers[browserslist];
26+
} else {
27+
browsers = browsers.defaults;
28+
}
29+
30+
let postCSS = makePostCSS(source, target, assetManager, sourcemaps, browsers);
31+
32+
let previouslyIncludedFiles;
33+
34+
return filepaths => {
35+
// If this is the first run or the changed file is one of the
36+
// previously included ones, run the compiler
37+
if(previouslyIncluded(filepaths, previouslyIncludedFiles)) {
38+
postCSS().
39+
then(result => {
40+
previouslyIncludedFiles = result.stats.includedFiles.
41+
map(filepath => path.normalize(filepath));
42+
43+
let options = {};
44+
if(fingerprint !== undefined) {
45+
options.fingerprint = fingerprint;
46+
}
47+
assetManager.writeFile(target, result.css, options);
48+
}).
49+
catch(error => {
50+
let options = { error };
51+
if(fingerprint !== undefined) {
52+
options.fingerprint = fingerprint;
53+
}
54+
assetManager.writeFile(target, errorOutput(error.message,
55+
assetManager.referenceDir),
56+
options);
57+
});
58+
}
59+
};
60+
}
61+
62+
function previouslyIncluded(filepaths, previouslyIncludedFiles) {
63+
return previouslyIncludedFiles === undefined ||
64+
filepaths.some(filepath => {
65+
return previouslyIncludedFiles.
66+
find(candidate => candidate === path.normalize(filepath));
67+
});
68+
}
69+
70+
let MESSAGE_PATTERN = /^(\S+)(:\d+:\d+:)\s+(.+)$/;
71+
72+
function errorOutput(message, referenceDir) {
73+
// eslint-disable-next-line no-unused-vars
74+
let [_, file, locator, description] = MESSAGE_PATTERN.exec(message);
75+
let error = `${path.relative(referenceDir, file)}${locator} ${description}`;
76+
77+
return `body:before {
78+
content: "\\26a0 CSS Error: ${error.replace(/"/g, "'").replace(/\s+/g, " ")}";
79+
font-weight: bold;
80+
display: block;
81+
border: 5px solid red;
82+
padding: 5px;
83+
}\n`;
84+
}

lib/make-postcss.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
let postcss = require("postcss");
2+
let atImport = require("postcss-import");
3+
let { promisify } = require("faucet-pipeline-core/lib/util");
4+
let readFile = promisify(require("fs").readFile);
5+
6+
module.exports = function(input, target, assetManager, sourcemaps, browsers) {
7+
// if(browsers && browsers.length > 0) {
8+
// let filepath = path.relative(assetManager.referenceDir, input);
9+
// console.error(`compiling CSS ${repr(filepath)} for ${browsers.join(", ")}`);
10+
11+
let processor = postcss([
12+
atImport()
13+
]);
14+
15+
let options = {
16+
from: input,
17+
target: target
18+
};
19+
20+
if(sourcemaps) {
21+
options.map = { inline: true };
22+
}
23+
24+
return () => {
25+
return readFile(input).then(code => {
26+
return processor.process(code, options);
27+
}).then(result => {
28+
let warnings = result.warnings();
29+
30+
// TODO: Maybe do the manipulation of the message here
31+
if(warnings.length > 0) {
32+
let errorMessage = warnings.
33+
map(warning => warning.toString()).
34+
join("\n");
35+
throw new Error(errorMessage);
36+
}
37+
38+
let includedFiles = result.messages.
39+
filter(message => message.type === "dependency").
40+
map(message => message.file);
41+
42+
return {
43+
css: result.css,
44+
stats: {
45+
includedFiles: [input].concat(includedFiles)
46+
}
47+
};
48+
});
49+
};
50+
};

package.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "faucet-pipeline-css",
3+
"version": "0.1.0",
4+
"description": "CSS for faucet-pipeline",
5+
"main": "lib/index.js",
6+
"scripts": {
7+
"test": "npm-run-all --parallel lint test:cli",
8+
"test:cli": "./test/run",
9+
"lint": "eslint --cache lib test && echo ✓"
10+
},
11+
"repository": {
12+
"type": "git",
13+
"url": "git+https://github.com/faucet-pipeline/faucet-pipeline-css.git"
14+
},
15+
"author": "Lucas Dohmen <[email protected]> (https://lucas.dohmen.io/)",
16+
"license": "Apache-2.0",
17+
"bugs": {
18+
"url": "https://github.com/faucet-pipeline/faucet-pipeline-css/issues"
19+
},
20+
"homepage": "https://www.faucet-pipeline.org",
21+
"dependencies": {
22+
"faucet-pipeline-core": "^1.0.0",
23+
"postcss": "~7.0.3",
24+
"postcss-import": "^12.0.0"
25+
},
26+
"devDependencies": {
27+
"eslint-config-fnd": "^1.6.0",
28+
"eslint-plugin-import": "^2.13.0",
29+
"json-diff": "^0.5.2",
30+
"npm-run-all": "^4.1.3",
31+
"release-util-fnd": "^1.1.1"
32+
}
33+
}

release

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env bash
2+
3+
set -eu
4+
5+
. ./node_modules/release-util-fnd/lib.sh
6+
7+
pre_release_checks
8+
npm run test
9+
10+
create_package > /dev/null
11+
publish_package

test/run

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
root=`dirname "$0"`
5+
root=`node -r fs -p "fs.realpathSync(process.argv[1]);" "$root"`
6+
7+
. "$root/../node_modules/faucet-pipeline-core/test/cli_harness.sh"
8+
9+
begin "$root/test_basic"
10+
faucet
11+
assert_identical "./dist/bundle.css" "./expected.css"
12+
assert_missing "./expected.json"
13+
end
14+
15+
begin "$root/test_error"
16+
faucet || echo "Crashed successfully"
17+
assert_identical "./dist/bundle.css" "./expected.css"
18+
end
19+
20+
begin "$root/test_fingerprinting"
21+
faucet --fingerprint
22+
assert_identical "./dist/fingerprint/bundle-12c46b3f47e2c83fc4f31fb2d6564c51.css" "./expected.css"
23+
assert_identical "./dist/no-fingerprint/bundle.css" "./expected.css"
24+
assert_json "./dist/manifest.json" "./expected.json"
25+
end
26+
27+
begin "$root/test_sourcemap"
28+
faucet --sourcemaps
29+
assert_identical_sourcemap "./dist/bundle.css" "./expected.css" "./expected.css.map"
30+
end
31+
32+
echo; echo "SUCCESS: all tests passed"

0 commit comments

Comments
 (0)