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.
Related
I work with an SEO consultant for SEO optimizations and faster page loading. He said that too many individual JS is being called. This will delay the loading of the site. For this, it is the right alternative to make a single BUNDLE. i need to do it as 1 or 2 BUNDLE must OPTIMIZE according to which one gives better performance. my hierarchy and chucked js as follow after build ; I also searched about webpack but I could not adapt the codes I found, as follow the page of next js related to webpack. I added this and nothing changed.
module.exports = {
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
// Note: we provide webpack above so you should not `require` it
// Perform customizations to webpack config
config.plugins.push(new webpack.IgnorePlugin(/\/__tests__\//))
// Important: return the modified config
return config
},
}
I also use next js for server side rendering. Other picture shows my structure in the react project and i think i should refer config to index js. maybe. How i should forward to solve my problem ? If you need any other information, i will try to write it.
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
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!
I'm using grunt-browserify and running into two issues in particular. The task is up and running successfully with the following config options. The variable jsFilesToConcat represents all of the javascript files for a Backbone.js + Marionette.js application, the main application defintion, the front-end utility assets (e.g. Bootstrap plugins), and all JS associated with the project. Is this the wrong approach? The thought was to load the entire 250k JS application (and all it's dependencies) at one time.
I want to offer the disclaimer that this is new territory for me, so I think my intended use case is available with the options already available with the plugin, but I'm confused by two errors:
1) Backbone not defined - which means that the script is in fact loading, however, when I inspect the call stack in Chrome Dev Tools it shows only the anonymous self-invoking function. So I'm not clear on how to pass the Backbone object to Marionette in order for it to be extended at load time.
2) require is not defined - error on the line where I'm declaring var SampleApp = require('SampleApp'). Do I need to do something special within my grunt config, or node.js server.js config to expose the require function?
3) Is the javascript executing asynchronously within itself, is this part of the browserify intended behavior that I'm not properly handling? I think since I'm wrapping alot of JS utilities in a global wrapper to protect namespacing, that's the reason some functions are not available, but I'm not clear on why that would affect require.
// uses grunt-browserify task
browserify: {
developmentJs: {
options: {
debug: true,
alias: ["./js/app.dev.js:SampleApp"],
},
src: [
'<%= pkg.jsFilesToConcat %>'
],
dest: 'public-dev/js/app.dev.js'
}
}
and then in the index.html of my single-page Marionette app, I have.
(function ($) {
$(document).ready( function() {
var sampleApp = require('SampleApp');
console.log( SampleApp );
});
})(jQuery);
Well for starters, the src attribute in your grunt file doesn't need to reference all of the files in your application. It only needs an entry point. So normally I have something similar to your anonymous self executing function in an index.js file, and set my src configuration option to ["./index.js"]. When browserify looks at that file, it will check for calls to require and grab all of the required dependencies.
That said, browserify will generate a file with an internal definition of require. The require function is not globally available on the page, nor are the dependencies that you include with require. You can use them in your application, but that doesn't make them available in the page. So if you are getting a Backbone is not defined error, the first thing I would check is that you have installed backbone via npm (npm install backbone --save).
Once everything is set up you should just have to include your compiled script on the page, and let your anonymous self executing function (which should now be in a file that grunt-browserify is processing) do the work to kick off your application.
I'm using Yeoman 1.0 and the latest version of the Backbone generator and everything I've written is working in development, however when I $ grunt build the resulting /dist is throwing the error:
Uncaught ReferenceError: Backbone is not defined
Unfortunately, since the js has been minified, trying to debug is almost pointless. Is there a way to "build" without the minification? I've tried playing around with settings in the gruntfile but can't seem to find the right options for the right task.
Can you share your GruntFile.js to check the configurations?
By the way, you can omit the minification, don't use uglify or whatever task you have been running so, give it a try to grunt-contrib-copy task which copies the files to designated folder (prod/dist).
https://github.com/gruntjs/grunt-contrib-copy
// Configuration goes here
grunt.initConfig({
// Configure the copy task to move files from the development to production folders
copy: {
target: {
files: {
'prod/': ['dev/**']
}
}
},
});