我正在尝试将less
文件编译为css
,我正在使用dotless
我用nuget
安装了它。这是我在项目“预构建事件命令行”中设置的设置
“$(SolutionDir)packages\dotless.1.3.1.0\tool\dotless.compiler.exe”
“$(ProjectDir)Content\style.less”
“$(ProjectDir)Content\style_less.css”
构建时发生的事情是,它只是在记事本中打开style.less
文件,然后停在那里。当我关闭less
文件时,它会打开输出css
(空),并在此处停止相同的故事,当我关闭css
时,它会执行常规构建。
想法?需要时间吗?这种行为是否正常?
修改
在Windows环境中是否还有其他方法可以编译LESS?
答案 0 :(得分:2)
正如我在一些问题评论中所说,因为DotLess对我不起作用,我转而使用其他方法:使用官方LESS编译器(JavaScript one)编译LESS并使用Windows Script Host执行。
在解决方案目录中创建一个文件夹(即为您的特定解决方案存储 .sln 和项目目录的位置)。将您的文件夹称为构建< /强>
你需要这些脚本(为 Build 文件夹中的每一个创建一个文件,我给你整个文件名):
<强> lessc.wsf 强>
<!--
Less.js compiler for Windows Script Host
http://blog.dotsmart.net/
Copyright (c) 2010, Duncan Smart
Licensed under the Apache 2.0 License.
-->
<job>
<script language="jscript">
// Stub out globals
var window = this;
var location = window.location = {
port: 0,
href: ''
};
var fso = new ActiveXObject("Scripting.FileSystemObject");
var input = null;
var util = {
readText: function (filename) {
//WScript.StdErr.WriteLine("readText: " + filename);
var file = fso.OpenTextFile(filename);
// Don't error on empty files
var text = file.AtEndOfStream ? '' : file.ReadAll();
// Strip off any UTF-8 BOM
var utf8bom = String.fromCharCode(0xEF, 0xBB, 0xBF);
if (text.substr(0, utf8bom.length) == utf8bom) {
text = text.substr(utf8bom.length);
}
file.Close();
return text;
}
};
// XMLHttpRequest that just gets local files. Used when processing "@import"
function XMLHttpRequest(){}
XMLHttpRequest.prototype = {
open: function (method, url, async) {
this.url = url;
},
send: function () {
// get the file path relative to the input less file/directory
var currDir = fso.folderExists(input) ? input : fso.getParentFolderName(input);
var filename = fso.BuildPath(currDir, this.url);
//WScript.StdErr.WriteLine("XHR.send " + filename);
// Little hack so *.less will resolve to *.less.css also. Helps with Visual Studio
// ensuring that file BuildAction is set to Content and you get rudimentary syntax highlighting with no set up.
if (filename.match(/.less$/i) && !fso.FileExists(filename)) {
filename = filename.replace(/.less$/i, '.less.css');
}
try {
this.status = 200;
this.responseText = util.readText(filename);
}
catch (e) {
this.status = 404;
this.responseText = e.description;
}
},
setRequestHeader: function () {},
getResponseHeader: function () {}
};
// Fake document
var document = {
_dummyElement: {
childNodes: [],
appendChild: function(){},
style: {}
},
getElementsByTagName: function(){ return []; },
getElementById: function(){ return this._dummyElement; },
createElement: function(){ return this._dummyElement; },
createTextNode: function(){ return this._dummyElement; }
};
</script>
<!-- less.js from https://github.com/cloudhead/less.js/tree/master/dist/ -->
<script language="jscript" src="less.js" />
<script language="jscript">
// Parse args
var args = {};
for (var i = 0; i < WScript.Arguments.Length; i++) {
var arg = WScript.Arguments.Item(i);
// Handle "-switch" and "--switch"
var match = arg.match(/^--?([a-z][0-9a-z-]*)$/i);
if (match) {
i = match[1];
arg = true;
}
args[i] = arg;
}
input = args[0];
var output = args[1];
if (fso.folderExists(input)) {
input = fso.getAbsolutePathName(input);
var files = getFiles(input, /\.less$/i);
for (var i = 0; i < files.length; i++) {
var file = files[i];
convert(file.path, output + '\\' + file.name.replace( /\.less$/i, '.css'));
}
}
else {
if (fso.folderexists(output)) {
output = fso.getAbsolutePathName(output) + '\\' + fso.getfile(input).name.replace(/\.less$/i, '.css');
}
convert(input, output);
}
// Returns array of {name:'foo.bar', path:'c:\baz\foo.bar'} for given directory and pattern
function getFiles(dir, regex) {
var e = new Enumerator(fso.getFolder(dir).files);
var files = []
for (; !e.atEnd(); e.moveNext()) {
if (regex.test(e.item().path)) {
files.push({
name: e.item().name,
path: e.item().path
});
}
}
return files;
}
function convert(input, output) {
if (!input) {
WScript.StdErr.WriteLine("lessc.wsf: no input files");
WScript.StdErr.WriteLine("Usage:");
WScript.StdErr.WriteLine(" Single file: cscript //nologo lessc.wsf input.less [output.css] [-compress]");
WScript.StdErr.WriteLine(" Directory: cscript //nologo lessc.wsf inputdir outputdir [-compress]");
WScript.Quit(1);
}
var data;
if (input == '-') {
var chunks = [];
while (!WScript.StdIn.AtEndOfStream)
chunks.push(WScript.StdIn.ReadAll());
data = chunks.join('');
}
else {
data = util.readText(input);
}
var parser = new less.Parser({
filename: input
});
try {
parser.parse(data, function (err, tree) {
if (err) {
WScript.StdErr.WriteLine("ERR: ");
for (var i in err) {
if (err[i]) {
WScript.StdErr.WriteLine(" " + i + ': ' + err[i]);
}
}
WScript.Quit(2);
}
else {
var css = tree.toCSS({
compress: args.compress
});
if (output) {
if(fso.FileExists(output))
{
var checkfile = fso.GetFile(output);
if(checkfile.Attributes & 1)
{
checkfile.Attributes = checkfile.Attributes ^ 1
}
}
var outputfile = fso.CreateTextFile(output);
outputfile.Write(css);
outputfile.Close();
}
else {
WScript.StdOut.Write(css);
}
}
});
}
catch (e) {
WScript.StdErr.WriteLine("ERROR:");
for (var i in e) {
if (e[i]) {
WScript.StdErr.WriteLine(" " + i + ': ' + e[i]);
}
}
WScript.Quit(3);
}
// Sometimes less will return errors inside the fake HTML element
if (document._dummyElement.innerHTML && document._dummyElement.innerHTML.match(/Syntax Error/i)) {
var s = document._dummyElement.innerHTML;
s = s.replace(/<[^>]+(\/?)>/g, function (m) { return m.indexOf('/') > 0 && m !== '</label>' ? "\n" : '' });
s = s.replace(/\n+/g, '\n');
WScript.StdErr.WriteLine("ERR: ");
WScript.StdErr.WriteLine(s);
WScript.Quit(2);
}
}
</script>
</job>
<强> lessc.cmd 强>
::For convenience
@cscript //nologo "%~dp0lessc.wsf" %*
<强> less.targets 强>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<DotLessCompilerPath>$(SolutionDir)Build\lessc.cmd</DotLessCompilerPath>
</PropertyGroup>
<Target Name="AllLessToCss" AfterTargets="AfterBuild">
<CreateItem Include="$(ProjectDir)**\*.less">
<Output TaskParameter="Include" ItemName="LessFile" />
</CreateItem>
<Message Text="" Importance="high" />
<Message Text="Now compiling LESS files..." Importance="high" />
<Message Text="------------------------------------------------------------" Importance="high" />
<Message Text="" Importance="high" />
<Message Text="File: "%(LessFile.FullPath) ======>>>>> "%(LessFile.RootDir)%(LessFile.Directory)%(LessFile.FileName).css"" Importance="high" />
<Exec Command=""$(DotLessCompilerPath)" "%(LessFile.FullPath)" "%(LessFile.RootDir)%(LessFile.Directory)%(LessFile.FileName).css" -compress" />
<Message Text="" Importance="high" />
<Message Text="------------------------------------------------------------" Importance="high" />
<Message Text="" Importance="high" />
</Target>
</project>
在构建文件夹中创建完整文件后,您需要修改ASP.NET应用程序项目文件(即 .csproj )。要修改项目文件,需要在Visual Studio IDE 中卸载项目(在解决方案资源管理器中右键单击项目节点,然后选择“卸载项目”)。
现在再次右键单击已卸载的项目,然后选择“编辑项目文件”。转到项目文件的末尾,然后在</project>
之前添加以下XML代码:
<Import Project="$(SolutionDir)Build\less.targets" />
最后,在Visual Studio中重新加载ASP.NET项目,构建它,如果一切顺利,您将找到任何ASP.NET项目LESS(.less)文件的“.css”副本! / p>
答案 1 :(得分:0)
我在我的项目中手动安装了Less.net,这是在我的Pre-Build事件中:
If "$(ConfigurationName)" == Debug (
FOR %%i IN ("$(ProjectDir)css\*.less") DO ("$(ProjectDir)Tools\dotless.Compiler.exe" "%%i" )
) Else (
FOR %%i IN ("$(ProjectDir)css\*.less") DO ("$(ProjectDir)Tools\dotless.Compiler.exe" -m "%%i" )
)
此代码将在css文件夹中查找并将所有.less文件转换为css文件,当项目处于调试模式时,css将是可读的,否则将被压缩。不要忘记更改路径,以便它在您的环境中工作。如果.less文件中存在错误,则错误和行号将显示在“输出”窗口中。