Scoped packages on forked versions
Created by: 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.