forked from borisirota/webworkify-webpack
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
117 lines (100 loc) · 5.06 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
var __webpack_require__ = arguments[2];
var sources = __webpack_require__.m;
var ENTRY_MODULE = __webpack_require__.s || "0";
// In webpack 2 the moduleId property is called `i` instead of `id`.
var webworkifyWebpackModuleId = arguments[0].id || arguments[0].i;
var webpackBootstrapFunc = function(modules) {
var installedModules = {};
function __webpack_require__(moduleId) {
if(installedModules[moduleId])
return installedModules[moduleId].exports;
var module = installedModules[moduleId] = {
exports: {},
id: moduleId,
loaded: false
};
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
module.loaded = true;
return module.exports;
}
__webpack_require__.m = modules;
__webpack_require__.c = installedModules;
__webpack_require__.oe = function(err) { throw err; };
__webpack_require__.p = "";
var f = __webpack_require__(__webpack_require__.s = entryModule);
return f.default || f; // try to call default if defined to also support babel esmodule exports
}
// http://stackoverflow.com/a/2593661/130442
function quoteRegExp(str) {
return (str+'').replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&");
}
module.exports = function (fn, options) {
var moduleWrapperStrings = [];
var potentialFnModuleIds = [ENTRY_MODULE];
var sourcesKeys = Object.keys(sources); // when using the CommonChunks plugin, webpacl sometimes storing sources in object instead of array
// first, find the modules that required webworkify-webpack, and note their requires so that we can limit the number of potential duplicate matches
// while we're at it, save the string version for use later
var key;
for (var i = 0, l = sourcesKeys.length; i < l; i++) {
var k = sourcesKeys[i];
if (!sources[k]) {
continue;
}
var wrapperFuncString = sources[k].toString();
moduleWrapperStrings[k] = wrapperFuncString;
// __webpack_require__ is the third argument passed to the wrapper function, but it may have been renamed by minification
var wrapperSignature = wrapperFuncString.match(/^function\s?\(\w+,\s*\w+,\s*(\w+)\)/);
if (!wrapperSignature) {
// no matches means the module doesn't use __webpack_require__, and we can skip it entirely
continue;
}
var webpackRequireName = wrapperSignature[1];
if (wrapperFuncString.indexOf(webpackRequireName + '(' + webworkifyWebpackModuleId + ')') > -1) {
// find all calls that look like __webpack_require__(\d+), and aren't webworkify-webpack
var re = new RegExp(quoteRegExp(webpackRequireName) + '\\((\\d+)\\)', 'g');
var match;
while (match = re.exec(wrapperFuncString)) {
if (match[1] != ('' + webworkifyWebpackModuleId)) {
potentialFnModuleIds.push(match[1]);
}
}
}
}
var fnString = fn.toString()
// FF adds a "use strict"; to the function body
.replace(/"use strict";\n\n/, '');
var fnStringNoSpace = fnString
.replace(/^function\s?\((.*)\)(\s?)\{(\n"use strict";\n)?/, 'function($1)$2{');
var fnStringWithSpace = fnString
.replace(/^function\s?\((.*)\)(\s?)\{(\n"use strict";\n)?/, 'function ($1)$2{');
// find the first moduleId from the above list that contains fnString
var key = potentialFnModuleIds.find(function (moduleId) {
var wrapperFuncString = sources[moduleId].toString();
if (wrapperFuncString.indexOf(fnStringNoSpace) > -1 || wrapperFuncString.indexOf(fnStringWithSpace) > -1) {
var exp = __webpack_require__(moduleId);
// Using babel as a transpiler to use esmodule, the export will always
// be an object with the default export as a property of it. To ensure
// the existing api and babel esmodule exports are both supported we
// check for both
if (!(exp && (exp === fn || exp.default === fn))) {
moduleWrapperStrings[moduleId] = wrapperFuncString.substring(0, wrapperFuncString.length - 1) + '\n' + fnString.match(/function\s?(.+?)\s?\(.*/)[1] + '();\n}';
}
return true;
}
return false;
});
if (typeof key === 'undefined') {
throw new Error('webworkify-webpack: Could not locate module containing worker function! Make sure you aren\'t using eval sourcemaps and that you pass named functions to webworkify-webpack!');
}
var src = 'var fn = (' + webpackBootstrapFunc.toString().replace('entryModule', key) + ')(['
+ moduleWrapperStrings.join(',')
+ ']);\n'
+ '(typeof fn === "function") && fn(self);'; // not a function when calling a function from the current scope
var blob = new Blob([src], { type: 'text/javascript' })
if (options && options.bare) { return blob; }
var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
var workerUrl = URL.createObjectURL(blob);
var worker = new Worker(workerUrl);
worker.objectURL = workerUrl;
return worker;
};