Skip to content

Commit 4f113cf

Browse files
author
zougt
committed
chore(): path is string or string[]
1 parent 5b038a8 commit 4f113cf

File tree

5 files changed

+105
-25
lines changed

5 files changed

+105
-25
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@ $ npm install less @zougt/less-loader --save-dev
1414

1515
在 webpack.config.js 使用`less-loader`的地方替换成`@zougt/less-loader`, 并添加`multipleScopeVars`属性
1616

17+
### multipleScopeVars
18+
19+
Type `object[]`
20+
21+
#### multipleScopeVars[].scopeName
22+
23+
Type `string`
24+
25+
#### multipleScopeVars[].path
26+
27+
Type `string | string[]`
28+
1729
```js
1830
const path = require("path");
1931
module.exports = {
@@ -125,7 +137,7 @@ src/components/Button/style.css
125137
}
126138
```
127139

128-
`html`中改变 classname 切换主题
140+
`html`中改变 classname 切换主题,只作用于 html 标签 :
129141

130142
```html
131143
<!DOCTYPE html>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zougt/less-loader",
3-
"version": "8.1.0",
3+
"version": "8.1.1",
44
"description": "A Less loader for webpack. Compiles Less to CSS.",
55
"license": "MIT",
66
"repository": "GitOfZGT/less-loader",

src/index.js

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import path from "path";
2-
import fs from "fs";
32

43
import less from "less";
54

@@ -9,6 +8,8 @@ import {
98
isUnsupportedUrl,
109
normalizeSourceMap,
1110
getScropProcessResult,
11+
getAllStyleVarFiles,
12+
getVarsContent,
1213
} from "./utils";
1314
import LessError from "./LessError";
1415

@@ -37,19 +38,12 @@ async function lessLoader(source) {
3738
let result;
3839
const preProcessor = (code) =>
3940
(options.implementation || less).render(code, lessOptions);
40-
const styleVarFiles = options.multipleScopeVars;
41-
const allStyleVarFiles = Array.isArray(styleVarFiles)
42-
? styleVarFiles.filter(
43-
(item) => item.scopeName && item.path && fs.existsSync(item.path)
44-
)
45-
: [{ scopeName: "", path: "" }];
41+
const allStyleVarFiles = getAllStyleVarFiles(this, options);
4642
try {
4743
// result = await (options.implementation || less).render(data, lessOptions);
4844
result = await Promise.all(
4945
allStyleVarFiles.map((file) => {
50-
const varscontent = file.path
51-
? fs.readFileSync(file.path).toString()
52-
: "";
46+
const varscontent = getVarsContent(file.path);
5347
return preProcessor(`${data}\n${varscontent}`, lessOptions);
5448
})
5549
).then((prs) =>

src/options.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"type": "object"
3939
},
4040
"multipleScopeVars": {
41-
"description": "The multipleScopeVars of the `Less` to be used (https://github.com/GitOfZGT/less-loader).",
41+
"description": "The multipleScopeVars of the `less-loader` to be used (https://github.com/GitOfZGT/less-loader).",
4242
"type": "array"
4343
}
4444
},

src/utils.js

Lines changed: 86 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import path from "path";
2+
import fs from "fs";
23

34
import less from "less";
45
import { klona } from "klona/full";
@@ -219,16 +220,63 @@ function normalizeSourceMap(map) {
219220

220221
return newMap;
221222
}
222-
const cssFragReg = /\.[^{}/\\]+{[^{}]*?}/g;
223-
const classNameFragReg = /\.[^{}/\\]+(?={)/;
223+
const getAllStyleVarFiles = (loaderContext, options) => {
224+
const styleVarFiles = options.multipleScopeVars;
225+
let allStyleVarFiles = [{ scopeName: "", path: "" }];
226+
if (Array.isArray(styleVarFiles)) {
227+
allStyleVarFiles = styleVarFiles.filter((item) => {
228+
if (!item.scopeName) {
229+
loaderContext.emitError(
230+
new Error("Not found scopeName in less-loader multipleScopeVars")
231+
);
232+
return false;
233+
}
234+
if (Array.isArray(item.path)) {
235+
return item.path.every((pathstr) => {
236+
const exists = pathstr && fs.existsSync(pathstr);
237+
if (!exists) {
238+
loaderContext.emitError(
239+
new Error(
240+
`Not found path: ${pathstr} in less-loader multipleScopeVars`
241+
)
242+
);
243+
}
244+
return exists;
245+
});
246+
}
247+
if (
248+
!item.path ||
249+
typeof item.path !== "string" ||
250+
!fs.existsSync(item.path)
251+
) {
252+
loaderContext.emitError(
253+
new Error(
254+
`Not found path: ${item.path} in less-loader multipleScopeVars`
255+
)
256+
);
257+
return false;
258+
}
259+
return true;
260+
});
261+
}
262+
return allStyleVarFiles;
263+
};
264+
265+
const cssFragReg = /[^{}/\\]+{[^{}]*?}/g;
266+
const classNameFragReg = /[^{}/\\]+(?={)/;
224267
const addScopeName = (css, scopeName) => {
225268
const splitCodes = css.match(cssFragReg) || [];
226269

227270
if (splitCodes.length && scopeName) {
228271
const fragments = [];
229272
const resultCode = splitCodes.reduce((codes, curr) => {
230273
const replacerFragment = curr.replace(classNameFragReg, (a) =>
231-
a.split(",").reduce((tol, c) => tol.replace(c, `.${scopeName} ${c}`), a)
274+
a.split(",").reduce((tol, c) => {
275+
if (/^html/i.test(c)) {
276+
return tol;
277+
}
278+
return tol.replace(c, `.${scopeName} ${c}`);
279+
}, a)
232280
);
233281
fragments.push(replacerFragment);
234282
return codes.replace(curr, replacerFragment);
@@ -247,11 +295,11 @@ const addScopeName = (css, scopeName) => {
247295
};
248296
};
249297

250-
const getScropProcessResult = (lessResults = [], allStyleVarFiles = []) => {
298+
const getScropProcessResult = (cssResults = [], allStyleVarFiles = []) => {
251299
const preprocessResult = { deps: [], code: "", errors: [] };
252300
const fragmentsGroup = [];
253301
const sourceFragmentsGroup = [];
254-
lessResults.forEach((item, i) => {
302+
cssResults.forEach((item, i) => {
255303
const { fragments, sourceFragments } = addScopeName(
256304
item.code,
257305
allStyleVarFiles[i].scopeName
@@ -262,26 +310,52 @@ const getScropProcessResult = (lessResults = [], allStyleVarFiles = []) => {
262310
...(preprocessResult.errors || []),
263311
...(item.errors || []),
264312
];
265-
if (allStyleVarFiles[i].path) {
266-
preprocessResult.deps.push(allStyleVarFiles[i].path);
267-
}
313+
const deps = Array.isArray(allStyleVarFiles[i].path)
314+
? allStyleVarFiles[i].path
315+
: [allStyleVarFiles[i].path];
316+
deps.forEach((str) => {
317+
if (str) {
318+
preprocessResult.deps.push(str);
319+
}
320+
});
268321
});
269-
if (lessResults.length && sourceFragmentsGroup.length) {
322+
if (cssResults.length && sourceFragmentsGroup.length) {
270323
preprocessResult.code = sourceFragmentsGroup[0].reduce(
271324
(tol, curr, i) =>
272325
tol.replace(curr, () => fragmentsGroup.map((g) => g[i]).join("\n")),
273-
lessResults[0].code
326+
cssResults[0].code
274327
);
275-
preprocessResult.map = lessResults[0].map;
276-
preprocessResult.deps = [...preprocessResult.deps, ...lessResults[0].deps];
328+
preprocessResult.map = cssResults[0].map;
329+
preprocessResult.deps = [...preprocessResult.deps, ...cssResults[0].deps];
277330
}
278331

279332
return preprocessResult;
280333
};
334+
const replaceFormSass = (url) => {
335+
let code = url ? fs.readFileSync(url).toString() : "";
336+
if (/\.(scss|sass)$/i.test(url)) {
337+
code = code.replace(/\$/g, "@").replace(/!default/g, "");
338+
}
339+
return code;
340+
};
341+
342+
const getVarsContent = (url) => {
343+
let content = "";
344+
if (Array.isArray(url)) {
345+
url.forEach((p) => {
346+
content += replaceFormSass(p);
347+
});
348+
} else {
349+
content = replaceFormSass(url);
350+
}
351+
return content;
352+
};
281353
export {
282354
getLessOptions,
283355
isUnsupportedUrl,
284356
normalizeSourceMap,
357+
getAllStyleVarFiles,
285358
addScopeName,
286359
getScropProcessResult,
360+
getVarsContent,
287361
};

0 commit comments

Comments
 (0)