Grails run-app services javascript starting with NODE_ENV line - javascript

When running a Grails 4 application using 'grails run-app' every javascript file provided by the webserver is starting with the line:
var process = process || {env: {NODE_ENV: "development"}};
This line is not part of the javascript source code and is probably generated by the asset-pipeline plugin. This confuses the hell out of my development environments (both intellij and VSCode) and ruins breakpoint handling.
Does anybody know how i can avoid 'grails run-app' generating this header line?
Some version information:
Grails 4.0.5
asset-pipeline-grails:3.2.4
java-version 11.0.9.
I have generated the 'helloworld' application using 'grails create-app' and run it without modifying anything using 'grails run-app'. Even now every serviced javascript file has the header line.

It turns out you need to overwrite the default asset pipeline with your own pipeline. Your own pipeline will leave out the JsNodeInjectProcessor which is the culprit.
Defining your own pipeline involves the following steps:
modify your build.gradle so all asset-pipeline modules are available at compile time
create MyJsAssetFile based on JsAssertFile from the -core package. From the processors variable, leave out JsNodeInjectProcessor.
create a file main/resources/META-INF/asset-pipeline/asset.specs, leaving out asset.pipeline.JsAssetFile and replacing it by MyJsAssetFile
Doing this will result in javascript files without the header line, and most importantly my Intellij IDE being able to debug my javascript logic embedded in my grails application.

Related

Can I generate source code during webpack processing / bundling?

From another question I got a way to dynamically scan source folders using WebPack API, and I've written some code that loads each found class using dynamic imports.
But there's nothing really dynamic here, since source files will be fixed once bundled; so the above code could then be replace with one that statically imports each discovered class.
Is there a way to generate source code during webpack execution and add it to the bundling process?
Whether possible the code should be part of the application, not a separate plugin or anything.

Using the same static data in both C# classes and JS files in the same MVC project without rebuilding again and again at runtime

