-
Notifications
You must be signed in to change notification settings - Fork 0
/
plugin.js
73 lines (70 loc) · 2.34 KB
/
plugin.js
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
63
64
65
66
67
68
69
70
71
72
73
const sass = require("sass");
const fs = require("fs");
module.exports = function ({ alias },{includePaths=[],useAlias=false,aliasPrefix="",compilerOptions={}} ) {
function aliasImportsToRelative(content, aliases, prefix) {
const parentDirRegex = new RegExp(
`((?<=')${prefix}[^\//*?|<>:\n; "]+(?=\/.*';)+)`,
"g"
);
//use prefix to filter regular imports from alias imports
const isAliasRegex=new RegExp(`(@import|@use)+(?=\ '${prefix})`)
return content
.split("\n")
.map((line) => {
if (line.match(isAliasRegex)) {
[method, AliasImport] = line.split(" ");
[target] = AliasImport.match(parentDirRegex) || [-1];
let aliasPath = aliases[target];
let relativeImport = aliasPath
? AliasImport.replace(parentDirRegex, aliasPath)
: AliasImport;
return `${method} ${relativeImport}`;
}
else
return line
})
.join("\n");
}
const importedByMap = new Map();
function addImportsToMap(filePath, sassImport) {
const importedBy = importedByMap.get(sassImport);
if (importedBy) {
importedBy.add(filePath);
} else {
importedByMap.set(sassImport, new Set([filePath]));
}
}
return {
name: "snowpack-sass-compiler",
resolve: {
input: [".scss", ".sass"],
output: [".css"],
},
_markImportersAsChanged(filePath) {
if (importedByMap.has(filePath)) {
const importedBy = importedByMap.get(filePath);
importedByMap.delete(filePath);
for (const importerFilePath of importedBy) {
this.markChanged(importerFilePath);
}
}
},
onChange({ filePath }) {
this._markImportersAsChanged(filePath);
},
async load({ filePath, isDev }) {
let data=fs.readFileSync(filePath, "utf-8");
data =useAlias ? aliasImportsToRelative(data,alias,aliasPrefix) : data;
if(compilerOptions["data"])
throw new Error("Handling data are made by the plugin. You need to remove 'data' attribute");
const result = sass.renderSync({data, includePaths,...compilerOptions});
if (isDev) {
const sassImports = result.stats.includedFiles;
sassImports.forEach(
(imp) => imp !== filePath && addImportsToMap(filePath, imp)
);
}
return result.css.toString();
},
};
};