This repository has been archived by the owner on Aug 5, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 38
/
webpack.js
131 lines (107 loc) · 3.9 KB
/
webpack.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
'use strict'
var STORE
function OpenRecordCachePlugin(store) {
this.store = store
STORE = store
}
class OpenRecordCacheInfusionDependency {
constructor(range, value, store) {
if(!Array.isArray(range)) throw new Error('range must be valid')
this.range = range
this.value = value
this.store = store
}
// methods needed by webpack
updateHash() {}
getWarnings() {
return null
}
getErrors() {
return null
}
getResourceIdentifier(){
return null;
}
getReference() {
return null
}
disconnect(){}
}
OpenRecordCacheInfusionDependency.Template = class OpenRecordCacheInfusionDependencyTemplate {
apply(dep, source) {
const before = [dep.range[0], dep.range[1] - 1] // => `require` call
const after = [dep.range[1] - 1 + dep.value.length + 5, dep.range[1] - 1 + dep.value.length + 5] // => the position after `require('openrecord....')``
// create a new constructor, add the cache to the config and call the original constructor
const beforeCode = [
'function CacheInfusedStore(config){',
'config = config || {}',
'config.cache = ' + JSON.stringify(dep.store.cache) + ';',
'return new '
].join('\n')
const afterCode = ['(config)', '}'].join('\n')
/*
BECOMES:
function CacheInfusedStore(config){
config = config || {}
config.cache = {...}
return new __webpack_require(1)(config)
}
*/
source.replace(before[0], before[1], beforeCode)
source.replace(after[0], after[1], afterCode)
}
}
OpenRecordCachePlugin.prototype.apply = function(compiler) {
var store = STORE
function compilation(compilation, params) {
compilation.dependencyFactories.set(OpenRecordCacheInfusionDependency, params.normalModuleFactory)
compilation.dependencyTemplates.set(OpenRecordCacheInfusionDependency, new OpenRecordCacheInfusionDependency.Template())
function parser(parser){
function callRequire(node){
// and check if 'openrecord' or 'openrecord/store/...' was required
if(node.arguments[0] && node.arguments[0].value && node.arguments[0].value.match(/^openrecord($|\/store\/)/)){
// now we do the fancy webpack dance
const dep = new OpenRecordCacheInfusionDependency(node.callee.range, node.arguments[0].value, store)
dep.loc = node.loc
dep.request = node.arguments[0].value // actually I don't know where request comes, but it's the file name/relative path of the required file in webpack code
parser.state.current.addDependency(dep)
}
}
// currently we search only for require calls
if(parser.hooks){
parser.hooks.call.for('require').tap('require', callRequire)
}else{
parser.plugin('call require', callRequire)
}
}
if(params.normalModuleFactory.hooks){
// from https://github.com/webpack/webpack/blob/master/lib/DefinePlugin.js
params.normalModuleFactory.hooks.parser.for("javascript/auto").tap('parser', parser)
params.normalModuleFactory.hooks.parser.for("javascript/dynamic").tap('parser', parser)
params.normalModuleFactory.hooks.parser.for("javascript/esm").tap('parser', parser)
}else{
params.normalModuleFactory.plugin('parser', parser)
}
}
function run(compiler, callback) {
store.ready().then(function(){
if(typeof callback === 'function') callback()
})
}
function done(stats, callback){
if(store.close) store.close()
if(typeof callback === 'function') callback()
}
if(compiler.hooks){
compiler.hooks.compilation.tap('openrecord', compilation)
compiler.hooks.run.tapAsync('openrecord', run)
// compiler.hooks.emit.tapAsync('openrecord', emit)
compiler.hooks.done.tapAsync('openrecord', done)
}else{
compiler.plugin('compilation', compilation)
compiler.plugin('run', run)
// compiler.plugin('emit', emit)
compiler.plugin('done', done)
}
}
module.exports = OpenRecordCachePlugin