Getting source maps working with evaluated code
Asked Answered
C

2

6

I have a build script that runs all my code through uglifyjs, does a bunch of fancy caching stuff, and ultimately runs eval( code ) on some JavaScript files.

I'm trying to get this whole process up and running with source maps, but I can't seem to get it working as long as I'm using eval. If I link to the files directly using <script src="..."> it works fine.

In my eval code, I have:

code, blah blah blah
//@ sourceMappingURL=/cache/618a67795c7460184bd9b99020cbb9fd.map

and then in that .map file, I have:

{
      "version"  : 3
    , "file"     : "618a67795c7460184bd9b99020cbb9fd.map"
    , "sources"  : ["/js/Parallax-JS/js/parallax-2.js"]
    , "names"    : [
          "a"
        , "bunch"
        , "of"
        , "variable"
        , "names"
    ]
    , "mappings" : "... LONG MAP ..."
}

I've tried putting //@ sourceURL= at the end instead, and that at least gives me the correct file name, but still no readable source.

Any ideas? Testing in Chrome 25 (dev) and 26 (canary)

Cudbear answered 17/1, 2013 at 9:13 Comment(1)
This seems to offer a solution: kybernetikos.github.io/jsSandbox/srcmaps/dynamic.html - but I want to state I did not personally try it.Dinky
A
7

I had a similar problem and the solution seem to be using an inlined SourceMaps (DataURL of a SourceMap).

Here is an example:

eval("blah blah\n//@ sourceMappingURL=data:application/json;base64,...");

Seems like you can't reference external resources from an eval.

I think you also need to use sourcesContent to insert the source code into the SourceMap.

Tested with Chrome 32.

Allomorph answered 12/2, 2014 at 12:35 Comment(3)
I'm still a bit confused. Could you provide a working jsfiddle of this? ThanksHasid
This isn't working for me. Was this a speculative answer or did you verify that it works?Chorus
This worked for me on Chrome 99.0.4844.74 for MacOS.Landloper
L
-2

Here is a setup using Grunt to compile javascript to single file using uglify with a source map

package.json

"src": {
    "js": "src/js"
},
"dest": {
    "js": "bin/js"
}

Gruntfile.js

grunt.initConfig({
    /**
     * Loading in the package file to read source and destination directories
     */
    pkg: grunt.file.readJSON('package.json'),
    uglify: {
    options: {
        banner: '/* all.min.js <%= grunt.template.today("dd-mm-yyyy") %> */\n',
        sourceMap: '<%= pkg.dest.js %>/all.min.js.map',
        sourceMappingURL: 'all.min.js.map',
        sourceMapRoot: '../../',
        mangle: false
        /*mangle: {
            except: ['jQuery']
        }*/
    },
    js: {
        src: [
            '<%= pkg.src.js %>/**/*.js'
        ],
        dest: '<%= pkg.dest.js %>/all.min.js'
    }
    }
};

grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('min', ['uglify']);

Which creates the following files:

all.min.js

/* all.min.js 04-10-2013 */
angular.module("App",[])
//# sourceMappingURL=all.min.js.map

all.min.js.map

{"version":3,"file":"bin/js/all.min.js","sources":["src/js/App.js"],"names":["angular","module"],"mappings":"AAeAA,QAAQC","sourceRoot":"../../"}
Laicize answered 24/10, 2013 at 22:8 Comment(1)
Poster explicitly asked about using source-maps when using eval. That means at runtime. Your solution deals with generating and linking source-maps at build-time, which is a known situation and not what the question is about.Dinky

© 2022 - 2024 — McMap. All rights reserved.