Bundle.config confused about debug and release and minification - bundle

I read this article http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification and I just feel there's a lot of content missing from it.
I was developing on a project using unminified javascript files. However, this became an issue when I decided to publish my project to another server, where bundle.config hijacks my javascript files and does things I never knew that I needed to test on my development, and now my dev machine is throwing all kinds of javascript errors. So now, I'm here, reading up on what bundle.config does with min files.
After reading the article, I made the following assumptions:
If I set my project to debug mode, my project will get all javascript files that does not contain any "min.js" files.
if I set my project to release mode, my project will attempt to get all my min.js files, and if there are no min.js files, then the non-min files will be converted to a minified version.
Based on those two assumptions, turns out I was wrong. Switching to Release mode doesn't do anything with min files, it acts the same way as my Debug mode.
Secondly, going into the web.config and setting the following to false (previously true):
<compilation debug="false" />
takes all my files that are not minified and minifies them, ignoring any min files I have! I don't see anything about File.min.js, all I see is something like: "File?v=dw-fikdksdm..." which is fine, since this is considered a "bundle" and gets minified, but why can't I just see my mins loaded? and what happens if minification and bundling throws javascript errors? What would I have to do at this point? Can I prevent some javascript files from not being included in a bundle and/or minified?
Also I've noticed there are a couple of 403 errors that occur when tried to load up the javascript resources.
Can someone explain what's going on here and why this is goes against my original assumption?

