[WIP][3.x] Make minify portable by making it work without file system#1366
[WIP][3.x] Make minify portable by making it work without file system#1366avdg wants to merge 1 commit intomishoo:masterfrom
Conversation
|
Demo:
Example code:
|
lib/minify.js
Outdated
| @@ -0,0 +1,125 @@ | |||
| exports.readFile = exports.simple_glob = exports.readNameCache = | |||
| exports.writeNameCache = function() { | |||
| throw Error("UglifyJS has no access to the file system"); | |||
There was a problem hiding this comment.
Would prefer a top level named error function followed by four lines with one assignment per line.
lib/minify.js
Outdated
| if (options.spidermonkey) { | ||
| toplevel = AST_Node.from_mozilla_ast(files); | ||
| } else { | ||
| function addFile(file, fileUrl) { |
There was a problem hiding this comment.
Can't declare a function in an if or else:
$ npm test
uglify-js@2.7.4 test /home/travis/build/mishoo/UglifyJS2
node test/run-tests.js
undefined:9153
function addFile(file, fileUrl) {
^^^^^^^^
SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function.
There was a problem hiding this comment.
Actually, this is the same code (only moved a bit). And didn't fix (although I could) because I spend time doing other things apparently.
There was a problem hiding this comment.
|
Assuming all tests pass, the patch looks fine. Although not much code was changed in minify(), the mangle name caches may not have been tested extensively in the previously existing minify() tests. Is it possible for users to override the four minify functions that use the file system to provide their own browser equivalents of a fake file system if they wanted? |
Yes, export is the same object as UglifyJS. As long as users can reach that code, users can change the functionality. |
|
I might remove |
|
Hmm I have to see, maybe we should allow external api to pass data to these read/write nameCache properties in some way (without changing other api's). I have to see how to refactor this yet. |
|
I won't make |
|
There's no files to glob in the browser (no equivalent of |
|
To abstract the file system, hooks would be needed for these cases: $ egrep '(fs|path)\.' tools/node.js
return fs.realpathSync(path.join(path.dirname(__filename), file));
return fs.readFileSync(file, "utf8");
: fs.readFileSync(file, "utf8");
inMap = JSON.parse(fs.readFileSync(options.inSourceMap, "utf8"));
var data = fs.readFileSync(filename, "utf8");
return readReservedFile(path.join(__dirname, "domprops.json"), reserved);
var cache = fs.readFileSync(filename, "utf8");
data = fs.readFileSync(filename, "utf8");
fs.writeFileSync(filename, JSON.stringify(data, null, 2), "utf8");
var dir = path.dirname(glob);
var entries = fs.readdirSync(dir);
var pattern = "^" + (path.basename(glob)
They needn't be implemented for the browser. |
|
|
|
Going to move the current progress to harmony...avdg:portable-minify-backup Then rebase this patch to be mergeable with master again. |
6694138 to
83369d5
Compare
lib/minify.js
Outdated
| @@ -0,0 +1,168 @@ | |||
| exports.readFile = function() { | |||
| DefaultsError.croak("UglifyJS has no access to read from the file system"); | |||
There was a problem hiding this comment.
Error message is too verbose - "readFile not supported" is sufficient. Ditto for writeFile and simple_glob.
30af788 to
eb3250d
Compare
|
You could add a test in test/mocha/cli.js for the |
|
Ow yeah, these tests there generate the portable version. |
|
Added few tests on the hooks (and fromString). There are still some additional tests needed for readNameCache, writeNameCache and the errors (as it seems that the errors simply don't show up). |
| }; | ||
|
|
||
| exports.simple_glob = function(files) { | ||
| return files; |
There was a problem hiding this comment.
Should return an array of strings if a scalar is passed:
exports.simple_glob = function(files) {
return Array.isArray(files) ? files : [ files ];
}as per comments in the original implementation:
// Argument `glob` may be a string or an array of strings.
// Returns an array of strings. Garbage in, garbage out.
There was a problem hiding this comment.
Seems the current code handles string as parameter fine, adding test as extra insurance for now.
There was a problem hiding this comment.
concat handles this flexible, non-arrays are implicitly treated as an array with 1 element.
test/mocha/portable.js
Outdated
| }); | ||
|
|
||
| it("Should minify from a string successfully", function() { | ||
| assert.strictEqual(minifier.minify('console.log("Hello world!");', {fromString: true}).code, |
There was a problem hiding this comment.
Suggest minifying 'console["log"]("Hello " + "world!");' in all your examples in this file to show that minify() actually did something.
|
I think I'm renaming |
It's already part of the external API and shouldn't be renamed. |
That's unfortunate then... |
|
About the renaming, maybe it might be listed in a separate issue, ready to fill any gap of opportunity. Given that minifiers are getting competition and that this is a relative small task that leads to better consistency of the api this might be an alternative option. This will also give more reasons to keep simple_glob part of the unofficial api, which is already an upgrade from being undocumented. |
|
Please keep the external API the same. You can add to it, but not remove stuff from it. Remember that |
If there's an UglifyJS2 3.x release then the external API can be altered. Probably the same time as minify() is dropped into bin/uglifyjs and/or harmony is merged into master - after the ES6 scope and compress bugs are fixed. Another thing that should be done in a hypothetical 3.x release is to flatten the overly complicated uglify options that currently has 4 or 5 different sub-sections: mangle, compress, mangleProps, and output (a.k.a. beautify) - and unify the options between bin/uglify and minify(). |
|
|
||
| // 3. mangle properties | ||
| if (options.mangleProperties || options.nameCache) { | ||
| options.mangleProperties.cache = readNameCache(options.nameCache, "props"); |
There was a problem hiding this comment.
options.mangleProperties defaults to false, which isn't an object :/ Need to know how this stuff is working before I can fix this...
There was a problem hiding this comment.
This code seems to come from #910 and isn't actually tested properly
There was a problem hiding this comment.
Just using default value to fix this...
|
I really hope I didn't do anything wrong and that the test coverage is good. It's easy to lose track of changes because |
|
Gonna attempt to stage it as is, additional features can be added and there is nothing structural anyway. |
|
Did a manual diff of the minify function, should look good |
|
Much better - only Travis CI is upset now: https://travis-ci.org/mishoo/UglifyJS2/jobs/220551459#L244-L247 I think we need to pull https://github.com/mishoo/UglifyJS2/pull/1366/files#diff-465a5a39285d7d0ab958a973c3d58432R96 |
|
oh yeah, it should be done differently, easy peasy... |
|
well, moving outside the else block shouldn't be enough... I defined it as an inline function. |
| exports["SymbolDef"] = SymbolDef; | ||
| exports["minify"] = minify; | ||
| exports["readNameCache"] = readNameCache; | ||
| exports["writeNameCache"] = writeNameCache; |
There was a problem hiding this comment.
Let's not export readNameCache & writeNameCache, as we never do before anyway.
There was a problem hiding this comment.
bin/uglifyjs depends on it
There was a problem hiding this comment.
we might do a deprecation policy
There was a problem hiding this comment.
Ah yes, it is exported directly under tools/node.js prior to this PR.
|
Just removed a whitespace |
|
Please update #1366 (diff) to use |
|
Done so for |
| }; | ||
|
|
||
| var defaultBase64Decoder = exports.base64Decoder = function(input) { | ||
| DefaultsError.croak("No base64 decoder implemented"); |
There was a problem hiding this comment.
Should fallback to using atob here if typeof atob == "function".
| } | ||
|
|
||
| var defaultBase64Encoder = exports.base64Encoder = function(input) { | ||
| DefaultsError.croak("No base64 encoder implemented"); |
There was a problem hiding this comment.
Should fallback to using btoa here if typeof btoa == "function".
|
- refactor `screw_ie8` to `ie8` - compact `sourceMap` options - more stringent verification on input `options` - toplevel shorthands - `ie8` - `keep_fnames` - `toplevel` closes mishoo#96 closes mishoo#1366 fixes mishoo#124 fixes mishoo#263 fixes mishoo#379 fixes mishoo#423 fixes mishoo#576 fixes mishoo#737 fixes mishoo#958 fixes mishoo#1036 fixes mishoo#1175 fixes mishoo#1220 fixes mishoo#1223 fixes mishoo#1280
- refactor `screw_ie8` to `ie8` - compact `sourceMap` options - more stringent verification on input `options` - toplevel shorthands - `ie8` - `keep_fnames` - `toplevel` - deprecated `fromString` in `minify()` - `minify()` no longer handles any `fs` operations - unify order of operations for `mangle_properties()` on CLI & API - `bin/uglifyjs` used to `mangle_properties()` before even `Compressor` - `minify()` used to `mangle_properties()` after `Compressor` but before `mangle_names()` - both will now do `Compressor`, `mangle_names()` then `mangle_properties()` closes mishoo#96 closes mishoo#1366 fixes mishoo#124 fixes mishoo#263 fixes mishoo#379 fixes mishoo#423 fixes mishoo#576 fixes mishoo#737 fixes mishoo#958 fixes mishoo#1036 fixes mishoo#1175 fixes mishoo#1220 fixes mishoo#1223 fixes mishoo#1280
- refactor `screw_ie8` to `ie8` - compact `sourceMap` options - more stringent verification on input `options` - toplevel shorthands - `ie8` - `keep_fnames` - `toplevel` - deprecated `fromString` in `minify()` - `minify()` no longer handles any `fs` operations - unify order of operations for `mangle_properties()` on CLI & API - `bin/uglifyjs` used to `mangle_properties()` before even `Compressor` - `minify()` used to `mangle_properties()` after `Compressor` but before `mangle_names()` - both will now do `Compressor`, `mangle_names()` then `mangle_properties()` closes mishoo#96 closes mishoo#1366 fixes mishoo#124 fixes mishoo#263 fixes mishoo#379 fixes mishoo#423 fixes mishoo#576 fixes mishoo#737 fixes mishoo#958 fixes mishoo#1036 fixes mishoo#1175 fixes mishoo#1220 fixes mishoo#1223 fixes mishoo#1280
- refactor `screw_ie8` to `ie8` - compact `sourceMap` options - more stringent verification on input `options` - toplevel shorthands - `ie8` - `keep_fnames` - `toplevel` - deprecated `fromString` in `minify()` - `minify()` no longer handles any `fs` operations - unify order of operations for `mangle_properties()` on CLI & API - `bin/uglifyjs` used to `mangle_properties()` before even `Compressor` - `minify()` used to `mangle_properties()` after `Compressor` but before `mangle_names()` - both will now do `Compressor`, `mangle_names()` then `mangle_properties()` - `options.parse` / `--parse` for parser options beyond `bare_returns` closes mishoo#96 closes mishoo#1366 fixes mishoo#124 fixes mishoo#263 fixes mishoo#379 fixes mishoo#423 fixes mishoo#576 fixes mishoo#737 fixes mishoo#958 fixes mishoo#1036 fixes mishoo#1175 fixes mishoo#1220 fixes mishoo#1223 fixes mishoo#1280
- refactor `screw_ie8` to `ie8` - compact `sourceMap` options - more stringent verification on input `options` - toplevel shorthands - `ie8` - `keep_fnames` - `toplevel` - deprecated `fromString` in `minify()` - `minify()` no longer handles any `fs` operations - unify order of operations for `mangle_properties()` on CLI & API - `bin/uglifyjs` used to `mangle_properties()` before even `Compressor` - `minify()` used to `mangle_properties()` after `Compressor` but before `mangle_names()` - both will now do `Compressor`, `mangle_names()` then `mangle_properties()` - `options.parse` / `--parse` for parser options beyond `bare_returns` closes mishoo#96 closes mishoo#1366 fixes mishoo#124 fixes mishoo#263 fixes mishoo#379 fixes mishoo#423 fixes mishoo#576 fixes mishoo#737 fixes mishoo#958 fixes mishoo#1036 fixes mishoo#1175 fixes mishoo#1220 fixes mishoo#1223 fixes mishoo#1280
|
I'm quite busy for now as I do lots of interviews, so here my apology that I even can't do simple fixes that requires more than 1 click. |
- rename `screw_ie8` to `ie8` - rename `mangle.except` to `mangle.reserved` - rename `mangle.properties.ignore_quoted` to `mangle.properties.keep_quoted` - compact `sourceMap` options - more stringent verification on input `options` - toplevel shorthands - `ie8` - `keep_fnames` - `toplevel` - `warnings` - support arrays and unquoted string values on CLI - drop `fromString` from `minify()` - `minify()` no longer handles any `fs` operations - unify order of operations for `mangle_properties()` on CLI & API - `bin/uglifyjs` used to `mangle_properties()` before even `Compressor` - `minify()` used to `mangle_properties()` after `Compressor` but before `mangle_names()` - both will now do `Compressor`, `mangle_names()` then `mangle_properties()` - `options.parse` / `--parse` for parser options beyond `bare_returns` - add `mangle.properties.builtins` to disable built-in reserved list - disable with `--mangle-props builtins` on CLI - `warnings` now off by default - add `--warn` and `--verbose` on CLI - drop `--enclose` - drop `--export-all` - drop `--reserved-file` - use `--mangle reserved` instead - drop `--reserve-domprops` - enabled by default, disable with `--mangle-props domprops` - drop `--prefix` - use `--source-map base` instead - drop `--lint` - remove `bin/extract-props.js` - limit exposure of internal APIs - update documentations closes #96 closes #102 closes #136 closes #166 closes #243 closes #254 closes #261 closes #311 closes #700 closes #748 closes #912 closes #1072 closes #1366 fixes #101 fixes #123 fixes #124 fixes #263 fixes #379 fixes #419 fixes #423 fixes #461 fixes #465 fixes #576 fixes #737 fixes #772 fixes #958 fixes #1036 fixes #1142 fixes #1175 fixes #1220 fixes #1223 fixes #1280 fixes #1359 fixes #1368
|
Hmm.. I might want to port the tests to the latest master |
Current status: Preparing for merge. Open for feedback.
TODO:
readNameCacheandwriteNameCacheinternal api, relying onreadFileandwriteFileas platform depending "drivers"writeFileandreadFileas overwritable functions in portable version. (Not so forsimple_glob, which will be unofficial api even though it is as easy to overwrite this function)simple_globbeing available.Test readFile individually(should be covered enough?)EXTRA: