/
LESSAsset.js
99 lines (84 loc) 路 2.34 KB
/
LESSAsset.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
const Asset = require('../Asset');
const localRequire = require('../utils/localRequire');
const promisify = require('../utils/promisify');
const Resolver = require('../Resolver');
const fs = require('../utils/fs');
const path = require('path');
const parseCSSImport = require('../utils/parseCSSImport');
class LESSAsset extends Asset {
constructor(name, options) {
super(name, options);
this.type = 'css';
}
async parse(code) {
// less should be installed locally in the module that's being required
let less = await localRequire('less', this.name);
let render = promisify(less.render.bind(less));
let opts =
(await this.getConfig(['.lessrc', '.lessrc.js'], {packageKey: 'less'})) ||
{};
opts.filename = this.name;
opts.plugins = (opts.plugins || []).concat(urlPlugin(this));
return await render(code, opts);
}
collectDependencies() {
for (let dep of this.ast.imports) {
this.addDependency(dep, {includedInParent: true});
}
}
generate() {
return [
{
type: 'css',
value: this.ast ? this.ast.css : '',
hasDependencies: false
}
];
}
}
function urlPlugin(asset) {
return {
install: (less, pluginManager) => {
let visitor = new less.visitors.Visitor({
visitUrl: node => {
node.value.value = asset.addURLDependency(
node.value.value,
node.currentFileInfo.filename
);
return node;
}
});
visitor.run = visitor.visit;
pluginManager.addVisitor(visitor);
let LessFileManager = getFileManager(less, asset.options);
pluginManager.addFileManager(new LessFileManager());
}
};
}
function getFileManager(less, options) {
const resolver = new Resolver({
extensions: ['.css', '.less'],
rootDir: options.rootDir
});
class LessFileManager extends less.FileManager {
supports() {
return true;
}
supportsSync() {
return false;
}
async loadFile(filename, currentDirectory) {
filename = parseCSSImport(filename);
let resolved = await resolver.resolve(
filename,
path.join(currentDirectory, 'index')
);
return {
contents: await fs.readFile(resolved.path, 'utf8'),
filename: resolved.path
};
}
}
return LessFileManager;
}
module.exports = LESSAsset;