This React-Native Expo template allows you to bootstrap a private NPM package hosted on GitHub, perfect for propritory modules within your organisation! You will be able to consume it in your main app using a GitHub access token.
You will be able to run Storybook for both native and web to QA and using WritingTests you can keep up the 100 % test coverage.
- Using this template
- Developing
- Build
- Expo
- Storybook
- Linting
- Continuous Integration
- Optimizations
- Module Formats
- Named Exports
- Publish a new version
- Consume package
- Configure libs
- Contributors β¨
Table of contents generated with markdown-toc
When you use this template you will get a React-Native Expo repo that's almost ready to be build and deployed to GitHub as a private NPM package.
Make sure to update package name in package.json as well as publishConfig in package.json.
You will probably want to change the license field from APACHE
(this repo) to UNLICENSED
(private repo) too.
For organisation "expohacks" the config would look like this.
Replace "expohacks" with your organisation name and "npm-github-react-native" with the package name
// package.json
{
"name": "@expohacks/npm-github-react-native",
"author": "Expo Hackers",
"version": "0.1.1",
"license": "UNLICENCED",
"publishConfig": {
"@ expohacks:registry": "https://npm.pkg.github.com",
"access": "restricted"
},
"repository": {
"type": "git",
"url": "git+https://github.com/expohacks/npm-github-react-native.git"
},
"bugs": {
"url": "https://github.com/expohacks/npm-github-react-native/issues"
},
"homepage": "https://github.com/expohacks/npm-github-react-native#readme",
...
}
Optionally configure Expo app.json.
Next:
Follow the React-Native Expo installation guide to set up a developer environment.
This project is bootstrapped using TSDX, but with some heavy modifications to produce React-Native Expo compatible code.
There is no fancy auto renaming CLI so make sure to change package name the first thing you do.
This TSDX setup is meant for developing libraries (not apps!) that can be published to NPM. If youβre looking to build a Node app, you could use
ts-node-dev
, plaints-node
, or simpletsc
.
If youβre new to TypeScript, checkout this handy cheatsheet
- Node.js LTS release
- Git
- Watchman for macOS or Linux users
- Visual Studio Code - cross-platoform modular IDE with React-Native support and integrated terminal.
- Windows users: PowerShell, Bash via WSL
Optionally install Yarn - a fast package manager for installing NPM dependencies. However, do not add new packages using Yarn as that would create a yarn.lock.
Just a recommendation based on what worked for this developer:
- React-Native Tools
- Expo tools
- Prettier
- TypeScript Hero
- TypeScript importer
- TypeScript toolbox
- Add jsdoc comments
- JSDoc markdown highlighting
- ES7 React/Redux/GraphQL/React-Native snippets
- ESLint
- GitHub Pull Requests
- Markdown editor
- HTML Preview
Once above environment is in place you can open a terminal in the repository root (in VS Code).
npm install # or yarn install
TSDX scaffolds your new library inside /src
.
To compile the code into the NPM deployable product, run
npm run start # or yarn start
This builds to /dist
and runs the project in watch mode so any edits you save inside src
causes a rebuild to /dist
.
- To do a one-off build, use
npm run build
oryarn build
. - To run tests, see jest
- To release, see Publish a new version
- To run, see Storybook
The app is built using Expo for React-Native. It allows working with JavaScript without native code and instant releases Over The Air (OTA). The commands (above) uses Expo to start, run, build and deploy the app.
The app is integrated with Storybook which provides an environment to develop and test components in isolation.
Make sure you have a react-native environment for Expo setup.
To run, first start the metro bundler:
npm run start:native # or yarn start:native
Use the terminal commands to start iOS (press i), Android (press a) or start developer tools (press d). Optinally, you can use a second terminal to run commands:
npm run ios # or yarn ios
npm run android # or yarn android
Configuration is found in the storybook/index.tsx entry point. Stories are added to storybook/stories/index.tsx.
For a new component stories should be added that replicate the requirements like Figma designs.
Storybook specific components are written that connect the component to Storybook knobs that allow manipulation of the props while running the app.
Notice how we use text
and action
from storybook to make these dynamic values that can be changed in the storybook knobs UI:
// LoginForm.stories.tsx
import {action} from '@storybook/addon-actions';
import {text} from '@storybook/addon-knobs';
import {storiesOf} from '@storybook/react-native';
import React from 'react';
storiesOf('LoginForm', module)
.addDecorator(getStory => <CenterView>{getStory()}</CenterView>)
.add('with text', () => (
<LoginForm mode="contained" onLogin={action('onLogin')}>
{text('Text', 'Login')}
</LoginForm>
))
.add('with some emoji', () => (
<LoginForm mode="outlined" onLogin={action('clicked-emoji')}>
π π π π―
</LoginForm>
));
The project is setup to use ESLINT with Prettier.
npm run lint # or yarn lint
Two actions are added by default:
main
which installs deps w/ cache, lints, tests, and builds on all pushes against a Node and OS matrixsize
which comments cost comparison of your library on every pull request usingsize-limit
Please see the main tsdx
optimizations docs. In particular, know that you can take advantage of development-only optimizations:
// ./types/index.d.ts
declare var __DEV__: boolean;
// inside your code...
if (__DEV__) {
console.log('foo');
}
You can also choose to install and use invariant and warning functions.
CJS, ESModules, and UMD module formats are supported.
The appropriate paths are configured in package.json
and dist/index.js
accordingly. Please report if any issues are found.
Per Palmer Group guidelines, always use named exports. Code split inside your React app instead of your React library.
- Commit and push your feature.
- Up version in
package.json
using the scriptnpm run version:next
oryarn version:next
. This will tag and push to your branch. - PR and merge your branch.
- Draft a new Release from that the new tag.
- GitHub Action builds and publishes. The package becomes available in "packages" GitHub page.
These details are valid if the package is private scoped.
- Open the lib where u want to consume the private NPM package
- Create a personal access token with
write:packages
scope - Config
.npmrc
to use the token (below) - Install the scoped package, e.g.
yarn add https://github.com/thomashagstrom/npm-github
Example npmrc
config for consuming thomashagstrom
org scoped packages:
replace "thomashagstrom" with your organisation name
@thomashagstrom:registry=https://npm.pkg.github.com/thomashagstrom
//npm.pkg.github.com/:_authToken=MyTopSecretTokenWithPackageScope
Install the dev peerDependencies. At this time:
npm i --save expo react react-native react-native-paper react-native-web @react-navigation/core @react-navigation/native @react-navigation/stack react-native-gesture-handler react-native-safe-area-context@3.3.2 react-native-screens react-native-web
# or yarn
Code quality is set up for you with prettier
, husky
, and lint-staged
. Adjust the respective fields in package.json
accordingly.
The project uses Jest to run unit tests. Together with Testing Library React Native it allows powerful testing capabilities without use of a real device.
See also: WritingTests.md
Find all available commands in package.json
.
The test
command uses CI config, so when developing use below command for optimal performance.
npm run test:dev # or yarn test:dev
Jest has a --watch
parameter that looks for changed files and only tests your changes, in real time. There's an alias for this parameter:
npm run test:watch # or yarn test:watch
size-limit
is set up to calculate the real cost of your library with npm run size
and visualize the bundle with npm run analyze
.
This is the folder structure we set up for you:
/src
index.tsx # EDIT THIS
/test
blah.test.tsx # EDIT THIS
.gitignore
package.json
README.md # EDIT THIS
tsconfig.json
TSDX uses Rollup as a bundler and generates multiple rollup configs for various module formats and build settings.
This is not very optimal for React-Native with Babel so we've opted for regular TypeScript build instead.
tsconfig.json
is set up to interpret dom
and esnext
types, as well as react
for jsx
. Adjust according to your needs.
Thanks goes to these wonderful people (emoji key):
Jared Palmer π |
Thomas HagstrΓΆm π |
This project follows the all-contributors specification. Contributions of any kind welcome!