Okay, here are a few things I discovered about this:
When in debug mode, and you check the web.config:
<system.web>
<compilation debug="true">
then all your javascripts will be preserved within the bundle virtual directory (they will not merge into a single file and they will not be minified).
When switching to release mode, then switch to:
<system.web>
<compilation debug="false">
so that all your javascript files within a bundle are minified and compiled into a single file, this reduces round trips to the network. Please note, one file is created for each bundle.
If you want to get the optimizations enabled regardless of whether or not you're in debug mode, then set BundleTable.EnableOptimizations = true, which forces the minification and bundling. If you leave this out of the code, then BundleConfig will look at the web.config instead.
RegisterBundles(BundleCollection bundles) method in BundleConfig.cs, you put in:
BundleTable.EnableOptimizations = true;
bundles.UseCdn = true;
var cssTransformer = new CssTransformer();
var jsTransformer = new JsTransformer();
var nullOrderer = new NullOrderer();
and this is how you'd add in javascript files:
var jqueryBundle = new CustomScriptBundle("~/bundles/jquery");
jqueryBundle.IncludeDirectory("~/Scripts/JQuery", "*.js");
jqueryBundle.Transforms.Add(jsTransformer);
jqueryBundle.Orderer = nullOrderer;
bundles.Add(jqueryBundle);
Couple notes:
Bundle.config does ignore all min files. I added File.min.js, and File.js, and it ignores File.min.js, and it minifies File.js and bundles it with other files included in the bundle. I checked because when I minified one of the files myself, all the variable names (not the structured code) compared to what was downloaded in my website was completely different than the min file I included in the project. So, this verifies that min files are not needed in your project.
Bundle.config ignores minifying any files named like this.. "File.debug.js", this will never be minified, in fact, it will never be included in your project in release. I found this out after realizing one of my javascript files never making it to the site.
403 errors will occur if you use "Content/css" as your virtual directory of where your bundle will appear, this needs to be changed to "bundles/css" and the 403 will go away like so (using razor):
#Styles.Render("~/bundles/css")
meaning if you have this in your code (notice where ~/bundle/css" is, this will be where your css files will go):
BundleTable.EnableOptimizations = true;
bundles.UseCdn = true;
var cssTransformer = new CssTransformer();
var jsTransformer = new JsTransformer();
var nullOrderer = new NullOrderer();
#region CSS Styles
var cssBundle = new CustomStyleBundle("~/bundles/css");
cssBundle.IncludeDirectory("~/Content/CSS", "*.css")
.IncludeDirectory("~/Content/CSS/Override", "*.css");
cssBundle.Transforms.Add(cssTransformer);
cssBundle.Orderer = nullOrderer;
bundles.Add(cssBundle);
#endregion
If your css has a relative path, this may also be changed, so look for 404 errors
Not all minified files will behave the way you want them to.. so you will have to ultimately do a semi bundled version (or you do not have to minify any js at all, and just bundle them)
But if you want to continue on doing the minified javascript and you do not know which files is throwing the error, the following steps will help:
Bundle everything
Open your browser and find all the sources of your bundled minified js
Copy working bundled js into another file
start manually inserting javascript using the tags instead of bundleconfig.cs, and keep adding them one by one until one fails.. if that fails.. then you'd have to use the un-minified version of that project
repeat step 3-4
I wish there was better documentation of bundle.config at the time of this writing, but I found this entire experience to be severely disappointing.

Related

Visual Studio Code C++ Intellisense Performance Problems

I have a bigger C++ Project. I use the Micrsoft C++ Extension with the default settings.
Intellisense takes sometimes over 1 minute to catch up with suggestions.
In order to solve the problem, I went through the settings. I've seen it is possible to set the Intellisense engine to "Tag Parser", it solves all the performance problems as expected, but unfortunately, it deactivates Error Squiggles.
Is it possible to combine Tag Parser Intellisense with the default error checking, if the error checking takes a minute it wouldnt be a such a problem?
Or do you have other ideas to solve the performance problem?
Depends on what compiler your running. I'm using Visual Studio Build Tools. For my UE4 project, source file Intellisense is pretty snappy but header files are really slow. Sadly I believe headers will always be slow on large project's using the default Intellisense. This is because VSCode recalculates Intellisense with every line of a header file you write.
Off topic info:
This is also why you should disable Auto PCH with “C_Cpp.intelliSenseCacheSize” set to 0. Let's say you have a class with a large AutoPCH cache file of 1 Gigabyte (not uncommon with Unreal Engine). VSCode is now deleting and writing this cache with every line you type in a header file. This won't help with Intellisense speed unfortunately.
Back to topic:
Make sure to custom tailor your "C_Cpp.default.includePath" and only include the paths you need. This is used for Default Intellisense but will also be used for Tag Parser if you don't specify any Tag Parser path with "C_Cpp.default.browse.path". Also note that any path in "C_Cpp.default.includePath" is NOT recursively searched for subfolders. You can override this behavior by adding /** to the end of the path. But use it wisely.
For a large project, a better way than using the includePath settings is to use compile commands (compilation database). "C_Cpp.default.compileCommands" lets you use a json file to custom tailor every include path for every header and source file you have. So now default Intellisense is only using the include files it needs for a particular file. You'll have to research on how to create a compile commands json file. There are tools that can auto create this. Unreal Engine actually moved to compile commands for 4.26 but there were no speedups because they still include everything for every file. I believe they have to do it this way based on how UE4 header includes are setup but I'd have to research.
Another way is to limit the #includes in header files and use forward declarations. Put your #includes in source files. This is probably one of the main reasons Unreal Engine header Intellisense is so slow. When creating a class it auto includes header files in the classes header file. Those included headers also include other headers and so on. So when VSCode recalculates header file Intellisense it's very slow. Source files don't seem to care though.
More info:
I forgot to mention about Tag Parser Intellisense. Tag parser info relies on "C_Cpp.default.browse.path" for include files. If you don't specify anything in "C_Cpp.default.browse.path" then:
Anything in "C_Cpp.default.includePath" will be use for tag parser Intellisense.
Your project's path will automatically be added (see Note below on why this might be bad)
Note: Any path used for the browse path that doesn't have /* at the end will be searched recursively for any subfolders that also have header files to cache.
Note: For multifolder projects, all folder project directories(recursive) will also be added to the tag parser includes for one big Tag Parser cache file.
The Tag Parser is still used when using Default Intellisense. It's used for switching between header and source (Alt+O) and for finding symbols. So you should still tweak the Tag Parser paths to your liking.
For large projects the Tag Parser can take 20+ minutes to finish creating it's cache file when you first open the project. You wont get Tag Parser Intellisense until it's finished. For Unreal Engine 4.26 this file is around 1.5 Gigabytes. Good thing though is that is doesn't get deleted and recreated like the Default Intellisense cache files.
You may need to tweak your "C_Cpp.default.browse.path" instead of not specifying one and and letting VSCode do what it wants.
I will say for source files you will miss having Default (Context Aware) Intellisense. But you can try Tag Parser Intellisense if you can get it to work.
Note: You can see when Intellisense is working. Default Intellisense is a fire symbol and Tag Parser Intellisense is a cylinder found on the bottom bar.

Laravel Mix: What is the benefit of extracting vendors?

My minified bundle size is 246kb. I am seeing if I can getting smaller and I read that extracting vue and jquery using mix.extract(['vue', 'jquery']); can help do this. I added this to webpack.mix.js` and now it created 2 files rather than 1. It made: 1) app.js which is 161kb and 2) vendor.js which is 180kb. What is the benefit of this if both need to be included in the page anyways?
This is mainly abut caching unchanged files. For example: while you developing app you are changing the files, adding your own code to your project and then recompile them all together. But vendors are the core libraries which you are never edit their code again. So there is no need to compile them again and download all source code in app.js file. Thus when you extract vendors which they are unchanged files then your cached content size will increase and it also decrease download time of your application because of less changed files must be downloaded again.
It helps you to optimize the file size of the files that client needed to download. Thus speed up the page loading speed even you have updated your site.
Check the documentation.
One potential downside to bundling all application-specific JavaScript with your vendor libraries is that it makes long-term caching more difficult. For example, a single update to your application code will force the browser to re-download all of your vendor libraries even if they haven't changed.

grunt-usemin renames fonts with revision headers but doesn't update #font-face rule in css/sass

In generator-angular, grunt-usemin is configured to revision static assets using grunt-filerev.
Grunt-filerev's sole responsibility (I looked through the code) is to rename the files. It then returns a summary object of the files renamed.
During the build process, grunt-usemin will then rename references to the static files in your projects folders (in my project, I can see it happening with imgs in html templates).
Fonts, however, get the revision hashes rename, but their references in my Sass files are not updated to reflect that - therefore, I get 404s on all my custom fonts.
I have already reached out time and again on issues in GitHub, but it looks like the good folks over there are respectfully busy with other business.
The question is: is this a configuration error on my part which is easy to adjust, or a bug in grunt-usemin.

Cross-project references between two projects

Is it possible to make a reference between two TypeScript projects? Assume we have the following project structure:
Module1.ts contains:
module TestModule {
export interface Interface1 {
}
}
Module2.ts contains:
module TestModule {
export interface Interface2 extends Interface1 {
}
}
Test1 is referenced in Test2. I get an error Could not find symbol 'Interface1' in Module2.ts. It works within one project, but I don't know how to make it visible from the other project... Maybe it's not possible for now.
[Edit 1.]
When I try to use TestModule.Interface1 pattern, I get the same error (said in different way). But the IntelliSense sees my Interface1:
[Edit 2.]
I have noticed I can't use files from the other project. Even if I have a correct reference (/// <reference ...) added and linked all the files in my 1st project.
There's lots of ways you can do this.
Option 1 - Project References (TypeScript 3.0+)
If you are using TypeScript 3.0 then look at using project references. Read more here.
Option 2 - Build script
Use something like gulp-typescript, grunt-ts, or just a batch script to copy the files over into a folder in the main project.
Alternatively, run a build event in Visual Studio that will copy the files over to the main project.
Option 3 - npm package
If you use npm, you could create a package for your other project. Then you can use your package in your main project. Specifying a local dependency is a good way to do this or by using something like sinopia, which is a private repository server. I've never used it, but it looks like it would work well.
Option 4 - NuGet package
You could look into creating a nuget package and then installing it locally.
Option 5 - --declaration --outDir compiler option
You can set the --outDir compiler option or the outDir property in tsconfig.json with the directory to your other project then also compile it with --declaration so that it generates the declaration files (.d.ts) too. For example: --declaration --outDir ../Test1/External.
Original Answer (Using --out)
You can do something similar in Visual Studio if you right click on your library project and click properties. In the TypeScript Build tab, check off the option to Combine JavaScript output into file and specify the location in your main project you want it to go (Ex. $(SolutionDir)/TypedApp/External/TypedLibrary.js). Then also check off Generate declaration files in order to generate a .d.ts file.
Once this is done, build your library project and then include the .js, and .d.ts in your main project. Include the .js file in your html and reference the .d.ts in your typescript files.
Each time you rebuild the library project, it will automatically update the main project with the changes.
The solution suggested by #dhsto works but I have found an alternative using linked folders. I have written about it in detail in this article, here is how it can be implemented:
It can be achieved by creating a folder to hold your references, I like to name this “_referencesTS”, the folder will contain all of the links to files from Test1. This can be done individually but would become very cumbersome if it had to be done for each new TS file. Linking a folder however will link all of the files beneath it, this can be done by editing the csproj file.
To edit the file right click the Test2 project and click “Unload Project”, then right click the project and click “Edit Test2.csproj”. Navigate to the <ItemGroup> that contains the <TypeScriptCompile> tags and insert the code below:
<TypeScriptCompile Include="..\Test1\**\*.ts">
<Link>_referencesTS\%(RecursiveDir)%(FileName)</Link>
</TypeScriptCompile>
Replace the relative path to the location of your TS files in Test1, this uses the wildcarding (*) to link all .ts files (dictated by the *.ts) within all sub folders (dictated by the \**\)..
The TS files within these folders will now appear linked within Test2, allowing for automatic typescript referencing.
Note: The only downside to this approach is that when a new file is added to Test1 within a linked folder, the user has to unload and load the project or close and open the solution for it to appear in Test2.
Frustrated with the state of affairs, I wrote a NuGet package that mostly solves this problem. Using the NuGet package you can just add a reference from one project to another and it will do the work of copying files around in a way that is safe from accidentally editing the wrong file and still gives intellisense and debugging.
Details can be found in the Readme.md, or you can just install the NuGet package and run (I recommend at least reading the how to use section).
https://github.com/Zoltu/BuildTools.TypeScript.FromReferences
I just want to add to the answer of David Sherret that the lib files to the TypedApp project could be added as Link files instead of depending on post build events. I'm having some issues with post build events in big solutions with a lot of projects, and the link files are now working ok for me. (I cannot add a comment to the answer because I only have 35 reputation points).
If you are compiling with the --out parameter you can simply reference Module1.ts from Module2.ts using /// <reference To learn more about code organization patterns in TypeScript see http://www.youtube.com/watch?v=KDrWLMUY0R0&hd=1
What visual studio language services sees available (which is everything) is different from what you compile and actually have available at runtime.
If you need to share the code between multiple projects you can always create a symbolic link on each project where you need it.
http://en.wikipedia.org/wiki/Symbolic_link
basarat's answer is the closest to being the most reliable solution for cross-project TypeScript references. However, when merging shared TypeScript code with a referencing project's TypeScript (important, for example, if you need to target different ECMAScript versions), the Source Map file doesn't resolve to the shared project's directories, so debugging won't work (in fact, Visual Studio often crashes after adding breakpoints to the files referenced in another project).
Linked files of any kind (Visual Studio links and symbolic links) don't work with debugging in any system (Visual Studio, Chrome, WebStorm, etc.)--linked files essentially don't exist to the ASP.NET debugger, nor any other debugger; they exist only in Visual Studio.
Please see this question/answer indicating what has worked great for both solid code maintenance and debugging in Visual Studio, Chrome, and Firefox, while still retaining the ability to combine shared code with the referencing projects' code (important, for example, if you need to target different ECMAScript versions): Visual Studio: How to debug TypeScript in a shared project using IIS Express and cross-project references (no linking or duplicating files)
The accepted answer disallows debugging in Visual Studio when a breakpoint is set in the Shared project. (At best the debugger will stop on a line in the compiled javascript, but not the original Typescript and certainly not in its original project location.)
In the Shared project's properties, let's say that Combine Javascript output into [a single] file is checked and set to AllShared.js, which also makes a AllShared.d.ts file because Generate declaration files is checked, and also makes a AllShared.js.map because Generate source maps is checked.
The referencing project should NOT copy or link these files in the way the accepted solution does. Instead:
Part 1, in the referencing project, create /typings/tsd.d.ts if it doesn't already exist, and append to the bottom of that file the line ///<reference path="../../SharedProject/AllShared.d.ts" />. Once this is done, (and at least one successful compile of SharedProject is done), Intellisense and the Typescript compiler should see Interface1 etc. (You'll likely get a red squiggly line underlining the statement if the path/file doesn't exist, which is nice.)
Part 2, in the referencing project's index.html, add the line <script src="http://localhost:29944/AllShared.js"></script> before that project's own script tags. The localhost part comes from the Shared project's Properties, Web tab, Project Url. (Both 'IIS Express' and 'Local IIS' work.)
Now when you run the referencing project, you should see Internet Explorer** request the relevant files from their respective "websites". Visual Studio breakpoints should be hit regardless whether they're in SharedProject or the referencing project.
. Although this solution works without gulp/grunt/powershell, Visual Studio's Combine Javascript output into one file doesn't glue together the files in any particular order, and it will eventually break your code. Then you'll need to add Gulp/etc. to the referencing project to insert a <script src="http://localhost:29944... tag for each file in Shared***, because keeping index.html updated by hand is a poor option. (Adding Gulp to the Shared project, to concat the .js and .d.ts files into singles runs into an issue with .js.map files, which can't be simply concatted.)
** IE and VS are both Microsoft products, so IE really works better if you want to use VS's breakpoints and debugger instead of a web browser's.
*** Gulp doesn't like injecting urls, only filepaths. Given HTML comments in index.html like <!-- SharedStuff:js --><!-- endinject -->, circumvent this like so:
gulp.task('insert-into-html', [], function () {
var common = gulp.src(['../SharedProject/**/*.js'], { read: false });
return gulp.src('./index.html')
.pipe(inject(common, {
relative: true,
name: "SharedStuff",
transform: function (filepath) {
return '<script src="http://localhost:29944/'+filepath+'"></script>';
}
}))
.pipe(gulp.dest('./'));
});

Files added to config.assets.precompile are not served in development

I am using the activeadmin gem which proposes a little weird way of including additional assets to those automatically generated by the gem:
https://github.com/gregbell/active_admin/issues/492
My problem however is that though in config/application.rb I do set
config.assets.precompile += ['active_admin.css', 'active_admin.js', 'my.css', 'my.js']
my_file.css and my_file.js are not served in development mode, it's Routing error.
I have registered them with the activeadmin's own config.require_javascript and config.require_stylesheet, which seems to work, since generated html contains the respective script tags.
However the /assets/my.css and /assets/my.css are not responsive.
What could cause a problem, how do you think?
It turned out that the files I was trying to add were corrupted somehow since creating the new ones and copying the content inside made a trick.
I was including the .js and .css files of this plugin:
http://loopj.com/jquery-tokeninput/
which is fine not taking this issue into account.

Resources