Skip to content

Commit 813565a

Browse files
committed
electron native build
1 parent 77a01f8 commit 813565a

File tree

4 files changed

+145
-68
lines changed

4 files changed

+145
-68
lines changed

cfx.md

Lines changed: 138 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,6 @@ After many tests, the proxy based solutions (naive, FlairSolverr) don't really w
2222
* rewrite leetcode-cli to replace request with modified node-libcurl
2323
* update the vscode leetcode plugin(extension) to use the enhanced leetcode-cli plugin
2424

25-
Finally, we use the curl_chrome116 command line + exec as the solution, because the NODE_MODULE_VERSION incompatibility issue in vscode. The vscode itself is built by electron, but we build the modified version of node-libcurl with node (18.12.0). Although in vscode leetcode extension, it spawns a separate node process (18.12.0) to run the underlying leetcode commands, we still got the NODE_MODULE_VERSION error.
26-
27-
```
28-
const childProc = wsl.useWsl()
29-
? cp.spawn("wsl", [leetCodeExecutor_1.leetCodeExecutor.node, leetCodeBinaryPath, "user", commandArg], { shell: true })
30-
: cp.spawn(leetCodeExecutor_1.leetCodeExecutor.node, [leetCodeBinaryPath, "user", commandArg], {
31-
shell: true,
32-
env: cpUtils_1.createEnvOption(),
33-
});
34-
35-
this.executeCommandEx(this.nodeExecutable, [yield this.getLeetCodeBinaryPath(), "plugin", "-e", plugin]);
36-
```
37-
3825
### Install curl-impersonate
3926
Refer to [INSTALL.md](https://github.com/lwthiker/curl-impersonate/blob/main/INSTALL.md#macos)
4027
+ install prebuild binary through brew
@@ -71,10 +58,146 @@ cd ../ && rm -Rf build
7158

7259
### Compile node-libcurl with curl-impersonate
7360
Build node-libcurl from source on macOS
74-
```
7561

62+
#### Option 1: node-libcurl (using lib/util2.js)
63+
build node-libcurl from source in two versions, one version is using node 18.12.0 (match to the version in vscode leetcode extension settings), the other one is using electron 27.3.6 (match to the vscode based electron version). copy two versions to different locations, and we won't hit the NODE_MODULE_VERSION incompatibility error!
64+
```
7665
# install the build tool node-gyp
7766
npm i -g node-pre-gyp node-gyp
67+
68+
# install electron 27.3.6, check https://releases.electronjs.org/ for electron versions
69+
# we need NODE_MODULE_VERSION 118 corresponded electron version
70+
npm i -g electron@v27.3.6
71+
72+
# verify the electron version
73+
➜ electron -v
74+
v27.3.6
75+
76+
# copy /usr/bin/curl-config to /usr/local/bin/curl-config
77+
# and make sure /usr/local/bin is before /usr/bin in PATH
78+
# then modify /usr/local/bin/curl-config and update prefix from /usr to /usr/local/opt/curl
79+
# to avoid clang: error: no such file or directory: '/usr/include'
80+
cp /usr/bin/curl-config /usr/local/bin/curl-config
81+
82+
# build electron version(NODE_MODULE_VERSION 118) node-libcurl
83+
HOME=~/.electron-gyp npm_config_runtime=electron npm_config_target=27.3.6 npm_config_target_arch=x64 npm_config_arch=x64 npm_config_build_from_source=true npm_config_disturl=https://www.electronjs.org/headers yarn add node-libcurl
84+
# check node_libcurl.node
85+
➜ ll node_modules/node-libcurl/lib/binding/node_libcurl.node
86+
➜ otool -L node_modules/node-libcurl/lib/binding/node_libcurl.node
87+
node_modules/node-libcurl/lib/binding/node_libcurl.node:
88+
@rpath/libcurl.dylib (compatibility version 13.0.0, current version 13.0.0)
89+
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1600.157.0)
90+
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1336.61.1)
91+
92+
# verify the libcurl (using node will get NODE_MODULE_VERSION incompatible error)
93+
electron curl/lc.js
94+
95+
# copy node-libcurl to vscode leetcode extension
96+
cp -a node_modules/node-libcurl ~/.vscode/extensions/leetcode.vscode-leetcode-0.18.1/node_modules/
97+
98+
# build node version(NODE_MODULE_VERSION 108) node-libcurl
99+
npm_config_build_from_source=true yarn add node-libcurl
100+
101+
# check node_libcurl.node
102+
➜ ll node_modules/node-libcurl/lib/binding/node_libcurl.node
103+
➜ otool -L node_modules/node-libcurl/lib/binding/node_libcurl.node
104+
node_modules/node-libcurl/lib/binding/node_libcurl.node:
105+
@rpath/libcurl.dylib (compatibility version 13.0.0, current version 13.0.0)
106+
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1600.157.0)
107+
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1336.61.1)
108+
109+
# verify the libcurl
110+
node curl/lc.js
111+
./lc show 164 -x
112+
113+
# copy node-libcurl to the embedded leetcode of vscode leetcode extension
114+
# ignore this if using symbolic link
115+
cp -a node_modules/node-libcurl ~/.vscode/extensions/leetcode.vscode-leetcode-0.18.1/node_modules/vsc-leetcode-cli/node_modules/
116+
# or do a link, replace ~/test/leetcode-cli with your leetcode-cli working directory
117+
cd ~/.vscode/extensions/leetcode.vscode-leetcode-0.18.1/node_modules
118+
mv vsc-leetcode-cli vsc-leetcode-clix
119+
ln -s ~/test/leetcode-cli vsc-leetcode-cli
120+
121+
# DONE! Goto vscode and reload the window, the leetcode extension should work now!
122+
```
123+
124+
#### Option 2: exec + curl_chrome116 (using lib/util1.js)
125+
Alternatively, we can use exec to execute curl_chrome116 to avoid below NODE_MODULE_VERSION compatibility issue for native build lib like node-libcurl! Follow the steps in [Option 1](#option-1-node-libcurl-using-libutil2js) except those related to electron!
126+
```
127+
Failed to list problems: Error: The module '/Users/harry/.vscode/extensions/leetcode.vscode-leetcode-0.18.1/node_modules/vsc-leetcode-cli/node_modules/node-libcurl/lib/binding/node_libcurl.node' was compiled against a different Node.js version using NODE_MODULE_VERSION 108. This version of Node.js requires NODE_MODULE_VERSION 118. Please try re-compiling or re-installing the module (for instance, using `npm rebuild` or `npm install`)..
128+
```
129+
130+
### Test Conclusion
131+
| Not working | Working |
132+
| ----------- | ----------- |
133+
| original node-libcurl | curl-impersonate |
134+
| naive proxy | node exec + curl-impersonate |
135+
| | modified node-libcurl |
136+
137+
### TODO
138+
139+
### Update the vscode leetcode extension
140+
See the manual steps of copying, linking folders in [Option 1](#option-1-node-libcurl-using-libutil2js)
141+
142+
### References
143+
- [Could not login with both 'leetcode user -l' and 'leetcode user -c'](https://github.com/skygragon/leetcode-cli/issues/218)
144+
- [Cannot login with premium account](https://github.com/skygragon/leetcode-cli/issues/194)
145+
- [Failed to log in with a leetcode.com account](https://github.com/LeetCode-OpenSource/vscode-leetcode/issues/478), [a comment](https://github.com/LeetCode-OpenSource/vscode-leetcode/issues/478#issuecomment-564757098)
146+
- Proxy Server to bypass Cloudflare: [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr), [naiveproxy](https://github.com/klzgrad/naiveproxy)
147+
- [How To Bypass Cloudflare in 2024](https://scrapeops.io/web-scraping-playbook/how-to-bypass-cloudflare/)
148+
- [How to Bypass Cloudflare in 2024: The 8 Best Methods](https://www.zenrows.com/blog/bypass-cloudflare)
149+
- [How to bypass Cloudflare when web scraping in 2024](https://scrapfly.io/blog/how-to-bypass-cloudflare-anti-scraping/)
150+
- [node abi versions](https://github.com/nodejs/node/blob/main/doc/abi_version_registry.json)
151+
- https://github.com/lwthiker/curl-impersonate
152+
- https://github.com/lwthiker/curl-impersonate#libcurl-impersonate
153+
- https://github.com/lwthiker/curl-impersonate/issues/80#issuecomment-1166192854
154+
- https://github.com/JCMais/node-libcurl?tab=readme-ov-file#building-on-macos
155+
- https://www.electronjs.org/docs/latest/tutorial/using-native-node-modules
156+
- build node-libcurl [with electron](https://github.com/JCMais/node-libcurl?tab=readme-ov-file#electron-aka-atom-shell)
157+
158+
### Questions ?
159+
- How does macOS load /usr/lib/libcurl.4.dylib (8.4.0) or @rpath/libcurl.dylib (8.1.1) at runtime?
160+
```
161+
# otool -L node_modules/node-libcurl/lib/binding/node_libcurl.node
162+
shows libcurl.4.dylib is linked (but /usr/lib/libcurl.4.dylib doesn't exist!!) ?
163+
164+
node_modules/node-libcurl/lib/binding/node_libcurl.node:
165+
/usr/lib/libcurl.4.dylib (compatibility version 7.0.0, current version 9.0.0)
166+
167+
node_modules/node-libcurl/lib/binding/node_libcurl.node:
168+
@rpath/libcurl.dylib (compatibility version 13.0.0, current version 13.0.0)
169+
170+
# DYLD_PRINT_LIBRARIES=1 node curl/lc.js
171+
for new build approach (curl-config), node-libcurl (8.1.1)
172+
... ...
173+
dyld[3203]: <0124D559-13AB-354E-836D-A0560B3F4FC2> /Users/harry/test/leetcode-cli/node_modules/node-libcurl/lib/binding/node_libcurl.node
174+
dyld[3203]: <7825CF7A-09D9-32D9-8FA7-704D0B71BF92> /usr/local/Cellar/curl-impersonate/0.6.0-alpha.1/lib/libcurl-impersonate-chrome.4.dylib
175+
... ...
176+
177+
for old build approach (node_libcurl.target.mk), node-libcurl (8.4.0)
178+
... ...
179+
dyld[69574]: <4528259C-8493-3A0C-8B35-F29E87F59EED> /Users/harry/test/leetcode-cli/node_modules/node-libcurl/lib/binding/node_libcurl.node
180+
dyld[69574]: <90815EBD-89C8-33E7-8B86-5A024176BC15> /usr/lib/libcurl.4.dylib
181+
... ...
182+
looks like macOS does some magic when loading /usr/lib/libcurl.4.dylib (in memory or cache?)
183+
```
184+
- The leetcode extension is not always running in separate process space from vscode itself
185+
186+
The vscode itself is built with electron, but the modified version of node-libcurl was built with node (18.12.0). Although in vscode leetcode extension, node 18.12.0 is nominated as the node.js executable path and the extension does spawn a separate node process to run the underlying leetcode commands, we still got the NODE_MODULE_VERSION incompatible error.
187+
```
188+
const childProc = wsl.useWsl()
189+
? cp.spawn("wsl", [leetCodeExecutor_1.leetCodeExecutor.node, leetCodeBinaryPath, "user", commandArg], { shell: true })
190+
: cp.spawn(leetCodeExecutor_1.leetCodeExecutor.node, [leetCodeBinaryPath, "user", commandArg], {
191+
shell: true,
192+
env: cpUtils_1.createEnvOption(),
193+
});
194+
195+
this.executeCommandEx(this.nodeExecutable, [yield this.getLeetCodeBinaryPath(), "plugin", "-e", plugin]);
196+
```
197+
- Will different install locations for the node-libcurl module (e.g. as one of the node 18.12.0 global modules) fix the NODE_MODULE_VERSION incompatible issue?
198+
199+
### Archived notes
200+
```
78201
# build & install node-libcurl from source, first time (to generate build files)
79202
# npm_config_build_from_source=true npm i node-libcurl
80203
# use yarn as npm doesn't create build folders and make files!
@@ -125,55 +248,7 @@ node curl/lc.js
125248
# run test, it works!
126249
node curl/lc.js
127250
128-
### questions ???
129-
# otool -L node_modules/node-libcurl/lib/binding/node_libcurl.node
130-
to find out which libcurl.4.dylib is loaded (as /usr/lib/libcurl.4.dylib doesn't exist!) ?
131-
otool
132-
lib/binding/node_libcurl.node:
133-
/usr/lib/libcurl.4.dylib (compatibility version 7.0.0, current version 9.0.0)
134-
135-
# DYLD_PRINT_LIBRARIES=1 node curl/lc.js
136-
... ...
137-
dyld[69574]: <4528259C-8493-3A0C-8B35-F29E87F59EED> /Users/harry/test/leetcode-cli/node_modules/node-libcurl/lib/binding/node_libcurl.node
138-
dyld[69574]: <90815EBD-89C8-33E7-8B86-5A024176BC15> /usr/lib/libcurl.4.dylib
139-
... ...
140-
looks like macOS has some special mapping when loading /usr/lib/libcurl.4.dylib (in memory or cache?)
141-
142-
# references
143-
# https://github.com/lwthiker/curl-impersonate
144-
# https://github.com/lwthiker/curl-impersonate#libcurl-impersonate
145-
# https://github.com/lwthiker/curl-impersonate/issues/80#issuecomment-1166192854
146-
# https://github.com/JCMais/node-libcurl?tab=readme-ov-file#building-on-macos
147-
```
148-
149-
### Test Conclusion
150-
| Not working | Working |
151-
| ----------- | ----------- |
152-
| original node-libcurl | curl-impersonate |
153-
| naive proxy | node exec + curl-impersonate |
154-
| | modified node-libcurl |
155-
156-
### TODO
157-
- Fix the NODE_MODULE_VERSION error by building node-libcurl [with electron](https://github.com/JCMais/node-libcurl?tab=readme-ov-file#electron-aka-atom-shell)
158-
```
159-
Failed to list problems: Error: The module '/Users/harry/.vscode/extensions/leetcode.vscode-leetcode-0.18.1/node_modules/vsc-leetcode-cli/node_modules/node-libcurl/lib/binding/node_libcurl.node' was compiled against a different Node.js version using NODE_MODULE_VERSION 108. This version of Node.js requires NODE_MODULE_VERSION 118. Please try re-compiling or re-installing the module (for instance, using `npm rebuild` or `npm install`)..
160-
```
161-
- Try different install locations for the node-libcurl
162-
163-
### Update the vscode leetcode extension
164-
165-
### References
166-
- [Could not login with both 'leetcode user -l' and 'leetcode user -c'](https://github.com/skygragon/leetcode-cli/issues/218)
167-
- [Cannot login with premium account](https://github.com/skygragon/leetcode-cli/issues/194)
168-
- [Failed to log in with a leetcode.com account](https://github.com/LeetCode-OpenSource/vscode-leetcode/issues/478), [a comment](https://github.com/LeetCode-OpenSource/vscode-leetcode/issues/478#issuecomment-564757098)
169-
- Proxy Server to bypass Cloudflare: [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr), [naiveproxy](https://github.com/klzgrad/naiveproxy)
170-
- [How To Bypass Cloudflare in 2024](https://scrapeops.io/web-scraping-playbook/how-to-bypass-cloudflare/)
171-
- [How to Bypass Cloudflare in 2024: The 8 Best Methods](https://www.zenrows.com/blog/bypass-cloudflare)
172-
- [How to bypass Cloudflare when web scraping in 2024](https://scrapfly.io/blog/how-to-bypass-cloudflare-anti-scraping/)
173-
- [node abi versions](https://github.com/nodejs/node/blob/main/doc/abi_version_registry.json)
174-
175-
### Archived notes
176-
```
251+
# ------------------------------------
177252
# node-gyp related files:
178253
~/Library/Caches/node-gyp/20.11.1/include/node/common.gypi
179254
~/Library/Caches/node-gyp/20.11.1/include/node/config.gypi

lib/util.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { request } = require('./util1')
1+
const { request } = require('./util2')
22

33
request.get = (opts, callback) => request({...opts, ...{method: 'GET'}}, callback);
44
request.post = (opts, callback) => request({...opts, ...{method: 'POST'}}, callback);

lib/util2.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ const request = (opts, callback) => {
8787
headers,
8888
};
8989

90-
console.log('status code', statusCode);
91-
console.log('response body', body);
92-
console.log('response headers', headers);
90+
// console.log('status code', statusCode);
91+
// console.log('response body', body);
92+
// console.log('response headers', headers);
9393
// console.log(url, typeof(body), body);
9494

9595
const data = typeof(body) == "string" ? JSON.parse(body) : body;

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,12 @@
5151
"dependencies": {
5252
"ansi-styles": "3.2.1",
5353
"cheerio": "0.20.0",
54+
"global": "^4.4.0",
5455
"he": "1.2.0",
5556
"mkdirp": "^1.0.4",
5657
"moment": "^2.29.1",
5758
"nconf": "^0.11.2",
59+
"node-libcurl": "^4.0.0",
5860
"ora": "3.0.0",
5961
"prompt": "1.0.0",
6062
"request": "2.88.0",
@@ -65,7 +67,7 @@
6567
},
6668
"devDependencies": {
6769
"chai": "4.2.0",
68-
"electron": "^29.1.1",
70+
"electron": "27.3.6",
6971
"electron-rebuild": "^3.2.9",
7072
"eslint": "5.9.0",
7173
"eslint-config-google": "0.11.0",

0 commit comments

Comments
 (0)