madskristensen / WebEssentials2013

Visual Studio extension
http://vswebessentials.com
Other
944 stars 251 forks source link

Incorrect errors from less compilation #1170

Closed kingmotley closed 10 years ago

kingmotley commented 10 years ago

We have a common less file that gets imported to many different less files, and we get strange errors when building. Such as: 6/9/2014 9:57:25 AM: LESS: tripstarterslincoln.less compiled. 6/9/2014 9:57:26 AM: LESS: tripstartersCulinary.less compiled. 6/9/2014 9:57:26 AM: LESS: traveldeals.responsive.less compiled. 6/9/2014 9:57:26 AM: LESS: tripstarterslincoln.less compilation failed: FileError: 'tripstartercommon.less' wasn't found 6/9/2014 9:57:26 AM: LESS: tripstartercommon.less compiled. 6/9/2014 9:57:26 AM: LESS: tripstarterschicago.less compiled. 6/9/2014 9:57:26 AM: LESS: tripstartersroute66.less compilation failed: FileError: 'tripstartercommon.less' wasn't found 6/9/2014 9:57:26 AM: LESS: tripstartersoutdoor.less compilation failed: FileError: 'tripstartercommon.less' wasn't found 6/9/2014 9:57:26 AM: LESS: tripstarterschicago.less compilation failed: FileError: 'tripstartercommon.less' wasn't found 6/9/2014 9:57:26 AM: LESS: tripstarterslgbt.less compilation failed: FileError: 'tripstartercommon.less' wasn't found

Notice that tripstarterslincoln.less compiled fine, then 3 lines later, it complains that it failed to compile because it couldn't find tripstartercommon.less, which it then finds and compiles on the very next line. Similar thing for tripstarterschicago.less, but in a different order.

SLaks commented 10 years ago

Beware of relative paths.

kingmotley commented 10 years ago

We have no path information at all in the less files. They are all contained in one folder (content).

Are you suggesting the includes all need to be relative to the base of the project even if they are all contained in the same folder together (./content/my.less), or worse and use absolute paths (C:\Users\me\documents\project\content\my.less)?

am11 commented 10 years ago

@kingmotley, we have recently overhauled the entire way of dealing with node-based services. Please upgrade to VS2013 Update 3 RC, which is the prerequisite for the latest nightly build v2.2.7.

If this fixes the issue, please consider closing it.

Thanks.

kingmotley commented 10 years ago

Will take a look at it, but likely won't be able to revisit this until Update 3 Final is released. I don't have a test dev box set up, and I'm leery of installing Update 3 prior to a final release and we are in the middle of a small crunch time.

ehorodyski commented 10 years ago

Can reproduce with VS2013 Update 3 final release, using nightly build of Web Essentials. Same issue, as posted in screenshot below. Running VS2013 Update 2 with WE 2.2.6 worked well; I wanted to grab the nightly but realized 2.2.7 needed Update 3 RC and by the time I got around to updating VS2013 the full release was already out, then starting with WE 2.2.7 the compilation seems to break when you import a lot of files. For reference, 'reference.less' imports 3 files but compiles fine.

Error running VS2013 with WE 2.2.7 nightly build: 8-7-2014 10-16-14 pm

ehorodyski commented 10 years ago

Yessir, updated comment for clarity.

am11 commented 10 years ago

Cool. Will take a look :)

ehorodyski commented 10 years ago

For reference, attached is a screenshot of a less @import heavy LESS file compiling correctly, VS2013 Update 3 WE 2.2.7 nightly build:

2

am11 commented 10 years ago

@ehorodyski can you make a sample project so we can test?

am11 commented 10 years ago

Here is how I tested:

Site.less is a glue file:

site

library/one.less:

one

references/two.less:

two

references/random/three.less:

three

references/random/four.less:

four

references/random/five.less:

five

ehorodyski commented 10 years ago

Give me a few moments to upload my source to GitHub. I'm much more familiar with TFS so it's taking longer than I had hoped. You will need many more files :-), also I have source mapping off.

am11 commented 10 years ago

:+1:

ehorodyski commented 10 years ago

Whew. I need to brush up on my GitHub :flushed: Try downloading from here: https://github.com/ehorodyski/web-essentials-test-solution/tree/test

am11 commented 10 years ago

Thanks. :+1:

And I need to brush up my TFS concepts :smile:

As I was suspecting, it turned out to be a syntax error: change this to:

