Integrate Babel into Angular 1.5 - angularjs

I have built an angular website working perfectly fine in chrome, but it is failing in IE because of ES6
I am running angular using cdn with a node server which is only used for serving the webpage, no code is there other than listening to port.
I want to add babel into that, but all the examples I am finding are for server code or using gulp or webpack. Is there any way to directly integrate babel for my purpose or I definitely need to have webpack\gulp configured.
Included the directory structure of the code, all the files are getting linked in index.html

Since babel changes your javascript I don't think you can include it in your html page you need to have it in a grunt or such pipeline so the javascript is transformed and then the transformed javascript is served:
gulp.task('build', [], function () {
return gulp.src('./app/index.html')
.pipe(preprocess({context: production_config.context}))
.pipe(babel({ presets: ['env'] }))
.pipe(gulp.dest('./build');
});
Then serve "build" instead of "app"
Maybe there's a more dynamic way

Related

angularjs-route not loading with angular --prod flag (angular-cli)

Context: I'm migrating from ngJs to ng10, the application runs normally when I not use the --prod flag
The thing is: when i use --prod flag the routes doesn't load and i am super clueless why not.
The only difference I see printing the "next" attribute on the $routeChangeStart is that the "next" object on --prod mode doesnt have an attribute called "locals"
2nd. weird thing: the $routeChangeStart is triggered when i change the URL on the URL bar as it should be, cus the $routeChangeStart is printed every time i change the URL
3rd. weird thing: for testing purposes i change templateUrl in the config for a template:'<div>Arcade PvP silly text</div>' and it doesnt load either, and as far i see, the controller of any view never triggers.
Pls help.
Angular-CLI 10.0.5
Angular 1.7.6 bootstraped over Angular 10.0.6
Okay, I manage to understand more deeply the reasons of this behavior and manage to make a workaround, gonna documentate it here:
This is an application made in AngularJS (1.7.x) bootstrapped over Angular 10.0.5
Deploying the application with ng serve --configuration=dev makes it work as expected after the normal long process of configure the different index.ts and convert everything from *.js to *.ts
The reason of the issue is located in the angular.json:
{
"projects":{
[project_name]:{
"architect":{
"build":{
"configurations":{
"production":{
...
"optimization":true <------- THIS
}
...
}}}}}}
The optimization flag effectively makes the bundle very lightweight and ng build --prod compiles normally. But as I mention in the question, the problem occurs at runtime: the routes "load" but the HTML never renders for any route configured, therefore ANY of the controllers either runs.
In deep investigation, the optimization flag tells the angular-cli webpack to run the minification over the JS, and by past experience, AngularJS seems to be tricky to receive the minifications/uglify processing all due to the mangle process, my problem is one of the reasons why.
Angular-CLI's Webpack runs TerserPlugin to make the minification and I need to configurate it to avoid using mangle, Angular now allows to use a custom webpack configuration file to add rules, this is achieved like this:
create a new file in the project base folder, let's say named custom-webpack.config.js
Reference this file in the angular.json build:
{
"projects":{
[project_name]:{
"architect":{
"build":{
"builder":"#angular-builders/custom-webpack:browser",
"options":{
"customWebpackConfig": {
"path": "./custom-webpack.config.js"
},
...
}
}}}}}}
In the file, let's do this:
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: true,
terserOptions: {
mangle: false,
ie8:false,
safari10:false
}
}),
],
}
}
And voila! The minification occurs, but not the mangle, the application will reduce it's bundle size as expected (mostly) and the angular-route will work normally.

Add PolyFill.js in AngularJS application

WE are embedding PowerBi JavaScript SDK in angularJs App. PowerBI Javascript SDK makes use of the Promise.
IE 11 do not support Promises. Lot of posts directed me to make use of ployfill.js for the same.
My Question is how do I Inject PolyFill.js file in angularjs app?
If you are using Webpack for bundling, add the polyfill.js before your main entry script.
module.exports = {
entry: ['polyfill.js', './main.js']
};
If you are using script tags in html, make sure to include the script before any other library that uses promises (PowerBI):
<script src="path/to/polyfill.js"></script>
A more modular approach is to use core-js and include only the polyfill you need:
module.exports = {
entry: ['core-js/fn/promise', './main.js']
};

Setting up React router: how to use {import} in the browser?

