I'm working on a large project, where minification of java and css was used before with Web Essentials, but no bundling has been yet made.
I want to move away from WebEssentials now and use something else.
I'v started with minification and bundling just a part of app .js files using Gulp, but when loading the project got an error from one of the pages:
Error: $injector:unpr Unknown Provider caused by other .min.js files,
which all worked fine before I've added mine.
All files are added to the path exactly in the same order, as they should be loaded on the page. Also replaced just those files which have been added to the bundle.
gulp code for minification:
gulp.task("min:appjs", function ()
{
return gulp.src(["!gulpfile.js", "!app/" + paths.minJs, paths.appjs], { base: "." })
.pipe(sourcemaps.init())
.pipe(concat(paths.concatJsAppDest), { newLine: ';' })
.pipe(ngmin())
.pipe(annotate())
.pipe(uglify())
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('.'));
});
What I can't wrap my mind about: how my minified file causes others minified files to crush when they've worked before. Plus one page of the project loads without any errors and others don't work.
Any ideas where I should check?
Ok, so the way I had to handle this was checking which file caused the error.
It appeared so one of the .js.min files from further if statements in the code was referring to the file in the bundle and couldn't find the reference.
Taking that file out of the bundle and keeping it separately solved the problem.
If there are any ideas how to include it in the bundle and still keep the reference, I would be glad to try it out.
Related
I'm using Grunt to build the Durandal starter kit pro package.
It all works fine, except for one tiny detail. I would like to exclude one file (app-config below) from the optimizer and keep it as a non minified file when my build is done.
Based on other SO thread suggestions, I'm currently excluding it using empty:, which removes it from the optimized file as expected. However, when I open the built project I get an error in the console:
Uncaught Error: main missing app-config
options: {
name: '../lib/require/almond-custom',
baseUrl: requireConfig.baseUrl,
mainPath: 'app/main',
paths: mixIn({ }, requireConfig.paths, {
'almond': 'lib/require/almond-custom',
'app-config': 'empty:'
}),
optimize: 'none',
out: 'build/app/main.js',
preserveLicenseComments: false
}
Is almond the problem? I tried switching it to the full requirejs using include: ['path/to/require'], without success.
If you want to reproduce it locally you can either download the starter kit from the above link, or use a slightly configurated version which is closer to my example. Just run an npm install in the folder and you're all set.
I have downloaded you source code and do the following steps.
Extract zip file, open cmd and change the directory to this folder.
Run npm install to install all the dependencies.
Run grunt to start to build the project.
And when I open http://localhost:8999/ and saw the alert 1 which is alert(appConfig.foo); in your main.js.
After clicked Ok to hide the alert, the web page works fines. Any more input for you ?
So I am not sure how you are facing with this issue.
From the reference of the durandal issues found in this particular link
grunt-durandal
The main module controls the implementation of the durandal services
The link can be found in main.js
Here you can see the system.debug(true).You can remove it as written in the post here document.
The function as quoted in the article Overrides request execution timeout making it effectively infinite.
Also while using uglify in grunt the debug is set to false as per the documentation.
As per the documentation you need to set the system.debug(false)
Hope this might help a bit.
try:
....
paths: mixIn({ }, requireConfig.paths, {
'almond': ['lib/require/almond-custom', '!lib/require/almond-custom/app-config.js']
}),
....
just note the second path of app-config.js is correct. I think you should find your way, the above is a hint, if not a direct solution.
To bundle and minify the files of my application I'm using .NET Bundling and Minification feature (and it's complicated to use any other tool, so I would like to find a solution for this).
As a remark and just in case it could help, I'm trying to minify angular files, files compiled from typescript and regular javascript files.
The problem is that when I execute the application I got some javascript exceptions related mostly to angular. I think it's not useful but maybe it could help, so this is the main exception I get:
Error: [$injector:unpr] Unknown provider: tProvider <- t <- highChartSeriesMappingService
http://errors.angularjs.org/1.5.5/$injector/unpr?p0=tProvider%20%3C-%20t%20%3C-%20highChartSeriesMappingService
[Rest of the exception trace][...]
If I just bundle them and no minify my files, by setting this instruction myScriptBundle.Transforms.Clear(), it works fine. Obviously, this action also avoids the mangling of variables, classes...names.
In order to be sure of what was happening, I used grunt and its plugin grunt-contrib-uglify to bundle and minify. At the beginning I had the same problem as before because of the basic configuration I used for the task:
uglify: {
options: {
preserveComments: false
},
myScript: {
files: {
'myScript.min.js': conf.myScript
}
}
}
Where conf is a reference to a json file with the url of the files to minify. But when I set the mangle property to false (here you have more info about it):
uglify: {
options: {
preserveComments: false,
mangle: false
},
myScript: {
files: {
'myScript.min.js': conf.myScript
}
}
}
It works fine too. It leads me to think that is the mangling of some classes names the root of the problem.
As you can see, I reached a solution using grunt but I would like to find a way to avoid mangling with .NET. Any idea?
After read the post of #AbdelrhmanMohamed and check again my project's files I realized that it was a problem related to angular and its array sytntax; some files lacked the dependencies injection through the array strings, so when those files where minimizied and the functions' names where mangled caused my exception in execution time.
To sum up, .NET bndling and minification process seems to work fine. If you work with angular you just have to be sure that all your classes which depend of other modules have the array string with those dependencies defined.
I have been researching the ability to minify an ExtJS application without Sencha and the closest I have come to is this link:
Is there a way to minify an ExtJS application without Sencha CMD?
However, I am not sure how to execute the file in one of the later comments. I am using the minify-maven-plugin with com.samaxes.maven and the CLOSURE engine. I was able to generate the minified js file of the entire project but I get errors when I try to load the web page.
I was able to verify the web page was calling the correct file. I received the error "TypeError: q is undefined"...not helpful at all. Without the minified file, the web application runs perfectly. So, the generated minified file must have something wrong with it.
The suggestion at the bottom of the link above indicates the sequence of files that I should include but I have no idea how to actually implement this. Also, there are probably over a hundred javascript files that need to be minified so I would rather not have to type each file in the jsb file.
Are there any suggestions on how to minify my entire project at build time with maven?
I'm using Grunt to build the project, but it doesn't really matter as all you need is to combine files, so maven should be more than capable.
I wanted my dev version to still rely on Extjs dynamic class loader so I don't have to rebuild the project whenever I modify one file, and only production version to be minified into a single file. There were a few pitfalls before I got it working, here is what I ended up with. Also this is for ExtJS6, but it probably still should be the same.
It is all controlled by backend variable dev, which when set to false will use minified sources.
index.html (I'm using some meta templating language as example)
<html>
<head>
{{if dev}}
<script src="/ext/ext-all-debug.js"></script>
{{else}}
<script src="/ext/ext-all.js"></script>
{{/if}}
<script>
var dev = {{dev}};
Ext.Loader.setConfig({enabled: dev});
</script>
{{if dev}}
<script src="/app.min.js"></script>
{{else}}
<script src="/app.js"></script>
{{/if}}
</head>
<body></body>
<html>
app files, requires directive doesn't work well when the dynamic loader is disabled, so I had to add conditions like this everywhere:
Ext.define('MyApp.view.Panel', {
extend: 'MyApp.view.GenericPanel',
requires: dev ? [
'MyApp.view.AnotherView',
] : [],
...
});
Gruntfile.js (if you need only concatenation replace uglify with concat everywhere)
module.exports = function(grunt) {
grunt.initConfig({
pkg : grunt.file.readJSON('package.json'),
uglify : {
build: {
files: {
'../app.min.js': ['../app/view/GenericPanel.js', '../app/**/*.js', '../app.js'],
}
}
},
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('default', [ 'uglify' ]);
};
grunt's project.json:
{
"name": "My App",
"version": "1.0.0",
"devDependencies": {
"grunt": "~0.4.5",
"grunt-contrib-concat": "^1.0.1",
"grunt-contrib-uglify": "^1.0.1"
}
}
The order of files matter, by default grunt will use alphabetic order. If you extend some class, the parent class has to be included higher. app.js should be at the end. Other than that it is working well in a single mixed file, so I didn't have to customize the file order further. Grunt has pretty powerful path patterns, so if you need to make sure some file is included first you just list it before other path patterns and it will be smart enough to not include it twice.
I recommend you start with simple concatenation without minification, and only if that works try minifying it. When minifying you might need to be careful with global functions and variables as they can be renamed if minifier is too aggressive. Grunt's minifier almost worked for me with the default settings, I just had to made couple small changes to my code (related to global functions).
While I am not sure why you would want this, the main thing you need is the so-called dependency tree - which tells you the order in which to include the source files.
Then you can put all the files (ExtJS source, libraries if applicable and also your own views) into one big file, in the correct order. This file should then work exactly as the 500 distinct files. (It did for me.)
That done, you can search for a working minifier. Not every minifier can minify ExtJS code, and I don't remember my last results before we finally decided to switch to Sencha Cmd, but I think Microsoft Javascript Minifier was one that worked for us.
Apart from that, minified JavaScript is really legible. You should provide the source of the error, with 200 characters before and 200 characters after the error, and I guess someone here can tell what's going on there.
There are two files in my project:
index.js where the following code is
define([ 'exports', 'hbs!./general'], function (exports, generalTemplate) {
});
general.handlebars which is correctly taken by require.js and the hbs! plug-in.
I'm basically using Require.js with Handlebars.js and the https://github.com/SlexAxton/require-handlebars-plugin for automating the creation of templates from files.
It works correctly, but Webstorm 8 (and also 7 before it) doesn't understand the file is correct so it always complains with: Cannot resolve file 'general'. It is the same with every file using that plugin prefix.
I coudln't find where (if it exists) to turn that notification off, because it underlines the entire file, and its parent directories as having errors.
How can I remove this error of being reported?
This notification can't be turned off unfortunately - annotator-level inspections can't be suppressed.
The issue with relative paths resolving when loading plugins for non-js extensions is tracked as WEB-1167, please vote
I change the code, extend some functionality and add new unittest for that. Now, when I run my unit tests with karma (test framework - jasmine), it throw me an error
'There is no timestamp for /libs/angular-bootstrap/ui-bootstrap-tpls.js!'
Uncaught Error: Script error for: angular-bootstrap
http://requirejs.org/docs/errors.html#scripterror
at http://localhost:9876/base/node_modules/karma-requirejs/lib/require.js?1379984163000:138
What I'm doing wrong?
It was my mistake completely. when using karma-requirejs you have main-test.js file where configure how to require.js get the files. I add reference to angular-bootstrap with mistake, that's why require.js couldn't find this file and throwing this mistake. So in my case this error means wrong file name provided.
It can be because it cannot access your source file. You should configure karma to serve scripts where require will look for them.
For example have the config in the karma conf
files:[{pattern: 'node_modules/**/*.js', included:false}]
The question is old, the OP already solved his problem by now, but I'll add my two cents:
From the error message (end of the first error line) we can conclude that you were including a paths (or deps) file in main-test.js with the .js extension.
In RequireJS, you need to call the file names without the extension, so your paths (or deps) would look more or less like this:
paths: {
'ui-bootstrap': 'libs/angular-bootstrap/ui-bootstrap-tpls' // <- without the extension
}