@import (reference) '../references/references.less';

and all the url() occurrences of less import.

SASS compiler strictly consider @import url(..) as CSS3 import. LESS' is kind enough to check the extension. But in deep nesting cases, it expect user to abide by recommended syntax:

@import <(optional modifier)> 'file-path-with-or-without-extension-enclosed-in-single-or-double-quotes'

See imports in docs.

HTH

ehorodyski commented 10 years ago

Wow. Excellent find. How utterly inconsistent since most of my files don't use url(). Worked like a charm. Thank you for your help! Glad it's not a bug...I wonder when the change was made to LESS so that it stopped working the way I had it. Oh well...no use wondering now. Thanks again.

am11 commented 10 years ago

@ehorodyski,

Actually, we have a prebuild task, which fetches the latest node.js packages every time WE's code is compiled (after the user manually deletes Resources\nodejs folder, before the build).

This way our services keep up to date.

@SLaks, on that note, there are some packages with really long paths, PreBuild throws Path Too Long exception for EnumerateDirectories. Mads and I are compiling it from C:'s root. Matter of time someone adds more nested stuff and 260 limit exceed even from the drive root. I think we need to find some alternative to EnumerateDirectories and other methods to avoid this exception. (kernel32 has this method which ignores the path size defense, don't know what's the alternative/wrapper in .NET)

SLaks commented 10 years ago

http://bcl.codeplex.com/wikipage?title=Long%20Path&referringTitle=Home

am11 commented 10 years ago

Guys v2.3 stable version is just released, check it out.

@SLaks, thanks for the link.

The exception is thrown at https://github.com/madskristensen/WebEssentials2013/blob/38b10bd70ca20ec2146caf175cd6ea8189620f13/EditorExtensions/PreBuildTask.cs#L222, when L215's lazy loading kicks in.

When I type System.IO.L... it shows LongPath only in PreBuild.cs. Although its has LongPathDirectories, but the method LongPathDirectories.EnumerateDirectories() is missing, which is the one we need. It has a different set of methods. Here is the online reference: http://www.dotnetframework.org/default.aspx/4@0/4@0/untmp/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/clr/src/BCL/System/IO/LongPath@cs/1305376/LongPath@cs (none of MSDN!)

But at the same time, System.IO.LongPath* are unavailable when we try other files.

Do you suggest to download and use BCL team's long path downloaded from CodePlex? Microsoft.Experimental.IO.LongPathDirectories

SLaks commented 10 years ago

