diff options
author | Claudio Guglielmo | 2020-01-13 15:32:11 +0000 |
---|---|---|
committer | Claudio Guglielmo | 2020-01-30 15:11:45 +0000 |
commit | 0265fde319bec07c2db31c3ce874d2fb1cc19430 (patch) | |
tree | 9d1f745802cbd0da765f0ed6c852c3b4b6aca9d3 /eclipse-scout-cli | |
parent | 0abd5ecf457a9b795bb10fc3a9adee82133641d1 (diff) | |
download | org.eclipse.scout.rt-0265fde319bec07c2db31c3ce874d2fb1cc19430.tar.gz org.eclipse.scout.rt-0265fde319bec07c2db31c3ce874d2fb1cc19430.tar.xz org.eclipse.scout.rt-0265fde319bec07c2db31c3ce874d2fb1cc19430.zip |
Improve productive JS stack traces
If an error occurs on a productive system, it is very hard to analyze
it because the stack trace points to the minified code.
This is actually nothing new, but because of the babel transformation,
not even the method names are readable now.
To improve it, source maps are now generated in prod mode, too, but
with important differences to the ones generated in dev mode:
1. They are generated as separate files to not bloat the actual source
files -> they are only requested when the browser's dev tools are
open.
2. They contain no source code which is especially important in a
closed source project.
3. The sources array doesn't point to the real files to prevent
revealing the absolute paths (security).
Having productive source maps is only the half step. They need to
be applied before the stack is sent to the server. For this, the
tool sourcemapped-stacktrace is used. The error handler now uses it
to transform the stack trace. Because it asynchronously downloads the
source map, the error handler is now async as well.
If an error occurs, the browser logs the error to the console.
In addition, the error handler applies the source map, analyzes the
error, shows a message box, logs the mapped error to the console
and sends it to the server (existing behavior, beside the mapping).
One could stop the browser from logging the error a second time
by returning true in the onerror handler, but it actually can be
beneficial because the links from the mapped stack are not clickable
in every browser (e.g. firefox).
There is one drawback: it takes some time until the error message is
shown, before it was shown instantly.
261160
Change-Id: Iabdfb08ad9ce7f882ff44d3fb272bf4ed3af7388
Reviewed-on: https://git.eclipse.org/r/155774
Tested-by: Scout Bot <scout-bot@eclipse.org>
Tested-by: CI Bot
Reviewed-by: Claudio Guglielmo <claudio.guglielmo@bsiag.com>
Diffstat (limited to 'eclipse-scout-cli')
-rw-r--r-- | eclipse-scout-cli/scripts/webpack-defaults.js | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/eclipse-scout-cli/scripts/webpack-defaults.js b/eclipse-scout-cli/scripts/webpack-defaults.js index a1e5ed424d..1a1afcc04d 100644 --- a/eclipse-scout-cli/scripts/webpack-defaults.js +++ b/eclipse-scout-cli/scripts/webpack-defaults.js @@ -32,16 +32,41 @@ module.exports = (env, args) => { }); } + /** + * Don't reveal absolute file paths in production mode -> only return the file name relative to its module. + */ + function prodDevtoolModuleFilenameTemplate(info) { + var path = info.resourcePath || ''; + // Search for the last /src/ in the path and return the fragment starting from its parent + var result = path.match(/.*\/(.*\/src\/.*)/); + if (result) { + return result[1]; + } + // Match everything after the /last node_modules/ in the path + result = path.match(/.*\/node_modules\/(.*)/); + if (result) { + return result[1]; + } + // Return only the file name (the part after the last /) + result = path.match(/([^/\\]*)$/); + if (result) { + return result[1]; + } + } + const config = { target: 'web', mode: args.mode, - devtool: devMode ? 'inline-cheap-module-source-map' : undefined, + // In production mode create external source maps without source code to map stack traces. + // Otherwise stack traces would point to the minified source code which makes it quite impossible to analyze productive issues. + devtool: devMode ? 'inline-cheap-module-source-map' : 'nosources-source-map', output: { filename: jsFilename, path: outDir, libraryTarget: 'umd', globalObject: 'this', - umdNamedDefine: true + umdNamedDefine: true, + devtoolModuleFilenameTemplate: devMode ? undefined : prodDevtoolModuleFilenameTemplate }, performance: { hints: false @@ -90,7 +115,6 @@ module.exports = (env, args) => { compact: false, cacheDirectory: true, cacheCompression: false, - sourceMaps: devMode ? 'inline' : undefined, plugins: [ require.resolve('@babel/plugin-transform-object-assign'), require.resolve('@babel/plugin-proposal-class-properties'), @@ -135,7 +159,9 @@ module.exports = (env, args) => { scout: { // Scout may be loaded as node module or may be part of the workspace // Also make sure the regex only matches *.js files to prevent the output from mixing with css - test: /[\\/]node_modules[\\/]@eclipse-scout[\\/].*\.js|[\\/]eclipse-scout-core[\\/].*\.js|[\\/]org.eclipse.scout.rt.svg.ui.html[\\/].*\.js/, + // sourcemapped-stacktrace is included as well because it is not worth it to have a separate bundle for it. + // Adding it to vendors.js would force the users to add the vendors.js to login.html as well, which may not be desired if they have custom third party libs not required by the login.html. + test: /[\\/]node_modules[\\/]@eclipse-scout[\\/].*\.js|[\\/]eclipse-scout-core[\\/].*\.js|[\\/]org.eclipse.scout.rt.svg.ui.html[\\/].*\.js|[\\/]node_modules[\\/]sourcemapped-stacktrace[\\/].*\.js/, name: 'eclipse-scout', priority: -5, reuseExistingChunk: true, @@ -192,7 +218,6 @@ module.exports = (env, args) => { // minify js new TerserPlugin({ test: /\.js(\?.*)?$/i, - sourceMap: devMode, cache: true, parallel: true }) |