I\'d like to know if there is a way to uglify only one file in command line using r.js (RequireJS Optimizer) which is already installed in my computer. Like we can minify a css
Since you mentioned this as a possibility in your question, I'm going to cover it.
On the computer that has uglify-js
. Find where uglify-js
is installed. Archive that directory and its subdirectories.
On the disconnected computer. Unarchive that directory in a node_modules
subdirectory for your project. Let's suppose the project is in /home/johndoe/foo
. I would want to unarchive it in /home/johndoe/foo/node_modules
.
You can use uglify-js
at node_modules/uglify-js/bin/uglify-js
.
This first method is the method I would use.
If somehow the first method does not work for you or does not work well, there's a second method. The fact is that copying installed Node packages does not perfectly replicate the installation process. In may cases it may work perfectly but in some cases it may not. So here's a method that makes npm
go through the whole installation process.
On the computer where uglify is installed, do:
$ npm ls
In the output look for uglify-js and all the packages that are inside it hierarchically. The output will look like this:
├── cookie@0.1.0
├─┬ uglify-js@2.4.12
│ ├── async@0.2.10
│ ├─┬ optimist@0.3.7
│ │ └── wordwrap@0.0.2
│ ├─┬ source-map@0.1.31
│ │ └── amdefine@0.1.0
│ └── uglify-to-browserify@1.0.2
└── yaml@0.2.3
In the output above you care about uglify-js
up to and including uglify-to-browserify
. For each of these packages, look into npm's cache for the compressed package file. On Linux and similar systems this will be in ~/.npm/
. For instance, on my machine uglify-js
is cached at ~/.npm/uglify-js/2.4.12/package.tgz
. Copy each of these packages to media that you can take to the disconnected computer. Make sure that you copy the correct versions. They are listed after the @
sign in the listing above.
Move the media to your disconnected computer.
For each package install it with:
$ npm install [path to the tgz file]
When you pass a tgz
to npm
it ignores the network, so long as all dependencies are met. The order here is important. You want to start with packages that have no dependencies themselves. I beleive the way npm ls
produces its list, if you just go in reverse order you'll be okay. So:
At the end of this process the uglifyjs
command will be in node_modules/.bin/uglifyjs
. You can readily test it against one of uglifyjs
' own files. For instance:
$ node_modules/.bin/uglifyjs node_modules/uglify-js/lib/output.js
I've tried a few other methods but found that npm
is quite eager to go to the network to find packages. It's really easy to think "maybe ABC would work..." and find that it does not because even though everything is available locally, npm
still wants a network connection.
uglify-js
included in r.js
The r.js
optimizer include s uglify-js
in it. Unfortunately, it is not packaged to be trivially usable outside r.js
. However, you can access it like this:
var r = require("./node_modules/.bin/r.js");
var fs = require("fs");
var config = {};
var fileContents = fs.readFileSync(process.argv[2]).toString();
r.tools.useLib("mine", function (require) {
require(["uglifyjs/index"], function (uglify) {
var parser = uglify.parser;
var processor = uglify.uglify;
var ast = parser.parse(fileContents, config.strict_semicolons);
if (config.no_mangle !== true) {
ast = processor.ast_mangle(ast, config);
}
ast = processor.ast_squeeze(ast, config);
fileContents = processor.gen_code(ast, config);
if (config.max_line_length) {
fileContents = processor.split_lines(fileContents,
config.max_line_length);
}
//Add trailing semicolon to match uglifyjs command line version
fileContents += ';';
fs.writeFileSync(process.argv[3], fileContents);
});
});
If the above code is saved in a file named script.js
and invoked like this node script.js input output
, it will uglify input
and put the result in output
. The key is to use the tools.useLib
method exported by r.js
. This allows access to the libraries that r.js
includes. The rest of the code is mostly copied from the section in r.js
where it performs uglification.
r.js
at the command line$ r.js -o name=main exclude=main out=built.js
This would optimize only the module main
(in the file main.js
) and put the output in build.js
. It won't follow any dependencies of main
. However, it modifies the define
by adding the module's name as the first parameter. This could be removed with a post-processing step with sed
, awk
, perl
, etc.
If the file you want to uglify would be shimmed for use with RequireJS (not an actual AMD-style module), you don't want to use the exclude
parameter:
$ r.js -o name=shimmed out=built.js
Just like the first command above, this also does more than just uglify the file. It adds a define
call at the end. Again, this could be taken out with sed
or a similar tool.
(I've definitely been able to use these commands without baseUrl=.
. However, depending on what you do exactly, r.js
may complain. So you may have to add baseUrl=.
to the command line.)