Uglify RequireJS modules without concatenating them - optimization

Is it possible to uglify all the RequireJS modules without concatenating them into a single file? (I know the other way round is possible with optimize: "none").

I know uglifyjs-folder have this option, with parameters -e and -o referencing a folder (not a file).
ex:
uglifyjs-folder "%CD%" -e -o "%CD%\subfolder"
(obs: %CD% in Windows gets the current folder)

It is possible use r.js to uglify the files without concatenating them. If you do not provide any module name in the configuration options (i.e. you don't use modules nor specify name), then r.js will process each file from baseUrl individually, and thus will uglify each file without concatenation. For instance, this trivial build configuration:
{
baseUrl: "js",
dir: "build",
}
causes r.js to process each file from js individually and copy it into build after uglifying the file. No concatenation happens no matter how many files you have in js. With the configuration above, r.js will not trace any dependencies between modules because it does not need to trace dependencies to do its work.
This being said, I would not use r.js for the purpose of uglifying the files individually unless there was some additional feature of r.js I'd need to use. For instance, it may be expedient to use cjsTranslate: true to have r.js convert CommonJS modules to AMD, and perform the uglification at the same time.

Related

lessc Option --source-map-rootpath seems not to work

I use lessc 2.7.3. I generate css files via a makefile and use following paths
the makefile is in themes/bodensee
the css is generated in themes/bodensee/css
the less files are in themes/bodensee/less
the maps are in the same folder as the css files.
My problem is that css files misses the themes/bodensee path, so it raises a file not found on css.map files.
lessc -s less/wlb.less --clean-css="--s0 --advanced" --source-map-rootpath=themes/bodensee/ --source-map="css/wlb.css.map" css/wlb.css
The CSS file now contains `sourceMappingURL=css/wlb.css.map``The rootpath does not have any effect.
I also tried a fantasy rootpath and searched for it in the file - it does not appear anywhere. But the option is correct. When I try to missspell the option, LESS drops an error.
What am I missing?
Description of the --source-map-rootpath option from here
Specifies a rootpath that should be prepended to each of the less file paths inside the sourcemap and also to the path to the map file specified in your output css.
Because the basepath defaults to the directory of the input less file, the rootpath defaults to the path from the sourcemap output file to the base directory of the input less file.
Use this option if for instance you have a css file generated in the root on your web server but have your source less/css/map files in a different folder. So for the option above you might have
The problem was indeed related to the Clean-CSS plugin.
I now call
lessc --source-map --clean-css="--s0 --advanced" -s less/wlb.less css/wlb.css which is working.
There is a standalone clean-css program, but that does not generate sources for the Less files. It's not clear if the lessc plugin and the standalone tool are the same or different implementations but both use node.
The standalone cleancss tool removes the source map URL generated by lessc be default (did not play around with the dozens of options).
These Node tools develop very fast and manual/tutorials often are outdated. That's why my make file stopped working. Developers of that tools should really consider not to touch working parameters or features and to keep their code compatible.

Why would one need gulp-concat, even though browserify is already being used?

I was of the understanding that Browserify could be used to bundle various JavaScript files into one. However, after looking at some examples on the internet, I found that some people use Browserify and yet they also include gulp-concat.
For example, the angularjs-gulp-example project uses both.
Why? I thought Browserify could do the concatenation as well.
Browserify is a bundler that creates JavaScript bundles from CommonJS modules. Typically, the bundle will contain all of a project's source files and all of the CommonJS/UMD dependencies. (Also, like Node, Browserify can require JSON files, so they could be in the bundle, too.)
If a project has dependencies that are not included using require and are instead indended to be used in <script> elements - the build process might opt to use a tool like gulp-concat to concatenate them to the front of the bundle.
That's likely why gulp-concat is used in the project you referenced in your question. It concatenates an Angular template cache that's generated from .html files - something Browserify doesn't deal with (unless a transform has been configured).

How to use package.json scripts to copy files with specific file extension

I am trying out npm as a build tool.
One stumbling block I have encountered is that I need to copy javascript files from one folder to another. The source folder contains typescript files, javascript files and map files, but in the target folder I am only interested in javascript files.
I do not want to make a copy-statement for each file, but would like to copy all .js files. Also, my source folder contains subfolders that also contains javascript files. These need to be copied as well, and maintain the subfolder structure.
What I have tried is using NCP with a filter, but I cannot get the filter to work. I have tested the regex used in the filter and it appears to work fine. The test was done at Regex Tester with regular expression .*\.js$ and test-strings like main.ts, main.js main.js.map etc, and only the .js strings were matched.
My package json contains the following (abbreviated):
{
"scripts": {
"copy": "ncp scripts wwwroot/scripts --filter=\".*(\\\\.js$)\""
},
"devDependencies": {
"ncp": "2.0.0.0"
}
}
Since my regex is in a string in a string I have double-escaped it. I have also tried other variations, for example:
--filter=/.*\.js$/g - compilation error
--filter=/.*\\.js$/g - no files copied
--filter=\".*\\.js$\" - no files copied
--filter=\"/.*\\.js$/g\" - no files copied
(no filter) - all files copied
I am in no way married to NCP. If something else works better then I will use that.
So: How do I, inside package.json's scripts section copy only files with a speific extension to another folder? I am pretty sure I have overlooked something blindingly obvious...
Warning! The cpx package appears to be abandoned. cpy-cli, copyfiles, and other solutions are listed in comments here or answers, below.
cpx might be a good substitution.
It has a CLI, allows you to use globs instead of regex, can preserve the directory tree, and is relatively up-to-date as I write this....
There's also npm module called copyfiles
https://github.com/calvinmetcalf/copyfiles
E.g. to copy all *.css files from the ./src folder to the ./styles folder:
copyfiles --flat src/*.css styles
Quick compatibility build script (also works on Windows):
"build": "react-scripts build && mv build docs || move build docs",
#powershell copy \"D:/Path/untitled.txt\" destionation-file.txt"
Windows users:
// Copy file
xcopy c:\workfile d:\test
// Copy folders incl. sub folders
xcopy <source> <destination> /e
// If folder name has space in name use double quotes
xcopy c:\workfile “d:\test new”
More info here
You can use gulp.js for this.
Write a gulp task to isolate only the js files (/path/to/files/*.js) and move it to destination of your choice.
It will require only a few lines of code.
Include that in the script section of package.json if necessary.
The link to gulp.js : https://gulpjs.com/
var gulp = require('gulp');
gulp.task('jscopy', function(){
return gulp.src('client/templates/*.js')
.pipe(gulp.dest('build/js'))
});
ncp copies recursively, therefore before copying files it will check whether directory matches filter or not, e.g.:
d:\path\to\app\src\server
d:\path\to\app\src\server\middleware
d:\path\to\app\src\server\middleware\cool-middleware.js
d:\path\to\app\src\server\middleware\cool-middleware.js.map
So your regex must matches all these paths and your file also
I am able to just use cp in my script command:
"build": "npx babel src --out-dir dist && cp ./src/*.css ./dist",
This will work if you have your distribution package already inside the /dist folder. You can also add another command to copy that over, then even run the publish command.
I use this in Git bash in windows which has the cp command available. The comments are correct that you will need this in your underlying shell/command prompt. It should be able to be modeled and updated for your OS.
#KostovV answer but adapted for json string and relative path
"build": "nest build && xcopy \".\\myFolder0\" \".\\myFolde1\\sub\"",

browserify with noparse=true - how it works

I would like to ask what is the purpose of using browserify with noparse option set to true (or how browserify works). For instance:
if browserify does not parse files at all, does it means that it will not find require statements?
if it does not find require statements, then how to force code to load module? For instance, I have toastr & jQuery. toastr requires jQuery. But when I used browserify to create a bundle with noparse set to true, and I added to this bundle both files:
var bundler = browserify();
bundler.add('jquery.js');
bundler.add('toastr.js');
bundler.bundle();
then I get the error, that jQuery module it not found.
Normally when you bundle a file with browserify, it parses the file for require() calls so it can build a dependency graph and bundle the required files. The purpose of the noParse option is to skip that parsing when you don't need or want it. For example, if you're bundling a large library file like jQuery and you know it doesn't contain any require() calls that need to be processed, it will save time in bundling if you noParse that file. Also, it's currently difficult to require() a previously browserified bundle when making a new bundle. In that case you can sometimes resolve the issue by setting noParse for the previously browserified bundle.
if browserify does not parse files at all, does it means that it will not find require statements?
Yes.

Why is browserify pulling in a lib 2 times? - Browserify

I have an Angular app where I use browserify to manage my dependencies. I am also using momentjs to do all my time manipulation. I have several modules that I am using browserify to build, but it is pulling in momentjs more than once, even when I use the external command. Here is my code. First I have a base module that has all of my shared libs:
require('angular');
require('angular-route');
require('moment');
Here is the code I use to browserify in my gulpfile.js:
browserify().require('./js/donor/donor-libs.js')
.bundle()
.pipe(source('donor-libs.js'))
.pipe(gulp.dest('./build'));
This builds out fine and has the libs that I would expect including momentjs.
Now I go to build a module that is dependent on this module. momentjs is used in this module. Here is the code that I use to build the module:
browserify().require('./js/donor/history-module.js')
.external('./js/donor/donor-libs.js')
.bundle()
.pipe(source(filename))
.pipe(gulp.dest('./build'));
Now when I look in my build directory, I have momentjs in both the donor-libs.js and my history-module.js. Why doesn't it recognize that I have already required in momentjs in my donor-libs.js? What do I need to do to only require in 3rd party libs one time? What don't I understand about the external command?
The reason libs are being pulled in multiple times is that the external command is being used improperly. external is expecting a path or an array of paths that will externalized. external will not look through a js file and find the required files and then not pull them in other modules. The code should of looked something like this
.external('angular', 'angular-route', 'moment')
or the path to the required lib. This would of externalized these files and fixed the problem of a lib being pulled in multiple times.