Issue
My issue (in as general term as I can put it) is that:
* Have some static data (changes rarely and requires a re-compile of the site) in the form of a series of configuration strings like URI, hash, etc for several files that needs to be use in both the c# of the MVC site as well as some of it in some JavaScript.
* We don't want to duplicate the data as it's bound to get out of sync and cause us all sorts of hard to track down bugs.
* Ideally we would like to create the JS file with the data inserted into it at build time taking the data straight from the c# class it's stored in so it doesn't cause lots of wasted time re-building the JS each time it's asked for and nether does the c# class need to dig around in a js file trying to pull out the data.
Research so far and potential solutions
T4 Text Templates
We have considered T4 (.tt Text Template) to build the JS but have only just come across T4 and have not yet found a way (if one exists) to access existing project classes in the T4 file to generate the JS.
Using something like Gulp
We could also use Gulp and build something in JS to extract the data from the class file directly to build the JS but up to now we have stuck with NuGet, a few VS extensions and our TFS deployment server and didn't really want to add the complexity of Gulp and ether switching everything back over to it or splitting our build across Gulp and MSBuild/TFS. We have a little experience with this and found it caused us more issues with keeping it running than it's worth.
Build & cache JS file at runtime
As mentioned we could also create a page that builds and returns the JS at run time. We could cache the output after the first build as it wouldn't change but that's still hitting my MVC instead of just a file and the cached data would need to be stored and retrieved.
This last method (Build & cache JS file at runtime) is the one I'm leaning towards as it would be the cleanest, easiest to follow by new devs in the future and wouldn't require any extra packages/libraries adding to the project.
While building and caching the .js file at runtime is certainly an option, this would waste a small amount of both RAM and CPU cycles on the web server. Not to mention, the caching could cause confusion during debugging.
IMO, a better option would be
Put the static data into a common file format such as JSON or XML
Use T4 templates to read the common format and build both the .js and .cs files
Create a batch file to run the T4 transformations and add it as a pre-build event in the .csproj file as in this answer
That way the files are built with the data as part of the normal build process (including during debugging), and the .js file can be deployed as a static file to the server as part of the normal deployment process. To help avert confusion, the T4 template can include a warning not to modify the output files during development.
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
You could of course replace T4 with a custom built console application that reads the source data from JSON or XML if you aren't familiar with the T4 technology and don't want any extra .tt files in your project that may confuse new developers. But you should take into consideration how often the .cs and .js files will change in development - T4 doesn't have to be compiled into a tool in order to use it.
Gulp is also an option, but it isn't worth adding it to the build pipeline for something as trivial as this. Only consider it if you are already using Gulp in the application or build.
But however you slice it, this sounds like a better candidate for a build step than something that happens at runtime.
The solution we went with in the end was to run the creation code when the website first runs by adding a call in the Application_Start() (called/or Global.asax) like this:
protected void Application_Start()
{
...
// Generates (replacing if required) all the static files that require dynamically creating
DynamicFileConfig.GenerateStaticFiles();
}
This allows the application/website to be up and running and giving us access to all the classes for this project without needing to split them out or add any complex libraries.
It also requires no extra build steps or any extra maintenance and in our case the processing time is done during the release (as our release system tests the site kicking off the Application_Start() code).
The code that kicks off is just a small static class with static functions the generate the file (it's not stored in our repo) or replace if it's already been created.

Exclude Javascript function within a (TFS) build

Hello I got a question regarding including or excluding specific contents of my JS file within my C# project. I developed a new JS functions which is still under development and it is based in my library.js file. Within C# you can set build flags in order to say which sections should be included whenever a build is running. FYI I am using TFS to build.
Now I was wondering is there a way within Visual Studio or TFS or some other mechanisme where I can say that a particular piece of code within my library.js file should not be included within my build? Like I can do with build flags within my C# code.
Perhaps I can use some prebuild steps or trying to come up with some JS code which check the current active buildflags?
Anyone have any ideas? I know that removing the code will solve it but that is not what I am looking for.
On TFS side, TFS build has the capability to map or cloak file, but doesn't has the feature to exclude a piece of code within a file. An easy way from TFS side is to use TFS branch to develop your own feature.

WebBrowserControl + JS minification: Manipulate resources-properties with js code for minification puproses in Visual Studio's pre-build events

Background: Got a C# project which involves a block of javascript that gets programmatically injected in the web pages displayed by a webbrowser control. However, it is desirable to minify this block of javascript and have it embedded/written-into in a property of the resources-file. I know the minification of javascript is possible. I was just wondering if it's also possible to write the resulting string into a specific property of the resources files using pre-build events.
P.S.: Of course the resulting string can be written into a file which is in turn bound to a resource-property. However I would prefer to avoid something as such, fearing the performance penalty it would impose in runtime (the javascript block gets loaded quite often). If I'm mistaken about this feel free to correct me.
For anyone struggling with similar issues out there, this is the step-by-step approach I have opted for (having run out of alternative solutions) in the context of Visual Studio 2010. The method below handles the minification of javascript files in a uniform way while respect the version control system you might use (by avoiding to generate phantom changes in files hosted by it). Here are the steps:
Install Java and Google's Closure (for javascript minification).
Open the Resources of your project, go to file-resources and create a dummy file-property a-la foo.txt. This should create and include in your project the directory named Resources. You may delete the foo.txt file after this.
Right click the Resources directory and create a javascript file ending in Uniminified.js (for example MyInjectableJavascript.Unminified.js). Edit the properties of this file and make sure that the build action is set to "None". By the way, DO NOT reference this file in the resources.
Now go back to the Resource's file-properties and add a new file-property with the same base-name of the file created above only this time ending in min.js (for example MyInjectableJavascript.min.js).
Go to the .min.js file that was created under the resources directory and turn it into an Embedded Resource.
Now go the properties of your project -> build events and insert the following code:
Pre-Build events (in one line):
call "$(ProjectDir)JavascriptMinificationWithGoogleClosure.bat" "$(ProjectDir)Resources\MyInjectableJavascript.Unminified.js" "$(ProjectDir)Resources\MyInjectableJavascript.min.js"
Post-Build events (two lines):
del "$(ProjectDir)Resources\MyInjectableJavascript.min.js"
call echo. 2> "$(ProjectDir)Resources\MyInjectableJavascript.min.js"
What this does is that it minifies the javascript code before your project is built and after it is build it resets the minified file to a single newline.
Note: The reason we don't delete the minified file all together, is that visual studio will generate an error and will behave very weirdly if the minified file that is referenced by the resources is not found (in my case visual studio deleted Resources.Designer.cs completely out of the blue ... 5 times). By truncating the min.js file it to a single newline you can keep it around and even add it to your version control system without bothering with it ever again.
Under the directory of your project place a file named JavascriptMinificationWithGoogleClosure.bat with the following contents:
"%JAVA_HOME%jre6\bin\java" -jar "%CLOSURE_JS_HOME%compiler.jar" --js %1 --js_output_file %2
Finally, create two environment variables (Right click Computer -> Properties -> Enviroment Variables) named JAVA_HOME and CLOSURE_JS_HOME which point respectively to the directories you have installed the executables of Java and Closure. For example:
JAVA_HOME -> C:\Program Files\Java\
CLOSURE_JS_HOME -> C:\Program Files\Closure\
Note: Make sure to include the trailing slash at the end of each of the two paths.
You can now access the minified javascript that will be generated during the build from C# code, using:
Resources.MyInjectableJavascript_min
Hope this helps. Good luck.
Cheers,
Dominick

How do I configure paths to my javascript files in the Jasmine / Maven autogenerated ManualSpecRunner.html?

I think the question says most of it. I have an autogenerated ManualSpecRunner.html file as created by maven / jasmine plug-in and I've got it to put itself into the deployable .war by using:
<jasmineTargetDir>${basedir}/pathForMyWebapp</jasmineTargetDir>
However, all the links to js files within the ManualSpecRunner.html are hard coded file:/// references - this is a bit mental, I want them to just be the relative paths to the files that are also in the webapp i.e.
Currently it gives me this path:
file:///home/username/code/HEAD/pathForMyWebapp/js/yui.js
whereas I need it to have the far more simple
/pathForMyWebapp/js/yui.js
I have tried changing two other variables in the maven script, but neither seems to have the desired effect, neither of these configuration options do what I need, the second having seemingly no effect:
<jsSrcDir>/pathForMyWebapp</jsSrcDir>
nor
<jsTestSrcDir>/pathForMyWebapp</jsTestSrcDir>
I've looked through the documentation but think I must be missing something (also, more notes on various config params listed in https://github.com/searls/jasmine-maven-plugin/blob/master/src/main/java/com/github/searls/jasmine/AbstractJasmineMojo.java are meant to do would be helpful so I can work out if I'm doing it wrong or if it's not possible!)
Any suggestions?
[p.s. I've changed some of the path names as they've got sensitive info in them, so please ignore their oddness!]
I think I understand the source of your confusion. It looks like you're trying to direct the target of the jasmine-maven-plugin to a directory inside your project's packaged *.war file so that you can run your specs against the code after it's deployed to a server, is that correct?
Unfortunately, the plugin wasn't designed with that use in mind. The jasmineTargetDir directory is usually left at its default value of target/jasmine and wasn't intended to be bundled with your application (it's analogous to the target/surefire-reports generated by maven-surefire-plugin for Java unit tests). So the reason that the script tags in ManualSpecRunner.html point to invalid locations is because that file is generated in order to be run from the local filesystem in a browser from the workstation that's building the project (to facilitate TDD).
All of that to say, if I'm reading your intention right, I think it'd be a cool feature to build a third spec runner that could be deployed with the app and executed remotely. (Especially if the project's Jasmine specs are functional/integration as opposed to isolated unit tests.) Unfortunately that's not something the project does yet.
I'm afraid that for now, if you needed to bundle the jasmine tests and execute them on the deployed server, you would need to copy ManualSpecRunner.html and jasmine into your src/main/webapp, fix the script tag references, and then manually maintain it as files are added and removed.
Make sense?

Categories

Resources