Skip to content

Commit a010f2e

Browse files
authored
feat: Async Loader example with tests and docs (#1334)
* feat: Async Loader with tests * loader: Added simple build step * loader: Async loading documentation * loader: Use CDN and DSN dynamic variables * loader: Defend users from ASI magic and update docs
1 parent c2e3977 commit a010f2e

17 files changed

+408
-351
lines changed

docs/install.rst

+39-8
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ So for example:
88

99
.. sourcecode:: html
1010

11-
<script src="jquery.js"></script>
12-
<script src="https://cdn.ravenjs.com/###RAVEN_VERSION###/raven.min.js" crossorigin="anonymous"></script>
13-
<script>Raven.config('___PUBLIC_DSN___').install();</script>
14-
<script src="app.js"></script>
11+
<script src="jquery.js"></script>
12+
<script src="https://cdn.ravenjs.com/###RAVEN_VERSION###/raven.min.js" crossorigin="anonymous"></script>
13+
<script>Raven.config('___PUBLIC_DSN___').install();</script>
14+
<script src="app.js"></script>
1515

1616
This allows the ability for Raven's integrations to instrument themselves. If
1717
included before something like Angular, it'd be impossible to use for
@@ -28,7 +28,7 @@ Our CDN distributes builds with and without :doc:`integrations <integrations/ind
2828

2929
.. sourcecode:: html
3030

31-
<script src="https://cdn.ravenjs.com/###RAVEN_VERSION###/raven.min.js" crossorigin="anonymous"></script>
31+
<script src="https://cdn.ravenjs.com/###RAVEN_VERSION###/raven.min.js" crossorigin="anonymous"></script>
3232

3333
This version does not include any plugins. See `ravenjs.com
3434
<http://ravenjs.com/>`_ for more information about plugins and getting
@@ -45,11 +45,11 @@ add it to ``bower.json``).
4545

4646
.. code-block:: sh
4747
48-
$ bower install raven-js --save
48+
$ bower install raven-js --save
4949
5050
.. code-block:: html
5151

52-
<script src="/bower_components/raven-js/dist/raven.js"></script>
52+
<script src="/bower_components/raven-js/dist/raven.js"></script>
5353

5454
Also note that the file is uncompresed but is ready to pass to any decent
5555
JavaScript compressor like `UglifyJS
@@ -63,7 +63,7 @@ Raven is also available as an npm package, `raven-js
6363

6464
.. code-block:: sh
6565
66-
$ npm install raven-js --save
66+
$ npm install raven-js --save
6767
6868
.. code-block:: html
6969