System.IO.LongPath is an internal class (http://referencesource.microsoft.com/#mscorlib/system/io/longpath.cs); it's used by IsolatedStorageFile.

You're seeing it in PreBuildTask.cs because it isn't part of the project, so IntelliSense does not filter on access levels. Calling it won't actually compile.

You should use the one from CodePlex; you'll need to edit the csproj to make it referenced by the pre-build task. (do not add it as a reference using VS)

SLaks commented 10 years ago

You can also use https://github.com/peteraritchie/LongPath; I have not used either one.

kingmotley commented 10 years ago

Seems most of the errors went away, but now we can't compile one of our less files any longer. It's an exact copy from here: https://github.com/neoziro/less-hidpi/blob/master/hidpi.less

We also get many errors about not being able to find this file, which may be because it can't compile it any longer. Not sure.

kingmotley commented 10 years ago

Apparently the problem isn't related to the content of the file. Creating even a brand new less file with nothing but "body{}" is returning the same error message: "8/8/2014 3:02:34 PM: LESS: test1.less compilation failed: LESS: Unexpected token u"

madskristensen commented 10 years ago

Sounds like a UTF-8 issue with BOM. Try to save the .less file with UTF-8 without signature

kingmotley commented 10 years ago

Maybe it is, but it's not coming from the LESS file. I've tried opening it in notepad, in textpad, saving in UTF-8, ANSI. Even creating a brand new less file does the same thing (right click on content folder, add, LESS stylesheet, type 'test2'). Get a window on left saying "body {}", window in right saying "/*

Compilation Error occurred (see error list to navigate to the error location): Error found:

*/", and an output window below saying "8/8/2014 3:36:05 PM: LESS: test2.less compilation failed: LESS: Unexpected token u"

madskristensen commented 10 years ago

Did you save it as "UTF-8 (without signature)"?

kingmotley commented 10 years ago

Same issue to second co-workers machine that just upgraded to Update 3, WE for Update 3 just an hour ago.

kingmotley commented 10 years ago

I assume it was trying to because when I click save's drop down, there is no option for without signature, just with encoding. And this isn't something we've done in the past.

kingmotley commented 10 years ago

Yes, tried with "Unicode (UTF-8 without signature) - Codepage 65001", no effect. Uninstalling and reinstalled WE 2.3 also had no effect.

madskristensen commented 10 years ago

The option is all the way at the bottom of the list almost. Not easy to find

madskristensen commented 10 years ago

@am11 Do you have any idea what to do here?

am11 commented 10 years ago

That's really odd. I even tried compiling the file referenced, its compiling just fine.

@kingmotley, what if you create a .cpp or .cs or .js file instead and then change its extension to .less? Do you have any other extension installed, which might be interfering with it?

kingmotley commented 10 years ago

Resharper, Codemaid, PowerShell, Azure SDK. I'll disable those and try. Disabling codemaid had no effect.

kingmotley commented 10 years ago

test2.less I saved as an ASCII file. Checked, and it is definitely ASCII, and upon opening it in Visual Studio, same error.

kingmotley commented 10 years ago

Uninstalled resharper 8.2 had no effect.

am11 commented 10 years ago

Also, please disable source-map generation from LESS options under WE and try.

Normally, its a JSON error: "Unexpected token u".

kingmotley commented 10 years ago

Changing "Create source map files" and "Process source maps" for LESS to false had no effect.

kingmotley commented 10 years ago

Not solution related either. Created a brand new solution, added a brand new LESS file, and it reports "8/8/2014 4:22:04 PM: LESS: test3.less compilation failed: LESS: Unexpected token u"

ehorodyski commented 10 years ago

@kingmotley: Hopefully you and your team aren't on such a short time squeeze.

I have two steps that I always try:

1) Make sure the solution files aren't read-only from Windows explorer. This trips up my projects many times, though I can only count one instance where WE couldn't reach my file because it was read-only. For whatever reason, TFS seems to constantly put your files in read-only mode when working in Visual Studio.

2) Looks like you already tried, but try deleting the old LESS file (not before saving the contents in a spare file!) and see if pasting the code in that new file helps. Again, looks like you tried it but it doesn't mean I won't recommend it to anyone else!

kingmotley commented 10 years ago

Yeah, tried those. I'm spinning up a brand new dev box in Azure to see if it has the same issue

am11 commented 10 years ago

We can diagnose the problem by injecting some old-fashioned file.write lines in less service JS file.

Incidentally, are you getting this issue with other compilers (SASS, CoffeeScript, SweetJS, LiveScript) too?

kingmotley commented 10 years ago

Not sure about the other compilers as we don't use them. The brand new dev instance did not seem to exhibit the same behavior. Thanks MS for including a prebuilt VS 2013 update 3 image by the way!

kingmotley commented 10 years ago

Unfortunately, my time has run out. Will investigate more on Monday.

am11 commented 10 years ago

@SLaks, thanks for the links. I tried the github one. Added it as a package. Now, its giving me error because I can't reference Pri.LongPath.dll as <Reference> under <task> doesn't allow nested <HintPath>: http://stackoverflow.com/q/23918413

I tried copy the dll to $(MSBuildToolsPath) using copy task, but access is denied. I installed another package MSBuildTasks for GACUtil to install it to GAC, again access is denied.

Should we use Reflection instead? Admittedly, that would be very untidy workaround.. Is there a better way?

SLaks commented 10 years ago

Is that a compiler error or a runtime error? What is the exact error and FusionLog?

You may be able to make it work by calling Assembly.LoadFile().

am11 commented 10 years ago

Its the compile time error.

I reverted the code changes, will try to reproduce and capture logs from fuslogvw.

Yes; Assembly.LoadFile() would be a viable option for reflection, will give it a go. :)

am11 commented 10 years ago

@SLaks, its fixed via https://github.com/am11/WebEssentials2013/commit/66a41d6ecae5a3c76040d4daa6532e57d4fa2ba3.

Just used reflection where it was causing the issue.

kingmotley commented 10 years ago

Well after trying some more things, it appears that I'm getting the error message because there is no output. The code https://github.com/neoziro/less-hidpi/blob/master/hidpi.less and the default less file should produce a 0 byte css file but instead reports "8/11/2014 10:11:35 AM: LESS: test3.less compilation failed: LESS: Unexpected token u". As soon as I add a property to the body selector, it compiles correctly without an error message.