I am following the React-router docs, but I have encountered an obstacle that is not really related to the router itself: Babel transpiles the {import} as require, which would be used by Express or Node.js on the server, but from what I understand from the docs, it is actually intended for client-side rendering.
Of course, the JSX file with the router transpiled using Babel and included into a HTML browser page does not work, since require is only used by express/node server-side.
May I ask how is it actually supposed to work in the browser?
Thank you
Babel's transpile of import produces code relying on CommonJS require, you're correct.
You're also correct that node offers a natire require implementation, whereas browsers do not.
There are tools - such as webpack, browserify, and requirejs (among others,) which each do at least two things:
to package up source into a single bundle
to expose that source in a way that satisfies require to match node, allowing you to use the same code at either side.
To that end, what you need to do is to pair babel with one of the packaging tools.
Webpack is more powerful; browserify is easier to use.
Here's a tiny gulpfile where I've automated the process. The relevant source clip is this:
gulp.task('browserify', ['babel'], function() {
var browserifyConfig = {},
bpack = browserify(browserifyConfig, { 'debug' : !production });
return bpack
.require('./dist/pbar.es5.js', { 'expose' : 'pbar' })
.bundle()
.on('error', errorHandler)
.pipe(source('pbar.es5.js'))
.pipe(gulp.dest('./dist'));
});
In order for commonjs like require statement to work in a browser environment. You will need to look into a bundling solution like:
https://webpack.github.io/
http://browserify.org/
A bundler will statically parse your commonjs files and their dependencies to create a bundle which can be used in the browser.
Internet is full of great examples on how they work.
Browserify is easier to get started than Webpack, however I would suggest you learn Webpack over Browserify. Webpack provides you much much more than just loading JS files with its extensive loaders, for example you can do something like:
const imgSrc = require('images/test.svg')
magical right?

How to keep Grunt dom_munger from stripping your CDN dependencies?

I have an object, Plaid, that is provided by a drop-in module from Plaid, called Plaid Link. Locally, the code works perfectly in my AngularJS front-end.
The module is loaded via my AngularJS app's index.html file, right next to all of the other script tags loaded for my application.
Index.html
<script src="https://cdn.plaid.com/link/stable/link-initialize.js"></script>
Here is the code where Plaid is called: (from an AngularJS controller)
$scope.addAccount = function(bankChosen) {
$log.debug("Plaid object: ", Plaid);
var linkHandler = Plaid.create({ // the troublesome line
env: 'tartan',
clientName: 'Example Project',
key: 'test_key',
product: 'connect',
onSuccess: function(public_token) {
Restangular.one('plaid').customPOST(
{
public_token: public_token,
user_id: $scope.currentUser.id,
institution_code: bankChosen
},
'addAccount'
);
},
onExit: function() {
$state.go('dashboard.successState');
},
});
linkHandler.open(bankChosen);
};
However, when I push to the production environment, currently hosted on Heroku, it gives the javascript error ReferenceError: Plaid is not defined when it tries to load. It is breaking error when deployed to production.
What could be causing this module to be unavailable during production?
The script that loads the CDN could be getting stripped away by a standard grunt task that does that sort of thing? Or maybe I am supposed to be loading the module from the CDN in some other way in a production-environment setting? I really don't know...
Update: I found one thing that might be stripping the loaded module
From the Grunt dom-munger docs
Use this task to read and transform your HTML documents. Typical use cases include:
Read the references from your script or link tags and pass those to
concat,uglify, etc automatically.
2. Update HTML to remove script
references or anything that is not intended for your production
builds.
Add, update, or remove any DOM elements for any reason.
dom_munger is part of my application's build process, which happens when it is deployed (!). Grunt is the likely culprit here.
Does anybody know how to load the script tag above, with dom_munger as still part of my app's grunt build step?
The problem was that during the build step Grunt strips away the script tags in my application. So I had to append the tag back on to my body tag using dom_munger's update --> options --> append option.
...only then could I get the CDN script to be linked to properly after the app was built using grunt build.
The line looks like this in my Gruntfile.
--> The key added line is this one
{selector:'body',html:'<script src="https://cdn.plaid.com/link/stable/link-initialize.js"></script>'},
dom_munger:{
[.....]
update: {
options: {
append: [
{selector:'body',html:'<script src="https://cdn.plaid.com/link/stable/link-initialize.js"></script>'},
]
},
src:'index.html',
dest: 'dist/index.html'
}
Quite the mysterious error for me. I hope this helps somebody else out at some point!

Webpack with angular 1.4 ES 5

I am working on an application which is build with angular 1.4 and ES5. It is using gulp to minify files. I wanted to use Webpack to leverage features like code-splitting and bundling everything in JavaScript files.
Is it even possible to use webpack with ES5 code as I see almost all blogs about WebPack deal with ES6. Any pointers will be greatly appreciated. Many thanks.
This is how my team did it. Essentially you want to create "entry point files" that perform requires for all your files, since this is how webpack works (it follows the dependency tree). Then point webpack at these "entry point files".
The example at the link above uses TypeScript, but you can easily use ES5 like this:
# ./entry-points/feature1.js
importAll = function(r) {
r.keys().forEach(r);
};
importAll(require.context('./app/feature1', true, /module\.js$/));
importAll(require.context('./app/feature1', true, /(^(?!.*(spec|module)\.js).*\.js)$/));
You can grab a polyfill for Object.keys here, and Array.forEach` here.
Then point to this file from your webpack config like this:
entry: {
'feature1': './entry-points/feature1.js'
}

Resources