This might be a stupid question but I really don't know what is going on.
I have created a React App with crate react app
and uploaded it as a private repository to my GitLab account. The (default) React App starts as expected after running yarn start
locally at localhost:3000
. Since I need to create packages for ongoing code development, I have started to get into using the NPM Registry at GitLab. This was actually quite easy:
.npmrc
within the app directory# Set URL for your scoped packages.
# This is my top-level group at GitLab
@scope:registry=https://gitlab.com/api/v4/packages/npm/
# Add the token for the scoped packages URL.
# I have chosen to use the personal key -> more infos: https://docs.gitlab.com/ee/user/packages/npm_registry/
//gitlab.com/api/v4/packages/npm/:_authToken="<auth-token>"
# Add token for uploading to the registry.
//gitlab.com/api/v4/projects/<project-ID>/packages/npm/:_authToken="<auth-token>"
npm init
to initialise the packagepackage.json
like so{
"name": "@scope/package-name",
"version": "0.1.0",
"main": "index.js", <-- the entry point
...
"publishConfig": {
"@scope:registry": "https://gitlab.com/api/v4/projects/<project-ID>/packages/npm/"
}
}
npm publish
Like I've said, the package gets uploaded to my GitLab account, under the scope fine. The only problem I have now is that running yarn start
from my local repo does result in a blank white screen. I have also realised that yarn does not redirect to http://localhost:3000
anymore but to http://localhost:3000/scope/repository-name
.
What am I missing here?
Thanks!
After a lot of try and error (and even more research), I have finally found the solution to my problem. I want to point out, that I am still not entirely sure why certain things happen but hopefully this solution will help the one or other from wasting time with this.
Basically, I want to publish certain React Components as an NPM Package to Gitlab. I work on a project which contains numerous different React Components - some of which are stand alone Single Page Applications and others are part of an "App". The components which are part of the Application might also be reused later in another project. Thus this qualifies them to be packaged.
Whenever I start developing, I start with create react app
and since a React App is usually a Single Page Application, it does not really make sense to package it. Nonetheless, if we want to develop some components which will be part of an app later, but still want to test the behaviour locally, it makes sense to do so.
I will describe how to create packages on Gitlab but I guess it will work the same (apart from details with authentication and scopes) with any other repository hosting service.
We start with setting up our React App
npx create-react-app react-package
After everything is installed navigate into application folder cd react-package
and start with developing a component. For our example we create a folder inside the src
folder named PackagedComponent
which will contain 2 files PackagedComponent.jsx
and index.js
.
Our component will be very simple
import React from 'react`;
export const PackagedComponent = () => {
return (
<h1>This is my packaged component!</h1>
);
}
The index.js
will serve as the starting point
export { PackagedComponent } from './PackagedComponent';
Next we have to do is create a repository on Gitlab and link it to the project we just have created. We then create a .npmrc
file in the root directory of our application. This is optional but I find this really easy since there is a good documentation on Gitlab for that. My .npmrc
file looks like that
# Add token for uploading to the registry. Replace <your_project_id>
# with the project you want your package to be uploaded to.
# The auth toke is only necessary if you have a private package
//gitlab.com/api/v4/projects/< your_project_id>/packages/npm/:_authToken="< your_auth_token>"
Next thing we do is to create the package.json
for the project and therefore we do
npm init
Just go with all the standard options for the moment.
Now it's time to do the actual building and packaging. First we have to install some more dev dependencies which will do the transpiling for us ( I will not explain all that but check here for further infos)
npm i --save-dev babel-cli babel-preset-env babel-preset-react babel-preset-stage-0
Now we have to modify the package.json
. First remove the line
"private: true"
then replace the build command
"scripts": {
"build": "rm -rf dist && NODE_ENV=production npx babel src/PackagedComponent --out-dir dist --copy-files",
...
},
then add the lines
"main": "dist/index.js",
"module": "dist/index.js",
"files": "/dist",
"babel": {
"presets": [ "react", "env", "stage-0" ]
}
change the name
to fit the scope. In my case I have created a group which contains my packaged-component
project. The group name in this case is the scope @group-name/packaged-component-package
.
"name": "@group-name/packaged-component-package",
Gitlab requires a publishConfig
so we have to add
"publishConfig": {
"@group-name:registry": "https://gitlab.com/api/v4/projects/<your_project_id>/packages/npm/"
}
be careful that you get the scope
and the project id
right!
Now we just have to install the missing packages
npm i
run the build command
npm run build
and publish to Gitlab
npm publish
If everything went well, you should see you package in your group on Gitlab under Packages & Registries.
Now we want to use our packaged component in another application. We can just run npx create-react-app test-app
again. In the app directory add a .npmrc
again
# Set URL for your scoped packages.
@group-name:registry=https://gitlab.com/api/v4/packages/npm/
# Add the token for the scoped packages URL. This will allow you to download
# `@foo/` packages from private projects.
# You only need this if the package is private
//gitlab.com/api/v4/packages/npm/:_authToken="<your_auth_token>"
Once this is done run npm i
and your Component should appear in the node_modules
directory under @group-name/packaged-component-package
.
Then open the App.js
and add the lines
import './App.css';
// import the packaged component
import { PackagedComponent } from '@group-name/packaged-component-package';
function App() {
return (
<div className="App">
<PackagedComponent />
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
Ideally you should see the following screen
Hope this helped!