Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sourceMap.content "auto" option #298

Closed
wants to merge 13 commits into from

Conversation

connorjclark
Copy link
Contributor

@connorjclark connorjclark commented Mar 2, 2019

I originally made these changes on UglifyJS2, but I merged them to Terser in the hopes they'd get accepted here :)

My original PR on UglifyJS: mishoo/UglifyJS#3220

Also involved adding these changes: mishoo/UglifyJS#3058

overview

Implements mishoo/UglifyJS#3219

--source-map "content=auto"

Allows for easier composition of source maps.

If an input file specifies a sourceMappingURL comment, the source map will be fetched.
If there is no comment, given an input file of src/file.js, the map will be looked for
at src/file.js.map and src/file.map. Maps can fetched via HTTP too.

--source-map "content=auto,contents=file1.js*file1.js.map|file2.js*path/to/map.js.map|..."

Allows for overriding the auto resolution strategy.

other stuff

Open to a different format for sourceMap.contents.

This is a super set of the other source map content options. I suggest removing those in a new major version, and making this "auto" behavior the default.

Copy link
Contributor

@L2jLiga L2jLiga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool stuff 😄

bin/uglifyjs Outdated
@@ -221,6 +223,59 @@ function run() {
} catch (ex) {
fatal(ex);
}
if (content == "auto") {
var to_ascii = function(b64) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can use UglifyJS.to_ascii

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

bin/uglifyjs Outdated
@@ -221,6 +223,59 @@ function run() {
} catch (ex) {
fatal(ex);
}
if (content == "auto") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to use strict equal

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

bin/uglifyjs Outdated

if (sourceMappingURL.indexOf('http') == 0) {
try {
return execSync('curl -s ' + sourceMappingURL).toString();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On my windows machine curl is not installed.... 😖

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace with the http libs. Required some promises.

lib/minify.js Outdated
if (typeof source_map_content == "string" && source_map_content != "inline" && source_map_content != "auto") {
source_map_content = parse_source_map(source_map_content);
}
source_maps = source_map_content && Object.create(null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to #300 (comment) I guess it would be much better to use smth like:

if (source_map_content) source_maps = new Set();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least it will reduce variety in code which doing same things

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 , but it's actually a Map.

bin/uglifyjs Outdated

if (!sourceMappingURL) {
// infer
if (fs.existsSync(name + '.map')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ESLint: Strings must use doublequote. (quotes)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

lib/sourcemap.js Outdated
if (sourceContent) {
generator.setSourceContent(source, sourceContent);
}
var maps = options.orig && Object.create(null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like Set

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 , but it's actually a Map.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad)

bin/uglifyjs Outdated
@@ -135,7 +136,7 @@ if (program.output == "ast") {
if (program.parse) {
if (!program.parse.acorn && !program.parse.spidermonkey) {
options.parse = program.parse;
} else if (program.sourceMap && program.sourceMap.content == "inline") {
} else if (content == "inline") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm little bit worried about this changes..
ESLint: 'content' is not defined. (no-undef)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops!

bin/uglifyjs Outdated
@@ -4,7 +4,7 @@

"use strict";

require("../tools/exit.js");
// require("../tools/exit.js");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to remove this to get the tests that expect errors to work. I can't reason about this code or how to augment it - ideas?

@connorjclark
Copy link
Contributor Author

This is a super set of the other source map content options. I suggest removing those in a new major version, and making this "auto" behavior the default.

Should this go for 4.0 or 5.0?

@connorjclark
Copy link
Contributor Author

connorjclark commented Mar 4, 2019

Forgot node 6 doesn't do async/await :( I'll update tomorrow. although, don't you think terser users would be long off of 6? :)

@L2jLiga
Copy link
Contributor

L2jLiga commented Mar 4, 2019

I think it can be part of Terser 4.0

@connorjclark
Copy link
Contributor Author

connorjclark commented Mar 4, 2019

I think it can be part of Terser 4.0

OK. I'll see about removing the "inline" in a follow up PR.

@connorjclark
Copy link
Contributor Author

OK- removed async/await. Obviously made the code less readable. More proof that async/await is a game changer :)

resolveSourcemapsPromise = Promise.resolve();
}
return resolveSourcemapsPromise.then(() => {
var result = UglifyJS.minify(files, options);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all of this below is just indentation

@connorjclark
Copy link
Contributor Author

What to do about #298 (comment) ?

@L2jLiga
Copy link
Contributor

L2jLiga commented Mar 7, 2019

I don't know, I guess it's a hack for old libUV and it can be deleted, not sure..

@fabiosantoscode, @kzc could you clarify?

@fabiosantoscode
Copy link
Collaborator

@hoten @L2jLiga node isn't guaranteed to output to stdout/stderr properly if you don't do that workaround. The workaround for that is to change instances of process.exit(errCod) with process.exitCode = errCod and change the code flow as necessary.

@fabiosantoscode
Copy link
Collaborator

See the code example reading "this is an example of what not to do" https://nodejs.org/api/process.html#process_process_exit_code

@connorjclark
Copy link
Contributor Author

Interesting, never ran into that before. I tweaked the exit workaround code so it'll also work within a promise context, without causing an unresolved rejection (the throw was problematic).

@connorjclark
Copy link
Contributor Author

Closing / Opening to force travis rerun. They had issues when this last ran.

@connorjclark
Copy link
Contributor Author

'istanbul' is not recognized as an internal or external command

OK, travis env is borked.

@L2jLiga
Copy link
Contributor

L2jLiga commented Mar 15, 2019

@hoten, you can tweak "test" script to exclude Istanbul call and make build green

@L2jLiga
Copy link
Contributor

L2jLiga commented Mar 17, 2019

@hoten there're conflicts after #300 and #288

@connorjclark
Copy link
Contributor Author

Resolved conflicts.

@connorjclark
Copy link
Contributor Author

Good to merge?

@fabiosantoscode
Copy link
Collaborator

I've just looked through the PR. It has some issues like generated code in test files, the fact that the exit() function is synchronous or asynchronous depending on the situation, regex-based reading of things you wouldn't normally use a regex for...

And I was adding comments one by one to outline them, but I realized the PR can't be accepted because of this:

#298 (comment)

If we're going to add this feature, it makes no sense to add it only in the CLI. The maintenance cost is too high and most people are using Terser behind another tool anyway. We can't add it to the CLI and the API at the same time, given the fact that the API is synchronous (IE Terser.minify returns an object, not a Promise). Making the Terser API asynchronous would have a huge impact on Terser users, making them use promises in scripts that might have always been synchronous. I can't push this upon them.

In conclusion, this is an amazing idea in theory, but without a real option to do a synchronous HTTP request present in node core, in practice it doesn't work.

@connorjclark
Copy link
Contributor Author

connorjclark commented Apr 15, 2019

Let's not close this just yet :) Your issues aren't unresolvable.

If we're going to add this feature, it makes no sense to add it only in the CLI.

Resolving source maps when not explicitly provided by poking around the environment (either the local filesystem or by reaching out to the web) only makes sense in the CLI. AFAICT, bin/uglifyjs is free to be as node-y as it wishes, while everything in lib (the API) must be shippable to a web context (and be synchronous).

Granted, the name auto makes less sense in isolation for the API (it's really looking up source maps in a provided map of them: options.sourceMap.contents) so perhaps auto would be better named provided (while still being automatically resolved from the CLI entry).

The maintenance cost is too high and most people are using Terser behind another tool anyway.

I disagree about the maintenance cost being high, but could you explain further?

The fact that Terser does not handle multiple source maps from multiple inputs is the exact reason this PR exists. Having this tool in my asset pipeline (well, it was uglifyjs, but still) made proper usage of source maps impossible. Good source map support is becoming very important, and Terser shouldn't ignore that.

We can't add it to the CLI and the API at the same time, given the fact that the API is synchronous (IE Terser.minify returns an object, not a Promise).

I'm not seeing the issue here. Terser.minify still returns an object in this PR. The API is still synchronous - the CLI entry point is not, but that is not the API, lib is.

Making the Terser API asynchronous would have a huge impact on Terser users, making them use promises in scripts that might have always been synchronous. I can't push this upon them.

I agree, lib should remain synchronous. But let's not stick to such standard for bin, an entry point no one should be relying on as a library, except via node bin/uglifyjs ....

In conclusion, this is an amazing idea in theory, but without a real option to do a synchronous HTTP request present in node core, in practice it doesn't work.

Thanks. But in practice, I think it will. Let's discuss further.

@connorjclark
Copy link
Contributor Author

Bumping b/c I believe I addressed your concerns in my previous comment, and believe this to be a very useful feature.

@connorjclark
Copy link
Contributor Author

gentle ping

@connorjclark
Copy link
Contributor Author

Please consider this patch again and my comments addressing your concerns.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants