Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

checkForLatestVersion() in createReactApp.js dos not respect npm registry config setting #13518

Open
wilee8 opened this issue Feb 15, 2024 · 1 comment

Comments

@wilee8
Copy link

wilee8 commented Feb 15, 2024

'https://registry.npmjs.org/-/package/create-react-app/dist-tags',

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:
[email protected]
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:

<html>
<head>
<title>BIG-IP Per Request Policy Resource blocked page</title>
<style>
...

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.

@sreeragdas
Copy link

hi , can i work on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants