Warm tip: This article is reproduced from serverfault.com, please click

Creating an NPM package out of a Create React App and publish on Gitlab

发布于 2020-11-05 18:51:39

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:

  1. create an .npmrc within the app directory
  2. add scope, repository ID and auth token (I have chosen to use a personal token) like so
# 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>"
  1. run npm init to initialise the package
  2. add the scope and a publishConfig to the package.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/"
  }
}
  1. run 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!

Questioner
Florian Ragossnig
Viewed
0
Florian Ragossnig 2020-12-01 02:48:59

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.

The goal

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.

The setup

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.

The packaging

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.

Adding the component to another application

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

enter image description here

Hope this helped!