I am using RequireJS optimizer in a gulp recipe to compile and concatenate my Modules but redundant 3rd party library files like bower.json and *.nuspec files are being copied to my output directory.
I have successfully managed to exclude full directories using fileExclusionRegExp in the requirejs.optimize options object with the following expression:
/^\.|^styles$|^templates$|^tests$|^webdriver$/
However, I cannot figure out how to exclude everything but .js file extensions. I could use the following:
/^\.|.json$|.nuspec$|^styles$|^templates$|^tests$|^webdriver$/
to exclude specific extensions but if a new type were to appear later, I would have to notice and then change the regex. Also, the regex would probably become unruly and hard to maintain with time. I have tried to use the following expressions:
/^\.|!js$|^styles$|^templates$|^tests$|^webdriver$/
/^\.|!.js$|^styles$|^templates$|^tests$|^webdriver$/
/^\.|^.js$|^styles$|^templates$|^tests$|^webdriver$/
/^\.|[^.js$]|^styles$|^templates$|^tests$|^webdriver$/
/^\.|[^.js]$|^styles$|^templates$|^tests$|^webdriver$/
The results ranged from doing nothing (the first 3, to breaking the build, last 2) any help anyone could provide would be appreciated.
Thanks
Try this regex:
^\.|\.(json|nuspec)$|^(styles|templates|tests|webdriver)$
Related
I have a specific folder which contains 5 JavaScript files and I would like UglifyJS to ignore them all (i.e. not minify). I am aware of the exclude option, but not sure how to use it exactly in relation to the absolute path of the folder within the solution and how the format of the exclude string should be.
Thank you in advance.
Try using the pattern option
--pattern '**/*.js,!**/folder/*.js'
DISCLAIMER: Please, do not start "singlequotes masterrace", "tabs are over spaces"-related shitstorms. Thanks :)
I wonder how to make this possible:
Project is using 4 spaces and doublequotes
I am using 2 spaces and singlequotes
Import project
Every opened file translate to 2 spaces and singlequotes
Save project as 4-spaces and doublequotes based
Commit it as 4-spaces and doublequotes files
I am web developer, JS ES6 (without flow), JSX (react), mainly using VS code.
This is not essental I 'can' stick to the project rules. But this will save me much time.
Thanks for advices!
You could do this with Git smudge/clean filters. A pre-requisite is that you have a tool that does the conversion of 4 spaces and double quotes to 2 spaces and single quotes and vice versa. Assuming you have these two, let's call them 4to2converter and 2to4converter, do the following:
Edit (or create) your .gitattributes file by adding a line like this:
*.js filter=convert
This tells git that it should apply convert filter on all .js files. You can include other file types as well.
Then define what the convert filter does by adjusting git config:
$ git config filter.convert.smudge 2to4converter
$ git config filter.convert.clean 4to2converter
What happens now is that every time you commit .js files, the file is first ran through 2to4converter, and every time you do a checkout, it is first ran through 4to2converter.
Finally, ensure first that you don't have any uncommitted work, and run:
$ git checkout HEAD -- **
This forces a checkout on all files, applying your newly defined filter.
In my Angular JS app, I'm using a lot of third party packages, mainly maintained via Bower.
When I use Grunt to concatenate all of them into one mega file, I'm getting errors when I load my page, for example that
Uncaught ReferenceError: angular is not defined and
GET http://localhost:8080/theproj/v4/dist/app/bootstrap.css.map 404 (Not Found)
What is the best way to properly concatenate all these files to ensure that everything loads in the right order and doesn't cause problems?
First issue: A lot of times third party libraries must be loaded in a particular order. That looks like like it's the source of your first issue. Something is trying to use angular and it's getting loaded before the angular code. You should refactor your grunt task to use a pre-defined order for third party libraries.
Second issue: You probably are missing the .map file. This is a file used by Chrome dev tools to show you the original source for the css (sass or less). Either provide the map file, or delete the reference to it from bootstrap.css. Or just ignore the error, it's only an error when you have chrome dev tools open, and doesn't actually affect your application.
For the issue of the correct order for your javascript files, i had that problem in a larger project where noone really had a clue which was the correct order.
Luckily we found that the Google Closure Compiler does exactly this: https://github.com/google/closure-compiler
You give it all your js files and it analyzes them all and concatenates them in order
$ java -jar compiler.jar --js_output_file=out.js in1.js in2.js in3.js ...
There is even a grunt plugin for the connection: https://github.com/gmarty/grunt-closure-compiler
'closure-compiler': {
frontend: {
closurePath: '/src/to/closure-compiler',
js: 'static/src/frontend.js',
jsOutputFile: 'static/js/frontend.min.js',
maxBuffer: 500,
options: {
compilation_level: 'ADVANCED_OPTIMIZATIONS',
language_in: 'ECMASCRIPT5_STRICT'
}
}
},
Another way would be to change your javascripts into AMD or CommonJS modules, this way you don't have to worry about the correct order. RequireJS (http://requirejs.org/docs/start.html) is a possibility for AMD for example or Webpack (http://webpack.github.io/) ...or many many others.
I have a directory like below:
/folder/b.js
/folder/jQuery.js
/folder/a.js
/folder/sub/c.js
I want to minify all these js files in one js file in order:
jQuery.js -> a.js -> b.js -> c.js
Q:
1.How can I do it via grunt-contrib-uglify?(In fact, there are lots of files, it is impractical to specify all source filepaths individually)
2.btw, How can I get unminified files when debug and get minified single file when release and no need to change script tag in html(and how to write the script tag)?
Good questions!
1) Uglify will reorder the functions in the destination file so that function definitions are on top and function execution on bottom but it seems that it will preserve the order of the function executions.
This means that the function jQuery runs to define its global functions will be put first if you make sure jQuery is mentioned first in Uglify's config in the Gruntfile.
I use this config:
uglify: {
options: {
sourceMap: true
},
build: {
files: {
'public/all.min.js': ['public/js/vendor/jquery-1.10.2.min.js', 'public/js/*.js'],
}
}
}
2) I don't think there is one definite way to accomplish this. It depends on what web framework, templating framework and what kind of requirements you have. I use express + jade and in my main jade layout I have:
if process.env.NODE_ENV === 'production'
script(src='/all.min.js')
else
script(src='/js/vendor/jquery-1.10.2.min.js')
script(src='/js/someScript.js')
script(src='/js/otherScript.js')
In my package.json I have:
"scripts": {
"postinstall": "grunt"
},
This means that when I run npm install on deploy (on Heroku) grunt is run to minify/concat files and when the app is started with NODE_ENV=production the minified client side javascript is used. Locally I get served the original client side javascripts for easy debugging.
The two downsides are:
I have to keep the two lists of script files in sync (in the Gruntfile and in the layout.js) I solve this by using *.js in the Gruntfile but this may not suite everyone. You could put the list of javascripts in the Gruntfile and create a jade-template from this but it seems overkill for most projects.
If you don't trust your Grunt config you basically have to test running the application using NODE_ENV=production locally to verify that the minification worked the way you intended.
This can be done using the following Grunt tasks:
https://github.com/gruntjs/grunt-contrib-concat concatenates
files
https://github.com/gruntjs/grunt-contrib-uglify minifies
concatenated files
EDIT
I usually run all my files through a Grunt concatenation task using grunt-contrib-concat. Then I have another task to uglify the concatenated file using grunt-contrib-uglify.
You're probably not going to like this, but the best way is to define your js source files as AMD modules and use Requirejs to manage the order in which they load. The grunt-contrib-requirejs task will recurse your dependency tree and concatenate the js files in the necessary order into one big js file. You will then use uglify (actually r.js has uglify built-in) to minify the big file.
https://github.com/danheberden/yeoman-generator-requirejs has a good example gruntfile and template js files to work from.
EDIT
I've recently started using CommonJS modules instead of AMD since it's much closer to the ES6 module spec. You can achieve the same results (1 big complied+concatenated js file) by running commonjs modules through Browserify. There are plugins for both grunt and gulp to manage the task for you.
EDIT
I'd like to add that if your site is written using ES6 that Rollup is the best new concatenating package. In addition to bundling your files, it will also perform tree shaking, removing parts of libraries you use if included via an import statement. This reduces your codebase to just what you need without the bloat of code you'll never use.
I don't think you can do this with the uglify task alone, but you have a multitude of choices which might lead to your desired outcome.
A possible workflow would be first concatenating (grunt-contrib-concat) the files in order into one single file, and put this concatenated file through uglify. You can either define the order for concat in your Gruntfile, or you use on of those plugins:
First one would be https://github.com/yeoman/grunt-usemin, where you can specify the order in your HTML file, put some comments around your script block. The Google guys made it and it's pretty sweet to use.
Second one would be https://github.com/trek/grunt-neuter, where you can define some dependencies with require, but without the bulk of require.js. It requires changes in your JS code, so might not like it. I'd go with option one.
I ran into the same issue. A quick fix is just to change the filenames - I used 1.jquery.min.js, 2.bootstrap.min.js, etc.
This might be only remotely related to your question but I wanted something similar. Only my order was important in the following way:
I was loading all vendor files (angular, jquery, and their respective related plugins) with a wildcard (['vendor/**/*.js']). But some plugins had names that made them load before angular and jquery. A solution is to manually load them first.
['vendor/angular.js', 'vendor/jquery.js', 'vendor/**/*.js]
Luckily angular and jquery handle being loaded twice well enough. Edit: Although it's not really the best practice to load such large libraries twice, causing your minified file unnecessary bloat. (thanks #Kano for pointing this out!)
Another issue was client-js the order was important in a way that it required the main app file to be loaded last, after all its dependencies have been loaded. Solution to that was to exclude and then include:
['app/**/*.js', '!app/app.js', 'app/app.js']
This prevents app.js from being loaded along with all the other files, and only then includes it at the end.
Looks like the second part of your question is still unanswered. But let me try one by one.
Firstly you can join and uglify a large number of js files into one as explained by the concat answer earlier. It should also be possible to use https://github.com/gruntjs/grunt-contrib-uglify because it does seem to have wildcards. You may have to experiment with 'expand = true' option and wildcards. That takes care of your first question.
For the second part, say you joined and uglified into big-ugly.js
Now in your html you can add following directives:
<!-- build:js:dist big-ugly.js -->
<script src="js1.js"></script>
<script src="js2.js"></script>
<!-- etc etc -->
<script src="js100.js"></script>
<!-- /build -->
And then pass it through the grunt html preprocessor at https://www.npmjs.com/package/grunt-processhtml as part of your grunt jobs.
This preprocessor will replace the entire block with
<script src="big-ugly.js"></script>
Which means that the html file with be semantically equivalent - before and after the grunt jobs; i.e. if the page works correctly in the native form (for debugging) - then the transformed page must work correctly after the grunt - without requiring you to manually change any tags.
This was #1469's answer but he didn't make it clear why this works. Use concat to put all js files into one, this module does this in the order of file names, so I put a prefix to the file names based on orders. I believe it even has other options for ordering.
concat: {
js: {
options: {
block: true,
line: true,
stripBanners: true
},
files: {
'library/dist/js/scripts.js' : 'library/js/*.js',
}
}
},
Then use uglify to create the minified ugly version:
uglify: {
dist: {
files: {
'library/dist/js/scripts.min.js': [
'library/js/scripts.js'
]
},
options: {
}
}
},
If your problem was that you had vendors which needed to be loaded in order (let's say jquery before any jquery plugins). I solved it by putting jquery in its own folder called '!jquery', effectively putting it on top of the stack.
Then I just used concat as you normally would:
concat: {
options: {
separator: ';',
},
build: {
files: [
{
src: ['js/vendor/**/*.js', 'js/main.min.js'],
dest: 'js/global.min.js'
}
]
}
},
Using the bundle feature of mvc4 courses
Uncaught SyntaxError: Unexpected token <
on loading. With debug="true" everything is works like excepted.
How can i solve the error or can i disable the bundle feature just for scripts?
Solved
Renamed the bundle name to not match up with any directory
Before you can answer the question of what caused this error, you must first figure out where the error occurred. The only difference in the syntax of your code when bundled is that it is minified. A very simple way to do this is to use a Bundle instead of a ScriptBundle:
var thirdParty = new Bundle("~/bundles/thirdParty").Include(
"~/Scripts/jquery-{version}.js",
"~/Scripts/bootstrap.js",
"~/Scripts/jquery-ui-{version}.js",
"~/Scripts/jquery.mockjson.js",
"~/Scripts/jQuery.XDomainRequest.js",
"~/Scripts/knockout-{version}.js"
);
thirdParty.Transforms.Clear();
bundles.Add(thirdParty);
Now, if you have multiple JavaScript bundles, do this for them one by one until you have the culprit bundle.
The only way that I've found to debug these issues is to take your bundle and split it in half to break it down further:
var thirdParty1 = new Bundle("~/bundles/thirdParty1").Include(
"~/Scripts/jquery-{version}.js",
"~/Scripts/bootstrap.js",
"~/Scripts/jquery-ui-{version}.js"
);
bundles.Add(thirdParty1);
var thirdParty2 = new ScriptBundle("~/bundles/thirdParty2").Include(
"~/Scripts/jquery.mockjson.js",
"~/Scripts/jQuery.XDomainRequest.js",
"~/Scripts/knockout-{version}.js"
);
bundles.Add(thirdParty2);
Notice that we've only disabled minification for one of the two bundles - thirdParty1. Be sure and update your #Scripts.Render to point to your new bundles. When you build and reload, you will either continue to get the error, or you won't, and will then know which half contains the troublesome code. But be sure and test it both ways, minifying thirdParty1 and unminifying thirdParty2 in my example and vice-versa to be certain something else isn't going on. You also might want to keep DevTools or whatever browser debugger you have open and look at the source of your bundles to ensure they are acting as expected.
Continue by moving the scripts from the minified bundle (thirdParty1 in my case) from the unminified bundle (thirdParty2) either one at a time or in chunks, if you have a lot of scripts. Remember to rebuild in-between, and be careful not to change the inclusion order of your scripts.
That should at least get you down to the file that has the issue - and hopefully searching for "<" will get you your answer.
Hope that helps.
His solution helped me, renaming the bundle to be different than the directory. I was grouping mine like so:
#Styles.Render("~/jqueryui")
#Scripts.Render("~/jqueryui")
There seems to be a bug when doing it this way with jquery UI styles. I just renamed the bundle to:
#Styles.Render("~/jqueryuiz")
#Scripts.Render("~/jqueryui")
and this fixed it for me. So the scripts don't seem to be affected in this way, nor do similar bundles, I have about 20 sets of bundles loaded and this is the only one causing issues.
My issue:
I reference script files in my Content folder but have a bundle name of ~Scipts. I renamed my bundle to ~DefaultScripts and that fix my issue. I didn't want to reference the Scripts folder, but it was going there instead of my Content folder.
bundles.Add(New ScriptBundle("~/Scripts").Include(
"~/Content/assets/global/plugins/jquery.min.js",
"~/Content/assets/global/plugins/bootstrap/js/bootstrap.min.js",
"~/Content/assets/global/plugins/js.cookie.min.js",
"~/Content/assets/global/plugins/jquery-slimscroll/jquery.slimscroll.min.js",
"~/Content/assets/global/plugins/jquery.blockui.min.js",
"~/Content/assets/global/plugins/bootstrap-switch/js/bootstrap-switch.min.js",
"~/Content/assets/global/scripts/app.js",
"~/Content/assets/layouts/layout2/scripts/layout.min.js",
"~/Scripts/custom.js"))
bundles.Add(New ScriptBundle("~/DefaultScripts").Include(
"~/Content/assets/global/plugins/jquery.min.js",
"~/Content/assets/global/plugins/bootstrap/js/bootstrap.min.js",
"~/Content/assets/global/plugins/js.cookie.min.js",
"~/Content/assets/global/plugins/jquery-slimscroll/jquery.slimscroll.min.js",
"~/Content/assets/global/plugins/jquery.blockui.min.js",
"~/Content/assets/global/plugins/bootstrap-switch/js/bootstrap-switch.min.js",
"~/Content/assets/global/scripts/app.js",
"~/Content/assets/layouts/layout2/scripts/layout.min.js",
"~/Scripts/custom.js"))