Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaudio Guglielmo2020-01-13 15:32:11 +0000
committerClaudio Guglielmo2020-01-30 15:11:45 +0000
commit0265fde319bec07c2db31c3ce874d2fb1cc19430 (patch)
tree9d1f745802cbd0da765f0ed6c852c3b4b6aca9d3 /eclipse-scout-cli
parent0abd5ecf457a9b795bb10fc3a9adee82133641d1 (diff)
downloadorg.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.js35
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
})

Back to the top