IE 11 'ng' not defined error - javascript

I've inherited an ASP.Net / MVC / Angular project coded by an outside consulting company. Angular is completely foreign to me, 90% of my coding has been in C# but I've managed to fumble my way through a number of small side tasks in this project.
All was well and good until one of our external users attempted to use the app in IE 11. There are 130+ errors that show in the console just from bringing up the home page. I've done quite a bit of searching, found all kinds of things related to polyfills and es5/es6 shims etc., but after attempting those changes, the only progress I've been able to make is clearing some of the errors related to unsupported arrow functions and parameter default values. As those disappear, I'm left with a slew of
SCRIPT5009: 'ng' is undefined
errors in the developer tools console. In almost all those cases, the error relates to trying to reference ng.core as in the following example
(function (app) {
app.Routes = ng.core.
Injectable()
.Class({
constructor: function () {...
I'm frankly struggling to even understand whether this is an AngularJS or Angular2 project as both are referenced (i.e., the current code makes use of bundling and creates an angular bundle referencing angular.js, angular-ui-router.js etc., as well as an angular2 bundle that references the angular2 files in the node_modules directory) Interestingly enough, if I remove the angularjs bundle and the reference to it in the #Scripts.Render() of the shared layout.cshtml file, I get the same number of errors which leads me to believe the app was initially started as an AngularJS one but went Angular2 and wasn't cleaned-up. That being said, there's no project-specific use of TS, only the standard TS files from the npm install are there.
The "'ng' undefined" error feels to me like there's some DI not happening properly but I can't make heads or tails of this.
The mandate to get this working in IE 11 "ASAP" has me ripping out what little hair I have left. Any pointers on where to even start looking or whether it's obvious from the description that there are architectural choices that have been made which dictate starting over in some sense, I'd really appreciate it.

Related

Intellisense of VS Code is poor

Hi I am using VS Code for quite some while and it's Suggestions of, for Example Class properties or methods is kinda poor. I wanted to check out if this is suppose to be like that or if that is an Issue only for me. I am using it mostly for frontend development with JS/TS or JS Frameworks and often when I install npm packages and import them Intellisense is not showing me their properties which is very lame because this should be in my opinion the number one support it should provide. Many other features of it are great so I would like to keep using it but if that is the supposed behaviour I think I have to switch to a new IDE.
For Example I am using Three JS right now which has in my opinion a very solid Object Oriented Style where it is very essential to know what properties and methods a class has, though Intellisense kind of does not know unless I have typed it once manually, e.g:
I have imported Three JS as follows at the top of the file:
import * as THREE from '../node_modules/three/src/Three.js';
and I am looking for TextureLoader which suppose to be a method of the THREE class which it is when I type it manually, everything works fine though VS Code does not seem to recognize it which is very poor behaviour for an IDE. The Suggestions you see in the Image are the only ones it suggests me. (There is textureLoader typed with a small t at the beginning, but that is because I have used a variable with that name) so VS Code only suggests me things that I have typed already. And
I have checked all the related Posts Stackoverflow is showing me but nothing is related to this topic and All the bug fixes only are related when you have a literal bug in VSCode, but I am not even sure this is an actual bug. Also many people love VSCode and claim it is the best free IDE and I am wondering why if it even can't provide the most fundamental things. I remember Eclipse for Java where it showed you every attribute and method of a class.
I thought it could be a problem of JS since it has no types but I think I remember that Webstorm provided the suggestions correct for JS
So my question is, is that expected? Should the Intellisense mechanism not detect Methods and variables defined in a imported class and just provide you with a list of all of them?
So I have found out that it is not just a problem with my VS Code. VS Code just cannot know what types or methods are available for a class or object. I thought it might have some parsing capabilities running through an class and picking up it's methods to display it in the suggestion/code completion box, but I guess this is to overkill.
So Type completion is available if you use Typescript. For me event though I am using Typescript together with Three.js I still haven't had any useful suggestions in my VSC. So I have found out that the IDE relies on the type definition files "[name].d.ts" where types for Typescript are defined. These should be provided by the author of libraries/ packages you use.
If their are not there is a repo where you can check if such types are available on the npm registry found under #types so for me I had to manually run:
npm install --save-dev #types/three
which installed me a new directory under #types/three with a d.ts for every three JS Module.
when you do then an import like:
import * as THREE from 'three';
typescript knows to also look for declaration files d.ts under "node_modules/#types/three" I guess
So to summarize:
No code completion because of js dynamic type system like [python, ruby]
You can have code completion using typescript since it has static types like [java, #c]
There must a [name].d.ts file provided telling the ide how a class is defined.
For build-in things like the 'dom' and 'window' it is provided by default when installing typescript
correct me if I'm wrong

Reduce Javascript size in Rails app and improve performance score. Maybe issue with ESBuild?

Not specifically a Rails question, but a question within a Rails app.
In my app I am using the jsbundling-rails gem configured with esbuild.
This gem adds a build line to my package.json file. It works and compiles all my JS and runs fine. However, I found that the generated file is rather large so I started looking at ways to optimise it.
My esbuild statement at this point looks like:
"build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds"
Firstly I thought I could try making my imports conditional. Eg, only import them when they are actually required. I asked another question on how to do that here.
I learned quite a lot digging into that, but at the end of the day it's made no difference to the output of my JS weirdly.
Chrome currently says that my main JS file has 91% code unused. It looks like all the imports are still being compiled together, whether they are statically or dynamically imported. Why can this be?
I then looked further into esbuild, I spotted the --splitting flag. It sounded reasonably correct so I updated my build script to be:
"build": "esbuild app/javascript/*.* --bundle --splitting --format=esm --sourcemap --outdir=app/assets/builds"
This caused a huge amount of outputted JS files (I think they are referred to as "chunks".
I ran my app, and the JS failed to load. The console stated that
Uncaught SyntaxError: Cannot use import statement outside a module
I wasn't 100% sure why was the case but I just guessed that I needed to add type: "module" to my javascript_include_tag in my Rails application layout view.
This made the JS load (which is good :-) )
BUT... The percentage of unused JS code is still 84% of my application.js
So..... my questions are as follows:
Are my dynamic importing of modules working?
Why does static or dynamic importing appear to make no difference?
How can I effectively reduce the size of the output code and reduce the unused percentage of JS on my home page?
This all started because I ran Google's Lighthouse test on my site and it reported my Structure and Accessibility to be practically perfect but performance was < 40. I am aiming to solve this.
I look forward to hearing from you with ideas on how I can try to fix this and improve my Lighthouse Performance score.
Are my dynamic importing of modules working? Why does static or
The paradigm you want is called Propshaft. Try looking at the SProckets -> Propshaft
https://github.com/rails/propshaft/blob/main/UPGRADING.md
Why dynamic importing appear to make no difference?
Because even though ESBuild allows for ES Module syntax (import statements), it still bundles everything into "1" big file. (1 big file for each javascript_include_tag you have, of course).
How can I effectively reduce the size of the output code and reduce the unused percentage of JS on my home page?
The sprockets paradigm was built for the HTTP1 web when keeping connections open and progressive download wasn't realistic. HTTP2 changed all that and now it's more efficient to do code splitting as you want to do. But the Rails world is still very behind and most apps still use Sprockets and try to optimize/minify was much as possible.
I'd recommend you take this course of action:
(1) Try the old-style way first. Remove anything unnecessary, split your app into different sections and load different manifest files for different sections. Use minification. See how far that gets you.
(2) Start experimenting with the new Propshaft for a few weeks until you fully understand it. If you feel it is solid, migrate to that.

Phantomjs "Module X not available!" when trying to render a AngularJS webpage

I spent a couple hours trying to find an issue that gave me any clues to solve my issues, but couldn't find anything relevant.
I am working on some SEO for a website (I'm no SEO specialist, am currently taking some courses and reading lots of articles on it), and one thing that I found out was the "Fetch and Render" as Google on Google Search Console.
However the website, which has loads of AngularJS (1.5.x) components, was just rendered the header, which I implied meant that the js didn't load properly and the Angular components couldn't been initialized.
Since, I then found out (can't confirm) that Google Search Console used PhantomJS to render the pages, so I decided to give it a try on my local environment.
We use Webpack to bundle all js files together, and it works as expected both on local and production environments, however it appears that PhantomJS has some problems when trying to render the bundled files.
Every module a page tries to bootstrap throws an error when running PhantomJS:
[$injector:nomod] Module '(moduleName)' is not available! You either
misspelled the module name or forgot to load it. If registering a
module ensure that you specify the dependencies as the second
argument.
But as I said, all browsers correctly loads all modules, apparently there is no error on the modules declaration, all imports are in order, everything should work as expected. Except it doesn't.
If you think an excerpt of the script could bring some light to the matter, I'll include when required, as the code is a bit sensitive, there is a lot of it (couldn't think about a bit that could be helpful), and since it works correctly almost everywhere it doesn't seem to me to be the issue, but I could definitely be wrong.
I'm sorry, I hate to post questions without code, but I'm a bit overwhelmed by this one.
Has anyone faced a similar issue?
Any help would be much appreciated.
Kind regards.

Webpack: How to have runtime (not buildtime) feature flags with same module names?

I'm hoping to find a way to have alternate versions of the same file available from the same webpack run and same output url, with a different chunk/bundle being dynamically loaded after a service call determines which group a user falls into.
Background:
Putting alpha/beta changes into production in the same build and output url lets us develop and test features with external users, but sticking conditionals everywhere (and later removing them) that needs can change is error-prone and generates more complicated code.
My thought was to have alternate versions of the same files in specially named subdirs - e.g. foo/file.js and foo/flagged--special/file.js - and then when something does import blah from 'foo/file' it will automatically get the correct version for that user.
This avoids conditionals in the code itself, and making a feature available for all is just overwriting the base file with the alternate. It also doesn't involve huge changes to our existing codebase and webpack config, nor does it involve a lot of funky and product-specific syntax to replace all our import statements. (After I put the idea together, someone pointed me to Mendel, where Yahoo did much the same thing, albeit as their own framework that is not friendly with webpack, so I'm assuming the base idea isn't crazy)
Problems:
I see examples of feature-flagging a build to one version or the other, but not any examples of having both in one build.
I could write a custom loader or plugin to wrap each file load to do this (I think - not sure about how the output of webpack works in terms of runtime evaluation), but that would result in adding both versions to the bundle.
I'm thinking I can create a base output chunk that does little more than fetch the user's options, then dynamically load one of two alternate chunks that have the different versions...but I have no idea if that will work, or if I'm fighting a losing war vs the webpack internals.
Can this work?
Has someone already done this?
Is there a better way?
Thanks in advance!

How to organize Vue-JS : Non Javascript way?

How to organize Vue-JS project [files and directory]: Non Javascript way?
Coming from a non-javascript background, I found Vue.js very intuitive and easy to use. My earlier experience in Javascript is with JQuery and vanilla javascript on the browser.
I created an application using Vue , Vue-components and vue router. Everything works fine.
My problem is, I have ended up writing a lot of code in a single index.html file of my project. This file contains over 10 templates that I have created and attached to different component in my app. I want to know that is there a non-javascript way to organize these templates in seperate files.
I see that there are options using webpack and browserify to modularize the project. But coming from non javascript background, I don't find them intuitive. I don't want to go node - npm way because that has its own learning curve and moreover it downloads a dozen of files and dependencies in my project which I don't understand. I am old school and more comfortable downloading the files and including them in the webpages.
So probably, you understand where I am going to. I need a solution where I could put my templates as separate files and read those files in the different components.
What I have tried :
Declaring the templates inside my components. But writing all that html inside the component is not that clean. It also, makes my JS file too huge. I am better in putting all data in the index.html instead.
Storing template as smaller chunk "homepage.html","about.html" and in my components, using $.get / $.load to read different components in ready function of the component. This works but I still have to fire an additional ajax call for each component which is not efficient.
Please refrain from suggesting the obvious node-npm [webpack and browserify] way. I know thats what is supported by Vue but this needs a learning curve and complete setup. Answer to this question would actually help other developers who hesitate going the node-npm way.
Please shout back if you need more clarifications to the question.
The options you've mentioned are your only real ones... the HTML of the template needs to be available when it's needed, so you either have to have it within your html file off the bat, or load it using AJAX or an in-browser loader like RequireJS (and this extension that allows it to load HTML https://github.com/requirejs/text).
In-file templates make sense for very small projects. As your project grows, you'll need to start using the tools that are built for this. NPM rocks and every JS package that you'll ever need can be included in your project in seconds.
I highly encourage you to try the Vue CLI
It does use node, npm, webpack and downloads dozens of files. Which you've you've explicitly asked for not to use, so let me clarify:
The Vue CLI takes care of the complexity and configures webpack for you.
You don't even have to know it's using webpack.
It's very developer friendly (it even has a built-in gui) and lowers the barrier to entry compared configuring a webpack config.
I hope you'll also find it "intuitive and easy to use".

Categories