Skip to content

Scoped packages on forked versions #1414

Closed
@danielfigueiredo

Description

@danielfigueiredo

Hello, everyone!

I know we had a PR merged to accept NPM scoped packages in --scripts-version, this is another issue. I recently have been maintaining a forked version of create-react-app where I mostly customized webpack configs to add things like cssnext, stylelint, etc. The problem happened when I updated ./packages/react-scripts/package.json to be a scoped package having the name to be something like @myOrg/my-package-name.

We all know that scoped packages will create a folder between node_modules and react-scripts, which is perfectly fine! I had of course to do some tweaks in few relative paths and everything worked.

The real problem is not with my published NPM package version, but instead with my local scripts. I'm trying to keep react-scripts e2e tests and things working, so that I can automate my fork and make sure the experience with my forked package is always good (things always working).

Looking at ./tasks/cra.sh around line 66 we have something like:

# Finally, pack react-scripts
scripts_path=$root_path/packages/react-scripts/`npm pack`

So our buddy NPM will look at my scoped package.json:

{
  "name": "@danorg/react-scripts",
  "version": "0.0.1",
...
}

and will generate a tar file named danorg-react-scripts-0.0.1.tgz. Well, things go fine until right after ./packages/create-react-app/index.js performs the install and tries to locate the installed react-scripts folder.

The getPackageName function does:

// Extract package name from tarball url or path.
function getPackageName(installPackage) {
  if (installPackage.indexOf('.tgz') > -1) {
    // The package name could be with or without semver version, e.g. react-scripts-0.2.0-alpha.1.tgz
    // However, this function returns package name only without semver version.
    return installPackage.match(/^.+\/(.+?)(?:-\d+.+)?\.tgz$/)[1];
  } else if (installPackage.indexOf('@') > 0) {
    // Do not match @scope/ when stripping off @version or @tag
    return installPackage.charAt(0) + installPackage.substr(1).split('@')[0];
  }
  return installPackage;
}

It infers the package name from the tar file, so it thinks the folder is danorg-react-scripts but it is actually danorg/react-scripts.

I'm having problems trying to figure out the best way to fix this, my thoughts were that cra.sh and ..../create-react-app/index.js should be a little bit smarter to figure out the actual package name.

A stupid way I found to do it is sending the actual package.json name as an argument to the script.
Let's say that our cra.sh as now the following line:

...
# Finally, pack react-scripts
scripts_path=$root_path/packages/react-scripts/`npm pack`
packageName=`node -e 'console.log(require("./package.json").name)'`

...
node packages/create-react-app/index.js --scripts-version=$scripts_path "$@" --package-name=$packageName

But I don't really know if that is the right way to fix this, maybe I shouldn't be using scoped packages.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions