-
-
Notifications
You must be signed in to change notification settings - Fork 835
Expand file tree
/
Copy pathupdateSelectorEngine.ts
More file actions
105 lines (93 loc) · 3.46 KB
/
updateSelectorEngine.ts
File metadata and controls
105 lines (93 loc) · 3.46 KB
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
import cp from 'node:child_process';
import fs from 'node:fs/promises';
import path from 'node:path';
/**
* This script updates the JQuery selector engine for the mock-doc package
* to the latest version.
*
* To run it, use the following command:
* ```sh
* npm run tsc.scripts
* npm run build.updateSelectorEngine
* ```
*/
const rootDir = path.resolve(__dirname, '..');
const jqueryDepDir = path.resolve(rootDir, 'node_modules', 'jquery');
const WINDOW_MOCK = `{
document: {
createElement() {
return {};
},
nodeType: 9,
documentElement: {
nodeType: 1,
nodeName: 'HTML'
}
}
}`;
async function run() {
console.log('updating JQuery Selector engine...');
await runCommand(`npm install --ignore-scripts`, jqueryDepDir);
await runCommand(`npm run build -- --include=selector`, jqueryDepDir);
const jqueryPkgJSON = JSON.parse(await fs.readFile(path.resolve(jqueryDepDir, 'package.json'), 'utf8'));
const thirdPartyDir = path.resolve(__dirname, '../../src/mock-doc/third-party');
await fs.mkdir(thirdPartyDir, { recursive: true });
const originalContent = await fs.readFile(path.resolve(jqueryDepDir, 'dist', 'jquery.js'), 'utf8');
/**
* This is a hack to make the jQuery selector engine work with the mock-doc package.
* Using the original jQuery bundle would cause a "RegExpCompiler Allocation failed - process out of memory"
* error due to the way the jQuery object is constructed. The following tweaks to the jQuery bundle
* resolve the issue:
*/
const fixedJQuery = originalContent
/**
* Never run the short-circuiting code due to usage of too many RegExp objects
*/
.replace('if ( !seed ) {', 'if ( false ) {')
/**
* Make jQuery an object to have it garbage collected
*/
.replace('var version = "', `const jQuery = {} as { find: Function };\nvar version = "`)
/**
* Inject window mock directly into iife
*/
.replace(`typeof window !== "undefined" ? window : this`, WINDOW_MOCK)
/**
* Rename the original jQuery function to jQueryOrig
*/
.replace('jQuery = function( selector, context ) {', 'jQueryOrig = function( selector, context ) {')
/**
* Replace use of `jQuery.attr` with `elem.getAttribute` to avoid having to include
* the attributes plugin to the bundle
*/
.replace('jQuery.attr( elem, name )', 'elem.getAttribute( name )')
/**
* make it return jQuery directly rather than relying on a module system
*/
.replace('module.exports = factory( global, true );', 'return factory( global, true );')
.replace('if ( typeof module === "object" && typeof module.exports === "object" ) {', 'if (true) {');
const newContent = `/* eslint-disable */
// @ts-nocheck
/**
* ATTENTION: DO NOT MODIFY THIS FILE
*
* This file is generated by "scripts/updateSelectorEngine.ts" and can be overwritten
* at any time. Don't make changes in here as they will get lost!
*/
export default ${fixedJQuery};
`;
fs.writeFile(path.resolve(thirdPartyDir, 'jquery.ts'), newContent, 'utf8');
console.log(`\nJQuery Selector engine updated to version ${jqueryPkgJSON.version}`);
console.log(`at ${thirdPartyDir} 🎉`);
}
function runCommand(cmd: string, cwd: string) {
return new Promise((resolve, reject) => {
console.log(`> ${cmd}`);
const child = cp.spawn(cmd, { cwd, shell: true });
child.on('error', reject);
child.on('exit', (code) => (code === 0 ? resolve(child) : reject()));
});
}
if (require.main === module) {
run();
}