17 Comments

For the past couple of years, Web Essentials have been including features for bundling and minifying JS and CSS files as well as compiling LESS, Sass and CoffeeScript. As of Web Essentials 2015 that is no longer the case. However, I’ve gotten so many requests to bring these features back that I’ve created two new Visual Studio 2015 extensions to deal with it. And I need your help testing them before Visual Studio 2015 goes RTM.

Bundler & Minifier

This extension allows you to perform bundling and minification of JS, CSS and HTML files very easily and, in my mind, takes a better approach to how it’s done over the same feature in Web Essentials.

Download from VS Gallery Bundler & Minifier
Download nightly CI builds from vsixgallery.com
Source code on GitHub  
 

Web Compiler

Based on what I learned building compilers for Web Essentials, this extension improves on the stability and usability significantly. You can now very easily specify which LESS/Sass/CoffeeScript files to compile and with what settings for each file individually.

Read more and download Web Compiler
Download nightly CI builds from vsixgallery.com
Source code on GitHub 

Why new extensions?

In the past year or so, I’ve started separating out features from Web Essentials into smaller single-purpose extensions. I’ve done that for several reasons.

  1. It keeps the Web Essentials source code smaller and more maintainable
  2. Since it’s smaller, I hope to get more contributions from the community
  3. If one feature in Web Essentials cause a crash/hang, then the entire extension is broken
  4. Issues are much easier to deal with in smaller extensions
  5. By having smaller extensions, you can install just the ones you need

The code in Web Essentials for dealing with Bundling, minification and compiling was very error prone and almost impossible to maintain. For several months I wasn’t even able to compile Web Essentials itself due to a lot of weirdness in the node.js based compilers being used.

Help wanted

Given that these two extensions are brand new and the amount of requests for them has been so immense, it becomes really important that they both are working awesomely when Visual Studio 2015 goes RTM. So please help me test them out by installing them and reporting any issues to their GitHub issue tracker. If you want to contribute then you’re more than welcome to send pull requests with modifications and/or unit tests. If you want to add new features, all I ask is that you open an issue first so we can discuss it before sending the pull request.

These extensions are for a huge portion of Visual Studio web developers who don’t want to setup Grunt/Gulp to handle the client-side workflows, but instead have happily relied on Web Essentials in the past. These extensions are for you.

4 Comments

Update Jan 16, 2015 – The newly released Visual Studio 2015 CTP 5 also supports Grunt/Gulp Intellisense using the files available in this blog post. In fact, the Intellisense will be a lot better in CTP 5 due to the support for Object Literal Intellisense in the JavaScript Editor.

I’ve spent some time figuring out how to get Intellisense working for Grunt and Gulp in the JavaScript editor. Today, I hit a breakthrough that lights up Intellisense automatically. All it requires is that you perform the following two steps:

  1. Download the JavaScript Intellisense files (zip with two .js files)
  2. Copy them to C:\Program Files (x86)\Microsoft Visual Studio 12.0\JavaScript\References

If you’ve installed Visual Studio under a different path, then you’ll have to find the correct folder at that location instead.

This trick also works in Visual Studio 2015 Preview, but then the folder to copy the JavaScript files to is: C:\Program Files (x86)\Microsoft Visual Studio 14.0\JavaScript\References

Here’s what it looks like when editing GulpFile.js:

GulpFile.js Intellisense

And here is GruntFile.js:

GruntFile.js Intellisense

This is my first attempt, so please give it a try and let me know what you think. I want to try building this into Visual Studio 2015 so your feedback is super important.

3 Comments

So you are building a website using static .html files instead of any server side technologies such as ASP.NET. That’s cool for various reasons, but my favorite is that it allows any developer on any platform to easily contribute on GitHub. No server-side components needed. Great!

You’re almost done and decide to run performance analytics tool such as Google Page Speed on your site. Now the problems begin. Here’s some of the items that you are told to optimize:

  • Minify HTML
  • Set far-future expiration dates on static resources (JS, CSS, images etc.)
  • Use cookieless domains for static files
  • Use a CDN

You could set up build processes using Grunt to do all of this work, but it is not that simple to do – especially after you already built your website. Most of these tools require you to setup your project in a specific way from the beginning.

When you think about it, none of the above mentioned performance issues are relevant on a developer machine, they are only applicable to the live running production website. So if we could let the production server do some tricks for us to make all of this easier and without us having to modify our source code, that would be great.

StaticWebHelper

While building SchemaStore.org I encountered exactly these issues and decided to create a generic and reusable solution. My idea was to let IIS handle the issues while the website could still run statically without IIS at all on a development machine.

The StaticWebHelper NuGet package does exactly that. Here’s what it does:

  1. Minifies any .html file at runtime and output caches
  2. Fingerprints references to static resources
  3. Creates a URL rewrite rule for handling the fingerprints
  4. Set’s far future expiration dates in the web.config
  5. Has support for CDNs using an appSetting

Fingerprinting is a browser cache busting technique for changing the URL to references files, so the browsers will load any changes while still featuring far-future expiration dates. Read more about fingerprinting.

#1 and #2 happens at runtime, but only once.

 <handlers>
   <add name="FingerPrint" verb="GET" path="*.html" type="StaticWebHelper.FingerPrintHandler" />
 </handlers>
It output caches the results so that no additional files are being created on disk and you get performance similar to static file serving. Any time a referenced JS, CSS or image file is updated on disk, it generates new fingerprints automatically. It also handles conditional GET requests (status 304).

#3, #4 and #5 are all handled in the web.config.

<add key="cdnPath" value="http://schemastore.org.m82.be/" />
<add key="minify" value="true" />

I use a custom reverse proxy CDN with nodes in both Europe and North America for serving static files cookieless. If you don’t need a CDN, it is still a good idea to use a different subdomain to handle static resources such as s.mydomain.com. StaticWebHelper supports both scenarios equally and it’s easy to setup in web.config.

For fingerprinting to work, it adds a URL rewrite rule in web.config.

<rule name="FingerPrint" stopProcessing="true">
  <match url="(.+)(\.[0-9]{18})\.([a-z]{2,4})$" />
  <action type="Rewrite" url="{R:1}.{R:3}" />
</rule>

To see this in action, check out the source code of SchemaStore.org on GitHub. Especially, take a look in the web.config file.

Azure Site Extensions

If your website is hosted on Azure, then it’s really easy to let an automated Site Extension do further optimizations such as image optimization and JS/CSS minification. Read more about that here.

0 Comments

The current JavaScript Intellisense in Visual Studio is generated based on IE’s JavaScript engine Chakraand its support for the various browser/DOM APIs. The cool thing about that is that the accuracy is really high, since the good folks on the IE team spends a lot of time implementing the APIs according to the web standard specifications. Awesome!

However, this means that the Intellisense in Visual Studio doesn’t include APIs that IE doesn’t support yet, such as the Shadow DOM, Server-Sent  Events, HTML Imports etc.

The good news is that the JavaScript editor in Visual Studio can easily be extended to include Intellisense for all of these APIs. The even better news is that it can all be done in JavaScript.

To do that, we need 2 things:

  1. Add a JavaScript file to the global Visual Studio references
  2. Add code to that file containing Intellisense

So let's get started.

Add a .js file to the global references

First of all, we must create a .js file somewhere on disk. Potentially on a network share for your entire team, or just in the user's documents folder. It doesn't matter where.

Then add a reference to it in Tools -> Options like this:

JavaScript references

Make sure to chose Implicit (Web) in the Reference Group dropdown. Otherwise it won't take effect for web projects.

Write some Intellisense

Now that the file has been referenced by Visual Studio, we can start adding additional Intellisense to it. Open the newly created .js file as well as any other JavaScript file. We are using the other JavaScript file to test the changes we make to our Intellisense file. We don't have to restart VS to see the changes, just save your Intellisense .js file and the changes take effect immediately.

Let's start by adding support for the new HTML Imports API. It's really simple because it only adds a single new property to DOM elements called import. So an example of how to use it would be something like this:

var link = document.querySelector('link[rel=import]');
var partial = link.import;

The value of partialis a Document element just like window.document. To add Intellisense for the import property, simple add this one line to your Intellisense .js file:

Element.prototype.import = Document.prototype;

We are extending the prototype of the Element object with an import property and giving it the value of the Document object's prototype. So now when we type this into our other JavaScript file, we should see this Intellisense:

HTML Imports Intellisense

What I've found to be a good rule of thumb is to make the added Intellisense apply more broadly than the spec might call for. In the example above, the import property should only apply to <link> elements (HTMLLinkElement), but since VS can't always know what type of element you're referencing, it makes good sense to just make it apply to all elements. It's up to you of course, but I think that this makes for a better experience.

Web Essentials

Today, Web Essentials 2013 ships two .js files that improves JavaScript Intellisense. One adds JSDoc comment support and the other adds many of the missing APIs including support for Angular.js.

The issue is that Web Essentials can't always add those two files to the global references.

If you already have Web Essentials installed, then you already have these two files located in C:\users\yourname\.

The files are:

  • JsDocComment.js
  • Modern.Intellisense.js

So make sure to check if you already have them in the JavaScript References options:

image

If not, just add them in the above dialog. The APIs that are added through Web Essentials are:

  • Shadow DOM
  • Vibration API
  • Fullscreen API
  • Canvas (improvements)
  • Server-Sent Events
  • HTML Imports
  • Object.observe()
  • Angular.js

Contribute

You can help improving the JavaScript Intellisense shipped in Web Essentials by adding support for more APIs to the Modern.Intellisense.js file on GitHub. A great way to get started is to go to status.modern.ie to look for APIs that Internet Explorer doesn't yet support. Under each API there's a link to the W3C specification.

As an added bonus, all of this also applies to Visual Studio 2012, but you have to get the two .js files from Web Essentials 2013 manually since they aren't shipped with Web Essentials 2012.

5 Comments

Earlier this year, Sayed and I released Web Developer Checklist to help web developer adhere to best practices. Checklists like these can be really helpful to make sure we don’t forget anything before releasing new or updated websites.

imageNow we’re introducing Web Developer Checklist as a Chrome extension that can automate a big portion of the checklist. The extension let’s you run checks for various best practices on any website - including your own running from localhost.

It performs a serious of checks by analyzing the DOM as well as integrating with 3rd-party services like Google PageSpeed.

Next steps

This first version of the Web Developer Checklist Chrome extension does a serious of really valuable checks. The next releases will have even more.

Specifically, we’re looking at adding:

  • HTML validation
  • CSS validation
  • Accessibility validation
  • JSHint
  • CssLint
  • Guidance for each item Done v.1.4.4

We think these checks would be hugely beneficial. If you have ideas for other checks that can be automated, please let us know in the comments below.

Open source

The Web Developer Checklist Chrome extension is open source and hosted on our GitHub org. As always, pull requests are more than welcome.