On our internal network, we have to configure npm to use the local npm registry mirror:
npm config set registry <mirror-url>
After setting the npm registry, I tried to create a new React app using create-react-app, but I have the following errors
$ npx create-react-app frontend
Need to install the following packages:
create-react-app@5.0.1
Ok to proceed? (y) y
undefined:1
<html>
^
SyntaxError: Unexpected token '<', "<html>
<he"... is not valid JSON
at JSON.parse (<anonymous>)
at IncomingMessage.<anonymous> (/home/wilee8/.npm/_npx/c67e74de0542c87c/node_modules/create-react-app/createReactApp.js:1109:28)
at IncomingMessage.emit (node:events:526:35)
at endReadableNT (node:internal/streams/readable:1408:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
Node.js v20.9.0
I opened the createReactApp.js file at the location in the error, and opened it to line 1109. It was checkForLatestVersion(), the resolve(JSON.parse(body).latest); line:
function checkForLatestVersion() {
return new Promise((resolve, reject) => {
https
.get(
'https://registry.npmjs.org/-/package/create-react-app/dist-tags',
res => {
if (res.statusCode === 200) {
let body = '';
res.on('data', data => (body += data));
res.on('end', () => {
resolve(JSON.parse(body).latest);
});
} else {
reject();
}
}
)
.on('error', () => {
reject();
});
});
}
I added a console.log(body); line before the JSON.parse() call and ran create-react-app again. It failed again, with the console.log() line showing that it was receiving an HTML error page instead of the expected JSON. This is just the header, which should make it clear:
I've ran into this issue with Docker before - we get blocked by registries and need to use our internal mirror. Which I have configured npm to use, but checkForLatestVersion() seems to be hard-coded to use the default (external) registry.
I modified checkForLatestVersion() to use the mirror URL instead:
.get(
//'https://registry.npmjs.org/-/package/create-react-app/dist-tags',
'<mirror-url>-/package/create-react-app/dist-tags',
res => {
And then create-react-app worked.
I think checkForLatestVersion() needs to be modified to check the registry setting in npm and use that URL instead of being hard-coded to use npmjs.org. Stealing some code from getProxy(), I came up with this:
function checkForLatestVersion() {
return new Promise((resolve, reject) => {
let registryURL = execSync('npm config get registry').toString().trim();
let tagsURL = registryURL + '-/package/create-react-app/dist-tags';
https
.get(
tagsURL,
res => {
if (res.statusCode === 200) {
let body = '';
res.on('data', data => (body += data));
res.on('end', () => {
resolve(JSON.parse(body).latest);
});
} else {
reject();
}
}
)
.on('error', () => {
reject();
});
});
}
npm config get registry returns https://registry.npmjs.org/ if no value is set for registry in the npm config, so this should work whether or not someone configures npm to use a registry mirror.
https://github.com/facebook/create-react-app/blob/0a827f69ab0d2ee3871ba9b71350031d8a81b7ae/packages/create-react-app/createReactApp.js#L1101
On our internal network, we have to configure npm to use the local npm registry mirror:
npm config set registry <mirror-url>
After setting the npm registry, I tried to create a new React app using create-react-app, but I have the following errors
I opened the createReactApp.js file at the location in the error, and opened it to line 1109. It was
checkForLatestVersion()
, theresolve(JSON.parse(body).latest);
line:I added a
console.log(body);
line before theJSON.parse()
call and ran create-react-app again. It failed again, with theconsole.log()
line showing that it was receiving an HTML error page instead of the expected JSON. This is just the header, which should make it clear:I've ran into this issue with Docker before - we get blocked by registries and need to use our internal mirror. Which I have configured npm to use, but
checkForLatestVersion()
seems to be hard-coded to use the default (external) registry.I modified
checkForLatestVersion()
to use the mirror URL instead:And then create-react-app worked.
I think
checkForLatestVersion()
needs to be modified to check the registry setting in npm and use that URL instead of being hard-coded to use npmjs.org. Stealing some code fromgetProxy()
, I came up with this:npm config get registry
returnshttps://registry.npmjs.org/
if no value is set for registry in the npm config, so this should work whether or not someone configures npm to use a registry mirror.