@@ -96,6 +96,37 @@ To use Raven with ES2015 (ES6) imports:
9696
.config('___PUBLIC_DSN___')
9797
.install();
9898
99+
Async Loading
100+
~~~~~~~~~~~~~
101+
102+
To load Sentry JS SDK asynchronously, you need to do two things.
103+
104+
Provide global ``SENTRY_SDK`` variable with SDK's URL (for example from our CDN), your DSN and SDK's configuration.
105+
And place the snippet below as soon as possible in your HTML code. For example:
106+
107+
.. code-block:: html
108+
109+
<script>
110+
window.SENTRY_SDK = {
111+
url: 'https://cdn.ravenjs.com/###RAVEN_VERSION###/raven.min.js',
112+
dsn: '___PUBLIC_DSN___',
113+
options: {
114+
release: '1.3.0'
115+
}
116+
}
117+
118+
;(function(a,b,g,e,h){var k=a.SENTRY_SDK,f=function(a){f.data.push(a)};f.data=[];var l=a[e];a[e]=function(c,b,e,d,h){f({e:[].slice.call(arguments)});l&&l.apply(a,arguments)};var m=a[h];a[h]=function(c){f({p:c.reason});m&&m.apply(a,arguments)};var n=b.getElementsByTagName(g)[0];b=b.createElement(g);b.src=k.url;b.crossorigin="anonymous";b.addEventListener("load",function(){try{a[e]=l;a[h]=m;var c=f.data,b=a.Raven;b.config(k.dsn,k.options).install();var g=a[e];if(c.length)for(var d=0;d<c.length;d++)c[d].e?g.apply(b.TraceKit,c[d].e):c[d].p&&b.captureException(c[d].p)}catch(p){console.log(p)}});n.parentNode.insertBefore(b,n)})(window,document,"script","onerror","onunhandledrejection");
119+
</script>
120+
121+
Or you can place those two things in a separate script tags. This will queue all errors (and promises if the environment supports ``unhandledrejection`` handler) that happened before SDK was loaded and send them once it's configured and installed.
122+
123+
Be aware however, that there are some trade-offs to this solution, as errors might provide less information due to them being "retriggered" instead of being caught from the original source.
124+
125+
NOTE: This won't work when opening ``index.html`` or any other html file from the file system, as it doesn't support anonymous cross-origin scripts.
126+
The same thing can happen for any cross-origin scripts as well. To read more about it, see `What the heck is "Script error"?<https://blog.sentry.io/2016/05/17/what-is-script-error>`_.
127+
128+
To read un-minified source code for this loader, see `loader.js<https://github.com/getsentry/raven-js/blob/master/src/loader.js>`_
129+
99130
Requirements
100131
~~~~~~~~~~~~
101132

karma.sauce.config.js

-117
This file was deleted.

karma.unit.config.js

-13
This file was deleted.

karma.config.js renamed to karma/karma.config.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
module.exports = {
55
// base path that will be used to resolve all patterns (eg. files, exclude)
6-
basePath: '',
6+
basePath: '../',
77

88
// frameworks to use
99
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
@@ -58,9 +58,12 @@ module.exports = {
5858
}
5959
},
6060

61+
// https://docs.travis-ci.com/user/gui-and-headless-browsers/#Karma-and-Firefox-inactivity-timeouts
62+
browserNoActivityTimeout: 30000,
63+
6164
// Continuous Integration mode
6265
// if true, Karma captures browsers, runs the tests and exits
63-
singleRun: false,
66+
singleRun: true,
6467

6568
// Concurrency level
6669
// how many browser should be started simultaneous
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
var commonSauceConfig = require('./karma.sauce.config');
2+
var files = require('./karma.integration.config').files;
3+
4+
module.exports = function(config) {
5+
var testConfig = Object.assign({}, commonSauceConfig, {
6+
logLevel: config.LOG_INFO,
7+
files: files.concat(['build/raven.test.js'])
8+
});
9+
config.set(testConfig);
10+
};

karma.integration.config.js renamed to karma/karma.integration.config.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ var testFiles = [
99
{pattern: 'test/integration/throw-object.js', included: false},
1010
{pattern: 'test/integration/example.json', included: false},
1111
{pattern: 'test/integration/frame.html', included: false},
12-
'test/integration/test.js',
13-
'test/globals.js',
14-
'build/raven.js',
12+
{pattern: 'build/raven.js', included: false},
13+
'test/integration/test.js'
1514
];
1615

1716
module.exports = function(config) {
1817
var testConfig = Object.assign({}, commonConfig, {files: testFiles});
1918
config.set(testConfig);
2019
};
20+
21+
module.exports.files = testFiles;

karma/karma.loader-sauce.config.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
var commonSauceConfig = require('./karma.sauce.config');
2+
var files = require('./karma.loader.config').files;
3+
4+
module.exports = function(config) {
5+
var testConfig = Object.assign({}, commonSauceConfig, {
6+
logLevel: config.LOG_INFO,
7+
files: files
8+
});
9+
config.set(testConfig);
10+
};

