Write before
When doing react-native development, we often find some third-party components that are easy to install and use by npm install.Have you ever thought about how we should develop and publish a component ourselves while using it?Whether it's sharing multiple projects for yourself or using open source for others, it's cool.
So today, I'm going to talk about how to develop a component of my own, open source to github, and publish to npm, using an example of a CardView component I've developed for use with ios and android.
A description
My component name is react-native-rn-cardview .If the react-native-cardview component name appears in the tutorial, it means the same thing.
1 Create and implement
1.1 Create a custom component template project
1.1.1 Installation react-native-create-library
$ npm install -g react-native-create-library
1.1.2 Create Template Project
We use the command react-native-create-library to create the project, specify the platform as ios,android, specify the package in android, other parameters can refer to themselves in react-native-create-library Documentation on github, not to mention here
$ react-native-create-library --package-identifier com.quenice.cardview --platforms android,ios cardview
Let's rename the project name
$ mv cardview react-native-cardview
It may be said that the owner of the building did not directly generate the react-native-cardview project, but instead asked the owner to generate the cardview and rename it.This is a trick, because some component-related names or classes are prefixed with react-native or RN by default for projects produced with react-native-create-library.
For example, if your initial project name is react-native-card-view, the component name defined in package.json will be react-native-react-native-card-view, and the related class defined in the android module will be RNReactNativeCardviewModule.java, which is obviously ugly.
ok, let's continue.
Now the directory structure:
$ tree
└── react-native-cardview ├── README.md ├── android │ ├── build.gradle │ └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── reactlibrary │ ├── RNCardviewModule.java │ └── RNCardviewPackage.java ├── index.js ├── ios │ ├── RNCardview.h │ ├── RNCardview.m │ ├── RNCardview.podspec │ ├── RNCardview.xcodeproj │ │ └── project.pbxproj │ └── RNCardview.xcworkspace │ └── contents.xcworkspacedata └── package.json
Once you've built your component project, you're ready to write your implementation code
2 Write code
Writing code is divided into three parts, one part is android native code, one part is iOS native code, and one part is react-native (or javascript) code.Because react-native-cardview Only native android modules are involved, so this article does not cover iOS native module development at this time. If you are interested, I can start a separate article to focus on native iOS modules.
2.1 Writing Android Native Module
There are generally three classes required to write native android code:
2.1.1 RNxxxModule
The main purpose of this class is to define the native module name, which can be accessed directly in javascript through React.NativeModules.xxx, where XXX is the return value of the getName method defined in the RNxxxModule class.Below are my components react-native-cardview Module class in
package com.quenice.reactnative; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.Callback; public class RNCardViewModule extends ReactContextBaseJavaModule { private final ReactApplicationContext reactContext; public RNCardViewModule(ReactApplicationContext reactContext) { super(reactContext); this.reactContext = reactContext; } @Override public String getName() { return "RNCardView"; } }
2.1.2 RNxxxManager
Manager classes are primarily native implementations of components and map react-native component properties to native properties
package com.quenice.reactnative; import android.graphics.Color; import android.support.v7.widget.CardView; import android.view.View; import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.ViewGroupManager; import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.views.view.ReactViewGroup; public class RNCardViewManager extends ViewGroupManager<CardView> { @Override public String getName() { return "RNCardView"; } @Override protected CardView createViewInstance(ThemedReactContext reactContext) { CardView cardView = new CardView(reactContext); cardView.setUseCompatPadding(true); cardView.setContentPadding(0, 0, 0, 0); ReactViewGroup reactViewGroup = new ReactViewGroup(reactContext); cardView.addView(reactViewGroup); return cardView; } @ReactProp(name = "cardElevation", defaultFloat = 0f) public void setCardElevation(CardView view, float cardElevation) { view.setCardElevation(PixelUtil.toPixelFromDIP(cardElevation)); } ... }
2.1.3 RNxxxPackage
The Package class is primarily used to register native modules, native component implementations, that is, to register the Module and Manager classes above
package com.quenice.reactnative; import java.util.Arrays; import java.util.Collections; import java.util.List; import com.facebook.react.ReactPackage; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.uimanager.ViewManager; import com.facebook.react.bridge.JavaScriptModule; public class RNCardViewPackage implements ReactPackage { @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { return Arrays.<NativeModule>asList(new RNCardViewModule(reactContext)); } // Deprecated from RN 0.47 public List<Class<? extends JavaScriptModule>> createJSModules() { return Collections.emptyList(); } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Arrays.<ViewManager>asList(new RNCardViewManager()); } }
2.2 Write native iOS code
react-native-cardview
iOS can be implemented directly by using shadow-related attributes in react-native, so this article does not cover
2.3 Write ReactNative code
Once you've written the native android/iOS module, you need to write javascript code to bridge react-native with the native module.
import PropTypes from 'prop-types'; import {requireNativeComponent, View} from 'react-native'; const iface = { name: 'CardView', propTypes: { cardElevation: PropTypes.number, maxCardElevation: PropTypes.number, backgroundColor: PropTypes.string, radius: PropTypes.number, ...View.propTypes, // include the default view properties }, }; module.exports = requireNativeComponent('RNCardView', iface);
3 Code upload and component Publishing
3.1 Code uploaded to github
After writing the code, we need to upload it to github, and then we need to use the GitHub address of the code when the component is published to npm
.If you haven't done a github-related configuration, you can refer to another article from me: Install GIt and configure connection GitHub
Execute the following command to synchronize the code into your github repository:
$ git add . $ git commit -a -m "initial commit" $ git push -u origin master
After synchronization, you can go to github to see if push succeeds:
https://github.com/YourGithubAccount/YourRepository
3.2 Component Publishing
After you have developed your components, if you want to install them in another project (or for others to install and use), then your components must be published to the npm registry.
3.2.1 npm registry
What is npm registry
Simply put, npm registry is equivalent to a package registration administration center.It manages the various plug-ins released by developers around the world, and developers can install the required plug-ins via npm install.
The official npm registry is: http://registry.npmjs.org/
The domestic speed is faster: https://registry.npm.taobao.org/
See
You can view the currently used registry:
$ npm config get registry
switch
Of course, you can also switch the npm registry currently in use by command
# Global Switching $ npm config set registry http://registry.npmjs.org/
Sometimes you just want to switch temporarily while executing some npm commands. At this time, you can use --registry to specify the registry for the temporary switch, such as when publishing in npm
$ npm publish --registry http://registry.npmjs.org/
You can temporarily specify that, of course, the registry will still be restored to its original registry after the command execution ends
3.2.2 Create/login npm registry account
To publish components to npm registry, you must be a registered user of npm registry by:
$ npm adduser
To add a new user, or you are already Official Web Register a user by:
$ npm login
To log in to the npm registry account.
Use the following two ways to confirm that you have successfully created/logged on to the npm registry
- Command $npm whoami confirms successful local logon authentication
- Open Online https://npmjs.com/~username Check to see if account creation was successful
3.2.3 Preparing for Release
3.2.3.1.gitignore and.npmignore
- Define which files are not uploaded to github in.gitignore
- Define which files are not packaged when published in.npmignore
- If you have.gitignore but no.npmignore file, then.gitignore can act as.npmignore
- Specific rules can be referred to as: npm-developers, .gitignore or .npmignore pattern rules
3.2.3.2 package.json
The package.json file defines all the information published, including key information such as component name, version, author, description, dependency, and so on.Specific can be referred to Working with package.json
Here are react-native-cardview The package.json file contents of:
{ "name": "react-native-rn-cardview", "version": "1.0.0", "description": "A ReactNative CardView Component for android and iOS", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [ "react-native", "react-component", "react-native-component", "react", "mobile", "ios", "android", "cardview" ], "author": { "name": "quenice", "email": "qiubing.it@gmail.com" }, "license": "MIT", "repository": { "type": "git", "url": "git@github.com:quenice/react-native-cardview.git" }, "devDependencies": { "react": "^16.2.0", "react-native": "^0.53.0" }, "peerDependencies": { "react": "^16.2.0" }, "dependencies": { "prop-types": "^15.6.0" } }
3.2.3.3 Writing readme.md
The readme.md file can be used to specify how components are used, considerations, and so on.Write in Markdown syntax
3.2.4 Release
Once you're ready, you can publish.It is important to note that the first release is different from the subsequent update release.
First Release
For the first time, execute the command directly:
$ npm publish
That's it. You can check online to see if the publication was successful.Access the link (<package>is the npm package name you published):
https://www.npmjs.com/package/<package>
See if there's already content, there's a description that the publication was successful.
Update Publication
If it's not your first release, you need to execute two commands
$ npm version <update_type> $ npm publish
The $npm version command is used to automatically update the version number with the value patch ``minor `major'for update_type.So in what scenarios should you choose what update_type?Look at the table below
update_type | scene | Version Number Rule | Give an example |
---|---|---|---|
- | First Release | Version number 1.0.0 | 1.0.0 |
path | When fixing bug s, minor changes | Incremental change from version number 3 | 1.0.0 -> 1.0.1 |
minor | When new functionality comes online and does not affect existing functional modules in the current version | Incremental change from version number 2 | 1.0.3 -> 1.1.3 |
major | When several new functional modules are online and have an impact on existing functionality in the current version | Incremental change from version number 1 | 1.0.3 -> 2.0.0 |
Be careful
If the first release number is not 1.0.0, use $NPM version <update_type>
To update will cause errors, because you did not follow the version rules it stipulated. At this time, you can manually modify the version field in package.json to match the version number of the contract rules, then execute $npm publish directly, and the next incremental update will automatically update the version number using $NPM version <update_type>
4 Tests
Components need to be tested from development to final release to ensure proper functionality. How do you test them?
4.1 Create a react-native project
First we create a react-native project called example
$ react-native init example
The example project directory can be at the same level as the component project directory react-native-cardview, and of course you can put it anywhere you want. For ease of operation, we'll put both directories at the same level.That is, the directory is now like this
$ tree . ├── example └── react-native-cardview
Then all we have to do is install the local or published components into the example project for testing
4.2 Local Code Testing
Before the components are released, we can install the local code directly into the example project and test it in several ways
4.2.1 yarn link
$ cd react-native-cardview $ yarn link $ cd ../example $ yarn link react-native-cardview $ react-native link react-native-cardview
Explain a few points:
- yarn link is a local component that registers the local code in the current directory as react-native-cardview with yarn. The component name react-native-cardview is actually based on the value of the name field in package.json, regardless of the directory name, except that it exactly equals the directory name here
- The yarn link react-native-cardview command installs the local component react-native-cardview into the example project, which you can find in example/node_modules
- react-native link react-native-cardview, as you should know, is a native module link for android/iOS
- In fact, yarn link simply means making a symbol link, that is, the content in the example/node_modules/react-native-cardview/directory points to react-native-cardview/directory content, and you change the code in the react-native-cardview/directory, which is equivalent to directly changing the code in the example/node_modules/react-native-cardview/directory.Can achieve the purpose of modifying component code while looking at the effect
Configuring local paths in 4.2.2 package.json
Add dependencies directly to example's package.json
example/package.json
{ "name":"example", ... "dependencies": { "react-native": "^0.55.4", "react-native-cardview":"file:../react-native-cardview", ... } ... }
Then execute
$ react-native link react-native-cardview
Like yarn link, it is equivalent to making a symbol link, directly modifying the code in the react-native-cardview/directory, and directly changing the code in the example/node_modules/react-native-cardview/directory
4.2.3 Direct copy local code
This is a straightforward way to copy react-native-cardview/directory directly to example/node_modules/react-native-cardview/directory
$ cp -rf react-native-cardview/ example/node_modules/
Then execute
$ react-native link react-native-cardview
The disadvantage of this approach is that you need to manually copy to example/node_modules/react-native-cardview/each time you change the code
4.3 Uploaded/released code tests
Components that have been uploaded to github or published to npm registry are tested in the same way that we normally install a third-party component.
4.3.1 via github
Add your code and upload it to the github repository via git, so you can install your components directly via npm install
npm install --save https://github.com/quenice/react-native-cardview.git
perhaps
npm install --save git@github.com:quenice/react-native-cardview.git
Note: Replace the above HTTPS or SSH with the URL on your own ghthub
Then execute
$ react-native link react-native-rn-cardview
4.3.2 via npm
This is no different from following third-party components
$ npm install --save react-native-rn-cardview
Then execute
$ react-native link react-native-rn-cardview
epilogue
At this point, the full development-test-release lifecycle of a react-native component is complete.
Because it's a component I developed in conjunction with myself react-native-rn-cardview The actual development process, so there are inevitable omissions, there are certainly many deficiencies.If you have any problems or find errors, you are welcome to leave a message in the comments area for us to discuss and solve together.
In addition, if you need to use CardView in react-native, you are welcome to use it react-native-rn-cardview
Author: Quenice
Link: https://www.jianshu.com/p/091a68ea1ca7
Source: Short Book
The copyright in the brief book is owned by the author. For any form of reprinting, contact the author for authorization and indicate the source.