How to avoid relative path when importing library?
Folder structure
screens login LoginScreen.js LoginNavigator.js onboarding OnboardingNavigator welcome WelcomeScreen.js term TermScreen.js notification NotificationScreen.js main MainNavigator.js news NewsScreen.js profile ProfileScreen.js search SearchScreen.js library package.json components ImageButton.js RoundImage.js utils moveToBottom.js safeArea.js networking API.js Auth.js
Turn library into a module
Turn library into a module so that Node can find it. Add “package.json” to any folder makes it into a Node module. Here is package.son file.
{ "name": "library", "version": "0.0.1" }
Usage
Instead of using relative path like this
import moveToBottom from '../../../../library/utils/move' import ImageButton from '../../../../library/components/ImageButton'
we can use absolute path like this
import moveToBottom from 'library/utils/moveToBottom' import ImageButton from 'library/components/ImageButton'
How to control static resource?
Folder structure
src ... res package.json strings.js colors.js palette.js fonts.js images.js images logo@2x.png logo@3x.png button@2x.png button@3x.png R.js
How to use one file to call all resource elements?
Learn from Android, all the resource can be called from R class. Resource ids are generated into R class after build
import strings from './strings' import images from './images' import colors from './colors' import palette from './palette' const R = { strings, images, colors, palette } export default R
How to manage constant string resource?
Create a strings.js file
const strings = { onboarding: { welcome: { heading: 'Welcome', text1: "What you don't know is what you haven't learn", text2: 'Visit my GitHub at https://github.com/onmyway133', button: 'Log in' }, term: { heading: 'Terms and conditions', button: 'Read' } } } export default strings
Create “package.json” file inside “res” folder
{ "name": "res", "version": "0.0.1" }
Usage
import R from 'res/R' render() { return ( <SafeAreaView style={styles.container}> <Image style={styles.logo} source={R.images.logo} /> <Image style={styles.image} source={R.images.placeholder} /> <Text style={styles.title}>{R.strings.onboarding.welcome.title.toUpperCase()}</Text> ) }
How to control app design
The design of the app should be consistent. Certain elements should have the same look and feel so they don’t confuse the user.
For example, the heading Text
should use one color, font, and font size. The Image
component should use the same placeholder image.
Create “res/palette.js”
import colors from './colors' const palette = { heading: { color: colors.title, fontSize: 20, textAlign: 'center' }, text: { color: colors.text, fontSize: 17, textAlign: 'center' } } export default palette
Usage
const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center' }, heading: {...palette.heading, ...{ marginTop: 72 }} })
How to control internal images?
Folder structure
src ... res images.js images logo@2x.png logo@3x.png button@2x.png button@3x.png scripts images.js clear.js
Create images.js
const images = { button: require('./images/button.png'), logo: require('./images/logo.png'), placeholder: require('./images/placeholder.png') } export default images
Usage
import images from 'res/images' import colors from 'res/colors' export default class ImageButton extends React.Component { render() { return ( <TouchableOpacity style={styles.touchable} onPress={this.props.onPress}> <View style={styles.view}> <Text style={styles.text}>{this.props.title}</Text> </View> <Image source={images.button} style={styles.image} /> </TouchableOpacity> ) } }
How to automatically update “images.js” when images folder is changed
Add /scripts/images.js
Simply traverse through images, and update /src/res/images.js
accordingly
const fs = require('fs') const imageFileNames = () => { const array = fs .readdirSync('src/res/images') .filter((file) => { return file.endsWith('.png') }) .map((file) => { return file.replace('@2x.png', '').replace('@3x.png', '') }) return Array.from(new Set(array)) } const generate = () => { let properties = imageFileNames() .map((name) => { return `${name}: require('./images/${name}.png')` }) .join(',\n ') const string = `const images = { ${properties} } export default images ` fs.writeFileSync('src/res/images.js', string, 'utf8') } generate()
Update images folder by running this script
node scripts/images.js
or config main “package.json”
"scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "test": "jest", "lint": "eslint *.js **/*.js", "images": "node scripts/images.js" }
and run
npm run images
Leave a Reply