webpack-contrib / uglifyjs-webpack-plugin

[deprecated] UglifyJS Plugin
MIT License
1.38k stars 179 forks source link

[Source Maps] Validation warning/errors (https://sourcemaps.io/) #134

Closed webpack-bot closed 6 years ago

webpack-bot commented 7 years ago

The examples I've used are collected into a project for debugging purposes here: https://github.com/OliverJAsh/webpack-uglifyjs-source-map-issue


Given:

// package.json
{
  "private": true,
  "dependencies": {
    "webpack": "^3.6.0"
  }
}
// webpack.config.js
const webpack = require('webpack');

module.exports = {
    devtool: 'source-map',
    entry: {
        main: ['./test.js'],
    },
    output: {
        path: `${__dirname}/target`,
        filename: 'main.js',
    },
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            sourceMap: true,
        }),
    ],
};
// test.js
import foo from './foo';

foo.bar();

const x = 1;
const y = x + 1;
console.log(y);
// foo.js
module.exports = {
    bar: function () {},
};

When I run webpack and use https://sourcemaps.io/ to validate the source map, I get 83 warnings:

image

If I switch from using the default import to importing the whole module:

// test.js
import * as foo from './foo';

foo.bar();

const x = 1;
const y = x + 1;
console.log(y);

… and then I validate the source map, I get 1 error and 81 warnings:

image

If I remove UglifyJsPlugin altogether, the source map has no warnings or errors.

This could be the validator reporting false positives, although I believe I am also seeing issues resolving stack traces against the source map, so I have reason to believe these are not false positives.


This issue was moved from webpack/webpack#5728 by @sokra. Orginal issue was by @OliverJAsh.

sokra commented 7 years ago

Could you try the latest version for the uglifyjs-webpack-plugin?

OliverJAsh commented 7 years ago

Hi @sokra. I just gave the latest beta (v1.0.0-beta.2) and stable (v0.4.6) a go and still got 83 warnings, as described above.

Minimal test cases for beta and stable:

https://github.com/OliverJAsh/webpack-uglifyjs-source-map-issue/tree/uglifyjs-webpack-plugin-beta https://github.com/OliverJAsh/webpack-uglifyjs-source-map-issue/tree/uglifyjs-webpack-plugin-stable

kzc commented 7 years ago

The issue is that webpack is producing a low ~quality~ resolution line-based source map as an input to uglify.

If you remove the uglify plugin from the webpack config:

const webpack = require('webpack');

module.exports = {
    devtool: 'source-map',
    entry: {
        main: ['./test.js'],
    },
    output: {
        path: `${__dirname}/no-uglify`,
        filename: 'main.js',
    },
    plugins: [
    ],
};

and re-run webpack it will produce a main.js.map file that looks like this (reformatted):

{
    "version": 3,
    "sources": [
        "webpack:///webpack/bootstrap f8a24624490861a08fdb",
        "webpack:///./test.js",
        "webpack:///./foo.js"
    ],
    "names": [],
    "mappings": ";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;AC7DA;;AAEA;;AAEA;AACA;AACA;;;;;;;ACNA;AACA,uBAAuB;AACvB",
    "file": "main.js",
    "sourcesContent": [
        " \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap f8a24624490861a08fdb",
        "import foo from './foo';\n\nfoo.bar();\n\nconst x = 1;\nconst y = x + 1;\nconsole.log(y);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./test.js\n// module id = 1\n// module chunks = 0",
        "module.exports = {\n    bar: function () {},\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./foo.js\n// module id = 2\n// module chunks = 0"
    ],
    "sourceRoot": ""
}

Here is that webpack generated source map in a source map visualizer.

By contrast using Rollup with the following config:

$ cat rollup.config.js 

import commonjs from 'rollup-plugin-commonjs';
export default {
    input: 'test.js',
    plugins: [
        commonjs(),
    ],
    sourcemap: true,
    output: {
        file: 'target-rollup/bundle.js',
        format: 'es',
    },
}
$ node_modules/.bin/rollup -c rollup.config.js

test.js → target-rollup/bundle.js...
created target-rollup/bundle.js in 38ms

will produce a high resolution source map (reformatted):

{
    "version": 3,
    "file": "bundle.js",
    "sources": [
        "../foo.js",
        "../test.js"
    ],
    "sourcesContent": [
        "module.exports = {\n    bar: function () {},\n};\n",
        "import foo from './foo';\n\nfoo.bar();\n\nconst x = 1;\nconst y = x + 1;\nconsole.log(y);\n"
    ],
    "names": [],
    "mappings": "AAAA,OAAc,GAAG;IACb,GAAG,EAAE,YAAY,EAAE;CACtB;;ACAD,GAAG,CAAC,GAAG,EAAE,CAAC;;AAEV,MAAM,CAAC,GAAG,CAAC,CAAC;AACZ,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAChB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC"
}

which looks like this in the source map visualizer.

OliverJAsh commented 7 years ago

Hey @kzc

Thanks for looking into this!

The issue is that webpack is producing a low quality line-based source map as an input to uglify.

Can you elaborate? Why is this causing validation errors/warnings?

Does the Rollup output validate without errors/warnings?

kzc commented 7 years ago

Can you elaborate? Why is this causing validation errors/warnings?

Notice that Rollup produces high resolution source mappings at the symbol level.

Webpack (with your config anyway) generates line-based mappings. It would appear that it negatively impacts uglify's ability to accurately map the transformed code. Perhaps there is an equivalent webpack setting to generate high resolution source maps comparable to Rollup - I don't know.

Does the Rollup output validate without errors/warnings?

I don't know anything about that validator or whether it is accurate. Feel free to try it on the Rollup results and post it here.

alexander-akait commented 6 years ago

Closing due to inactivity. Please test with latest version and feel free to recreate issue if still regressions. Thanks!

ijongkim commented 6 years ago

I am experiencing the same issue. If I remove UglifyJS the generated source maps pass validation, if I include it source maps become invalid. Is using Rollup to generate source maps the only viable solution?

alexander-akait commented 6 years ago

@ijongkim can you create niew issue with reproducible test repo