karma/karma.loader.config.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
var commonConfig = require('./karma.config');
2+
3+
var testFiles = [
4+
{pattern: 'node_modules/es6-promise/dist/es6-promise.auto.js', included: false},
5+
{pattern: 'test/integration/loader.html', included: false},
6+
{pattern: 'build/raven.js', included: false},
7+
{pattern: 'src/loader.js', included: false},
8+
'test/integration/loader-test.js'
9+
];
10+
11+
module.exports = function(config) {
12+
var testConfig = Object.assign({}, commonConfig, {files: testFiles});
13+
config.set(testConfig);
14+
};
15+
module.exports.files = testFiles;

karma/karma.sauce.config.js

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
var commonConfig = require('./karma.config');
2+
3+
var customLaunchers = {
4+
sl_chrome: {
5+
base: 'SauceLabs',
6+
browserName: 'chrome',
7+
platform: 'Windows 10',
8+
version: 'latest'
9+
},
10+
sl_firefox: {
11+
base: 'SauceLabs',
12+
browserName: 'firefox',
13+
platform: 'Windows 10',
14+
version: 'latest'
15+
},
16+
sl_edge: {
17+
base: 'SauceLabs',
18+
browserName: 'microsoftedge',
19+
version: 'latest',
20+
platform: 'Windows 10'
21+
},
22+
sl_ie_11: {
23+
base: 'SauceLabs',
24+
browserName: 'internet explorer',
25+
platform: 'Windows 7',
26+
version: '11'
27+
},
28+
sl_ie_10: {
29+
base: 'SauceLabs',
30+
browserName: 'internet explorer',
31+
platform: 'Windows 7',
32+
version: '10'
33+
},
34+
sl_safari: {
35+
base: 'SauceLabs',
36+
browserName: 'safari',
37+
platform: 'OS X 10.12',
38+
version: '11.0'
39+
},
40+
sl_ios: {
41+
base: 'SauceLabs',
42+
browserName: 'iphone',
43+
platform: 'OS X 10.12',
44+
version: '11.0'
45+
},
46+
sl_android_7: {
47+
base: 'SauceLabs',
48+
browserName: 'Chrome',
49+
platform: 'Android',
50+
version: '7.1',
51+
device: 'Android GoogleAPI Emulator'
52+
},
53+
sl_android_6: {
54+
base: 'SauceLabs',
55+
browserName: 'Chrome',
56+
platform: 'Android',
57+
version: '6.0',
58+
device: 'Android Emulator'
59+
},
60+
sl_android_5: {
61+
base: 'SauceLabs',
62+
browserName: 'android',
63+
platform: 'Linux',
64+
version: '5.1'
65+
},
66+
sl_android_4: {
67+
base: 'SauceLabs',
68+
browserName: 'android',
69+
platform: 'Linux',
70+
version: '4.4'
71+
}
72+
};
73+
74+
module.exports = Object.assign({}, commonConfig, {
75+
customLaunchers: customLaunchers,
76+
browsers: Object.keys(customLaunchers),
77+
reporters: ['failed', 'saucelabs'],
78+
singleRun: true,
79+
plugins: commonConfig.plugins.concat(['karma-sauce-launcher']),
80+
build: process.env.TRAVIS_BUILD_NUMBER,
81+
// SauceLabs allows for 2 tunnels only, therefore some browsers will have to wait
82+
// rather long time. Plus mobile emulators tend to require a lot of time to start up.
83+
// 10 minutes should be more than enough to run all of them.
84+
browserNoActivityTimeout: 600000,
85+
captureTimeout: 600000,
86+
sauceLabs: {
87+
startConnect: false,
88+
// Just something "random" so we don't have to provide additional ENV var when running locally
89+
tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER || Math.ceil(Math.random() * 1337),
90+
recordScreenshots: false,
91+
recordVideo: false,
92+
testName:
93+
'Raven.js' +
94+
(process.env.TRAVIS_JOB_NUMBER ? ' #' + process.env.TRAVIS_JOB_NUMBER : ''),
95+
public: 'public'
96+
}
97+
});

0 commit comments

Comments
 (0)