blutorange / closure-compiler-maven-plugin

Combine and minimize JavaScript with Closure Compiler.
http://blutorange.github.com/closure-compiler-maven-plugin
Apache License 2.0
52 stars 6 forks source link

closureSourceMapLocationMappings "maybe" not properly working #65

Closed OmarHawk closed 6 months ago

OmarHawk commented 6 months ago

Hi,

I'm not sure, if it is me or the plugin (or the closure compiler itself) that is not working properly, when it comes to setting a closureSourceMapLocationMapping.

I do have a project, which has the following structure where the source javascript files are located:

projectfolder/src/main/resources/javascript

and in the final artifact (running webservice), the original files are accessible behind (based on the context path)

/javascript

The minified javascript file, as well as the corresponding source map (that does work!) are located within

/scripts

folder.

If I don't define any closureSourceMapLocationMapping, within the .map file,

The map file contains sources like these (one example only):

"../../../src/main/resources/javascript/common/promotion-handler.js"

As soon, as I set it like this (or any arbitrary other setting actually - I can set every string within name/value there and it has the very same effect!)

                            <closureSourceMapLocationMappings>
                              <closureSourceMapLocationMapping>
                                <name>src/main/resources/javascript</name>
                                <value>/javascript</value>
                              </closureSourceMapLocationMapping>
                            </closureSourceMapLocationMappings>

The sources-list contains the entries like that (same example as above):

"common/promotion-handler.js"

while I actually want to have something like this:

"/javascript/common/promotion-handler.js"

I also tried just setting ../../../src/main/resources/javascriptin the name field, but that has the very same effect as the other config (or any other arbitrary config there, as mentioned above)...

Is it me and do I need to change anything in the configuration to achieve the desired result? As mentione,d the strange thing is, I can set an arbitrary value there and it has always the very same effect...

I'm using Maven 3.9.5 with JDK17 on Windows 10 and the latest plugin version (2.28.0)

blutorange commented 6 months ago

Thanks for the report. It could be closure compiler, but I won't rule out that this plugin sets some path incorrectly, I'll need to take a look later when I have time. If you have a simple sample Maven project, that would help. You could also check against the closure compiler CLI whether it produces the same or different results.

OmarHawk commented 6 months ago

I'll look to see, if I can provide a minimal example next week - unless you'd have had time by yourself then.

My workaround so far is copying via maven resources plugin the original javascript files into the place, where the source map file makes the browser expect the files now ;-)

blutorange commented 6 months ago

@OmarHawk

Ok, I finally had some time to look at this. You probably need to set the name in the source mappings relative to the sourceDir.

There is a test case here:

https://github.com/blutorange/closure-compiler-maven-plugin/blob/master/src/test/resources/projects/sourcemap/pom.xml#L82-L85

It maps files from js/ to localhost://foobar/. The source map then contains localhost://foobar/sample.js :

https://github.com/blutorange/closure-compiler-maven-plugin/blob/master/src/test/resources/projects/sourcemap/expected/location-mapping.js.map

So the value does have an effect and it outputs the value as a prefix. I suspect the issues are the paths. If the closureSourceMapLocationMapping is not set, this plugin applies the default FileSystemLocationMapping. Once closureSourceMapLocationMapping are given, it applies the given mappings instead. If the paths don't match properly, the value won't matter but it will still behave differently from when no mappings are specified.

Before the source files are passed to closure compiler, the paths are relativized against the baseDir

So if you specify the path relative to the project's base dir, it won't match. Can you perhaps try with the path relative to the sourceDir?

At least there's already a note in the readme ; )

closureSourceMapLocationMappings: When the file name of a source file contains the given prefix, it is replaced with the specified replacement. Here the file name is as it was passed to closure compiler, ie. relative to the sourceDir

OmarHawk commented 6 months ago

Well I tried, but maybe I just don't understand which path actually means what and goes where in order to achieve the desired the result.

So here is my section regarding (base)SourceDirs:

 <baseSourceDir>${basedir}/src/main/resources/</baseSourceDir>
<baseTargetDir>target/classes/</baseTargetDir>
<sourceDir>javascript/</sourceDir>
<targetDir>scripts/</targetDir>

-> The actual source files reside (viewed from pom.xml) at: ./src/main/resources/javascript/

while the final (copied) ones will be accessible relative to the source maps file at

../javascript/

I tried a few more variants (e.g. setting name to ../javascript/), but since I really didn't understand the explanation, I definetely didn't try the "right" variant.

blutorange commented 6 months ago

Your sourceDir is ${basedir}/src/main/resources/javascript. If you have a file located at ${basedir}/src/main/resources/javascript/logic/awesome.js, then logic/awesome.js will be passed to closure compile. closureSourceMapLocationMappings defines prefixes for that path, logic/awesome.js, which will be replaced with the configured value, when it starts with that prefix. So if you define the mapping logic/ => whatever/, then logic/awesome.js wil become whatever/awesome.js. If you use javascript/logic/, it won't work, since logic/awesome.js does not start with javascript/logic/.

If I understand you correctly, you don't want to replace a prefix with another value, you want to add a prefix to all paths. I.e. an empty name (which should work since version 2.30.0 of the plugin):

<closureSourceMapLocationMappings>
  <closureSourceMapLocationMapping>
    <name></name>
    <value>/javascript/</value>
  </closureSourceMapLocationMapping>
</closureSourceMapLocationMappings>

Then logic/awesome.js should be mapped to /javascript/logic/awesome.js

OmarHawk commented 6 months ago

Works like a charm. That was exactly, what we needed. Thanks a lot. :-)

blutorange commented 6 months ago

Glad it worked out!