I am using ASP.NET MVC to build a web application, and I have fallen in love with the library Q.js, available here:
Q.js
Right now, I am using version 1.0, I load it up in the way that is most natural to me as an ASP.NET MVC developer. I have a place in my BundleConfig that just loads the script with my other scripts.
BundleConfig.cs
public static class BundleConfig {
public static void RegisterBundles(BundleCollection bundles){
bundles.Add(new ScriptBundle("~/bundles/scripts")
.Include("~/content/scripts/jquery.js")
// lots of other includes
.Include("~/content/scripts/q.js"));
}
}
So then in my view _Layout.cshtml, it's the normal simple process...
_Layout.cshtml
<head>
#Scripts.Render("~/bundles/scripts")
</head>
Easy enough, right? Yes, it works fine. But I notice that Q.js has another branch labelled v2.
Now, from what I can immediately tell, they are not that much different, but I do not believe the creator would have made a version 2 if they were not doing it to improve the product. I'd like to try it out, but this is where my experience fails me.
version 2 seems fundamentally different than version 1. Here is a link to it for quicker reference; Qv2
The q.js file starts out with this at line 43.
require("collections/shim");
var WeakMap = require("collections/weak-map");
var Iterator = require("collections/iterator");
var asap = require("asap");
I am accustomed to the require function being a part of requirejs, but I don't believe that is the purpose being served here. I in fact think this is intended to be consumed/run/used by node.js.
Now, since I am using ASP.NET MVC, I won't be using node.js. I've attempted to just put the expected folders and files in the right place so that they would be path relative to q.js, but that does not seem to satisfy it.
The Actual Question
Is there a way I can 'compile' Q.js 2.0 into a .js file that will not require node.js, and can be loaded normally within my ASP.NET MVC project? Can I use node.js to actually create an output .js file that has everything I need?
browserify is a tool for Node that takes all of the require()d dependencies, resolves them, and packages them into a single JavaScript file servable to the browser.
Related
I have a very strange requirement that I need to bundle everything together in one HTML page with my Durandal Single Page application. I can make this away with my dependencies as I am defining them with a name:
define("models.mapper", [], function() {
});
However, it seems like it will not be possible to bundle durandal stuff as it defines modules without names:
define(['require', 'jquery'], function(require, $) {
// ....
}
This is fine when you want to make it work with path references but it seems like this will make it hard to inline this into HTML. Any ideas or suggestions on this?
Require.JS requires you to have only one anonymous define per file so that it can use the file path+name relative to the base path to give it a name. If you would like to have the durandal source inline on your page as well then you'll need to update their define lines to give them the appropriate names (i.e. define('durnadal/system', ......).
An easier approach may be to just build your source code in the structure of a normal durandal project and then use the RequireJS optimizer (http://requirejs.org/docs/optimization.html) to build them into a single JS file - if you configure this correctly without minification then you can just paste the file contents into a script tag on your page and it'll still be legible!
If you really wanted to you could then just continue developing in the single HTML file however you really should look at automating all of this into a grunt workflow and it shouldn't be too hard and you'll have much easier to manage code. Note that you may even be able to use the durandal grunt task to do this, but I'm not sure what options it allows you to provide but you can definitely use the requirejs grunt task and build it into your workflow without minification. With some templating task you could then inject that output into your final HTML page.
I just downloaded the latest version of angular-seed, and I noticed a file I haven't seen before (in any project). There is a index-async.html.template file within the app folder. I know enough to know what asynchronous loading is, but I have never seen a .template file used in web development before. Does anyone out there know what this is used for, and if there is any benefit to using the index-async.html.template vs. just the regular index-async.html?
It looks to be used solely when using the Angular-Seed update feature. If you look into the update-angular.sh file in the scripts directory you find this:
# Update the inlined angular-loader in app/index-async.html
sed '/##NG_LOADER##/{
s/##NG_LOADER##//g
r app/lib/angular/angular-loader.min.js
}' app/index-async.html.template > app/index-async.html
So, it seems that Angular-Seed will auto replace some dependencies when you use the update. It does this by token replacing in .template and then overwriting index-async.html.
So, it isn't to be used in web development.
Currently, I've been trying to put Cassette into our Sitecore project and it's just fallen flat on it's face. I've had dotLess in the project already, but would like a more solid solution for cache-busting while bundling.
I can use Cassette in a normal .Net4 project, but just can't get it to work in our Sitecore project. (Ed) We were unable to get it to actually build any sort of bundles (checked /_cassette) and it wasn't outputting anything to the page. For us, the project isn't built but is instead using CodeFile and I'm not sure if that was part of the problem. In general, we kept getting the No bundle with path 'xxx' exception no matter what we tried. It's a bummer to because I would really wouldn't mind having CoffeeScript weaved into the solution.
Is there a solution that compresses/minifies javascript and can render dotLess files with Sitecore?
The empty response streams from Cassette when working in any of the Sitecore client interfaces are being caused by the rewriteHtml functionality that it implements.
By default Cassette will buffer and rewrite page HTML output. This allows partial views to insert <link> tags referencing stylesheets after the <head> tag has been rendered. The rewrite functionality gets invoked as a PostRequestHandlerExecute event handler.
The empty response streams that you are seeing are as a result of the output stream that has been rewritten not being flushed. A fix for this issue is to flush the output stream when Close is called on the Cassette.AspNet.PlaceholderReplacingResponseFilter class, this is shown below:
void WriteUncompressedOutput()
{
var output = GetOutputWithPlaceholdersReplaced(bufferStream);
var outputBytes = outputEncoding.GetBytes(output);
if (outputBytes.Length > 0)
{
outputStream.Write(outputBytes, 0, outputBytes.Length);
outputStream.Flush();
}
}
If you do not require the rewriting functionality a workaround is available now. Just disable the Cassette HTML rewriting feature, either in the web.config:
<configuration>
<configSections>
....
<section name="cassette" type="Cassette.CassetteConfigurationSection, Cassette"/>
</configSections>
<cassette rewriteHtml="false"/>
or in code:
public class CassetteSettingsConfiguration : IConfiguration<CassetteSettings>
{
public void Configure(CassetteSettings configurable)
{
configurable.IsHtmlRewritingEnabled = false;
}
}
This information is included in my blog post about using Cassette with Sitecore.
We ended up getting SquishIt to work rather easily and without much hassle besides getting the JavaScript files to play nicely together.
I want to use an external crypto library in my GWT project (client side). (particularly, Stanford Javascript Crypto Library, http://crypto.stanford.edu/sjcl/
I have added these lines in my project's gwt configuration file (MyProj.gwt.xml)
<script src="libs/sjcl/sjcl.js" />
<script src="libs/sjcl/core/sha256.js" />
And have created a new method in my security class:
public static native String sha256(String ptext)
/*-{
return sjcl.hash.sha256.hash(ptext);
}-*/;
But when I call it
String result = Security.sha256("password");
I get an error ("sjcl is not defined")
If someone who knows these issues and javasript could read the library and tell me the right way, I will be saving much time and effort - no digging in monstrous JavaScript.
UPD:
First thing I figured out, external library must be in /war directory
Second, I couldn't make GWT import the *.js files if I added the following just to gwt.xml files
<script src="libs/sjcl/sjcl.js"></script>
<script src="libs/sjcl/core/sha256.js"></script>
I had to add similar lines to Entry point's html source
<script src="/sjcl/sjcl.js"></script>
<script src="/sjcl/core/sha256.js"></script>
This way import works, I could check it with Chrome Inspector
I tried to use another library, not so complicated as sjcl, and it worked fine.
So, obviously, I'm not using sjcl right.
Another library is simpler, just pure methods, sjcl uses classes and stuff, but as I don't know JS at all, I can't figure out how to call such things properly without digging into JS syntax. I really would like to skip this part.
Can anybody look into the sjcl code and tell me how to call the method properly? The source is really small and JS pro can figure it out at a glance, I think.
UPD 2:
It turned out that adding the following code to gwt.xml is enough, just put library in /war and pay attention to the preceding "/" in the path. If you don't put it there, GWT will be seeking for you lib in module directory
UPD 3:
And don't forget to clear browser's cache or "not found" error won't go away
Make sure that when you talk about objects in the global context that you prefix them with $wnd, meaning the main window instance that the app is running in. This is documented in the JSNI docs, see https://developers.google.com/web-toolkit/doc/latest/DevGuideCodingBasicsJSNI#writing.
public static native String sha256(String ptext)
/*-{
return $wnd.sjcl.hash.sha256.hash(ptext);
}-*/;
"sjcl is not defined" means that you didn't import the sjcl file correctly.
Check the file path and make sure the browser can access the file.
I am using OpenRasta 2.0, and am hosting within a console application.
I would like to be able to return some static HTML pages and JavaScript files from this setup, for example:
/index.html
/jquery.js
The files are entirely static, i.e. no Handler or Resource is required.
I have added the appropriate files to the project, and initially tried the following syntax:
ResourceSpace.Has
.ResourcesOfType<object>()
.AtUri("/")
.HandledBy<HtmlHandler>()
.RenderedByAspx("~/Views/IndexView.aspx");
The .aspx file is added to the project under a folder 'Views', and is set the build action to 'Embedded Resource'. This results in a NullReferenceException at runtime when attempting to resolve the virtual path. If I set the build action of the file to 'Compile', then it will not compile, I'm guessing because the console project does not understand ASPX.
I have also tried the following shorthand syntax for this available if referencing the WebForms codec:
ResourceSpace.Has
.TheUri("/jquery.js")
.ForThePage("~/Views/jquery.js");
But this suffers from the same issues as my initial approach, although does remove the need for a dummy Handler. So as far as I can tell, the WebForms codec cannot be used within a console application because the ASPX files cannot be compiled.
I was able to return HTML using the Razor codec as this expects the view templates to be embedded. However - I was not able to return a JavaScript file with the appropriate media type using the same technique, and I had to turn my otherwise static files into .cshtml files with a #resource defined.
I can't find any examples online of returning static HTML and/or JavaScript using OpenRasta. I would expect to find a dedicated configuration API for this like the "TheUri" syntax but independent of the WebForms codec.
I could create my own 'EmbeddedFileHandler' to return the content of a static embedded file, but I feel like I'm missing something since this is such a simple use case...
Anything that depends on the asp.net pipeline being initialized (such as aspx webforms pages) cannot compile because the BuildProvider is not there to do it, mostly because webforms is too tightly coupled to the asp.net pipeline.
OR 2 was not really designed to be used as a full web stack outside of asp.net for serving static content, as usually the host environment is better suited at doing it, but that's definitly something we're going to address in 3.0.
What I'd suggest is something along the lines of registering FileInfo as a resource, create a handler that can scan the file system for the files you want, and provide your own codec that either stream the data itself or call the API for the host http listener. It should be about 20 lines of code tops and would make a great blog post. :)