kingmotley commented 10 years ago

Trying to track back where the error is coming from, it appears to come from the node server, but it appears WE is making requests to the node server trying to get something from the root, and the node server is failing as well. I see many of these requests come and get errors returned. Not sure if that is normal either.

GET / HTTP/1.1
origin: web essentials
user-agent: web essentials
web-essentials: web essentials
auth: RrjPsKOIATd/yAM2BwezLYB+xEGdDV3kjRWXj85A6Qc=
Host: 127.0.0.1:18356
Connection: Keep-Alive

HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 11 Aug 2014 17:48:00 GMT
Connection: keep-alive
Transfer-Encoding: chunked

20c
{"Success":false,"Remarks":"TypeError: Cannot call method 'toLowerCase' of undefined\n    at Server.onRequest (C:\\Users\\rmckee\\AppData\\Local\\Microsoft\\VisualStudio\\12.0\\Extensions\\n51vx54l.h4z\\Resources\\nodejs\\tools\\server\\we-nodejs-server.js:111:70)\n    at Server.emit (events.js:98:17)\n    at HTTPParser.parser.onIncoming (http.js:2108:12)\n    at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:121:23)\n    at Socket.socket.ondata (http.js:1966:22)\n    at TCP.onread (net.js:527:27)"}
0

GET /?service=LESS&sourceFileName=C:%5CDropbox%5Cenjoy2%5Cenjoy2%5Ccontent%5Chidpi.less&targetFileName=C:%5CDropbox%5Cenjoy2%5Cenjoy2%5Ccontent%5Chidpi.css&mapFileName=C:%5CDropbox%5Cenjoy2%5Cenjoy2%5Ccontent%5Chidpi.css.map&sourceMapURL&autoprefixer&autoprefixerBrowsers=IE%20%3E=%209,%20last%202%20ff%20versions,%20last%202%20Chrome%20versions,%20last%202%20safari%20versions,%20last%202%20ios%20versions& HTTP/1.1
origin: web essentials
user-agent: web essentials
web-essentials: web essentials
auth: RrjPsKOIATd/yAM2BwezLYB+xEGdDV3kjRWXj85A6Qc=
Host: 127.0.0.1:18356

HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 11 Aug 2014 17:48:00 GMT
Connection: keep-alive
Transfer-Encoding: chunked

190
{"Success":false,"SourceFileName":"C:\\Dropbox\\enjoy2\\enjoy2\\content\\hidpi.less","TargetFileName":"C:\\Dropbox\\enjoy2\\enjoy2\\content\\hidpi.css","MapFileName":"C:\\Dropbox\\enjoy2\\enjoy2\\content\\hidpi.css.map","Remarks":"LESS: Unexpected token u","Details":"Unexpected token u","Errors":[{"Message":"LESS: Unexpected token u","FileName":"C:\\Dropbox\\enjoy2\\enjoy2\\content\\hidpi.less"}]}
0

GET / HTTP/1.1
origin: web essentials
user-agent: web essentials
web-essentials: web essentials
auth: RrjPsKOIATd/yAM2BwezLYB+xEGdDV3kjRWXj85A6Qc=
Host: 127.0.0.1:18356

HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 11 Aug 2014 17:48:00 GMT
Connection: keep-alive
Transfer-Encoding: chunked
20c
{"Success":false,"Remarks":"TypeError: Cannot call method 'toLowerCase' of undefined\n    at Server.onRequest (C:\\Users\\rmckee\\AppData\\Local\\Microsoft\\VisualStudio\\12.0\\Extensions\\n51vx54l.h4z\\Resources\\nodejs\\tools\\server\\we-nodejs-server.js:111:70)\n    at Server.emit (events.js:98:17)\n    at HTTPParser.parser.onIncoming (http.js:2108:12)\n    at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:121:23)\n    at Socket.socket.ondata (http.js:1966:22)\n    at TCP.onread (net.js:527:27)"}
0
am11 commented 10 years ago

When I compiled https://github.com/neoziro/less-hidpi/blob/master/hidpi.less with WE v2.3, it produces no css file and in output it says: LESS: hidpi.less compiled.

am11 commented 10 years ago

That is normal; when "Success":false," is found in return JSON, WE handles this case. But its not normal when service=LESS is in URL if (!/^[a-zA-Z0-9_-]+$/.test(params.service)) is satisfied and subsequently line 111 throw exception!