This repository has been archived by the owner on Aug 7, 2021. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 49
/
css2json-loader.ts
62 lines (49 loc) · 2.14 KB
/
css2json-loader.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { parse, Import, Stylesheet } from "css";
import { loader } from "webpack";
import { getOptions, urlToRequest } from "loader-utils";
const betweenQuotesPattern = /('|")(.*?)\1/;
const unpackUrlPattern = /url\(([^\)]+)\)/;
const inlineLoader = "!nativescript-dev-webpack/css2json-loader?useForImports!"
const loader: loader.Loader = function (content: string, map) {
const options = getOptions(this) || {};
const inline = !!options.useForImports;
const requirePrefix = inline ? inlineLoader : "";
const ast = parse(content, undefined);
let dependencies = [];
getImportRules(ast)
.map(extractUrlFromRule)
.map(createRequireUri)
.forEach(({ uri, requireURI }) => {
dependencies.push(`global.registerModule("${uri}", () => require("${requirePrefix}${requireURI}"));`);
// Call registerModule with requireURI to handle cases like @import "~@nativescript/theme/css/blue.css";
if (uri !== requireURI) {
dependencies.push(`global.registerModule("${requireURI}", () => require("${requirePrefix}${requireURI}"));`);
}
});
const str = JSON.stringify(ast, (k, v) => k === "position" ? undefined : v);
this.callback(null, `${dependencies.join("\n")}module.exports = ${str};`, map);
}
function getImportRules(ast: Stylesheet): Import[] {
if (!ast || (<any>ast).type !== "stylesheet" || !ast.stylesheet) {
return [];
}
return <Import[]>ast.stylesheet.rules
.filter(rule => rule.type === "import" && (<any>rule).import)
}
/**
* Extracts the url from import rule (ex. `url("./platform.css")`)
*/
function extractUrlFromRule(importRule: Import): string {
const urlValue = importRule.import;
const unpackedUrlMatch = urlValue.match(unpackUrlPattern);
const unpackedValue = unpackedUrlMatch ? unpackedUrlMatch[1] : urlValue
const quotesMatch = unpackedValue.match(betweenQuotesPattern);
return quotesMatch ? quotesMatch[2] : unpackedValue;
};
function createRequireUri(uri): { uri: string, requireURI: string } {
return {
uri: uri,
requireURI: urlToRequest(uri)
};
}
export default loader;