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
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"
}
{
"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'
import moveToBottom from '../../../../library/utils/move'
import ImageButton from '../../../../library/components/ImageButton'
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'
import moveToBottom from 'library/utils/moveToBottom'
import ImageButton from 'library/components/ImageButton'
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
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'
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
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
text1: "What you don't know is what you haven't learn",
text2: 'Visit my GitHub at https://github.com/onmyway133',
heading: 'Terms and conditions',
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
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"
}
{
"name": "res",
"version": "0.0.1"
}
Usage
<SafeAreaView style={styles.container}>
source={R.images.logo} />
source={R.images.placeholder} />
<Text style={styles.title}>{R.strings.onboarding.welcome.title.toUpperCase()}</Text>
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>
)
}
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'
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
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({
heading: {...palette.heading, ...{
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center'
},
heading: {...palette.heading, ...{
marginTop: 72
}}
})
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
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
button: require('./images/button.png'),
logo: require('./images/logo.png'),
placeholder: require('./images/placeholder.png')
const images = {
button: require('./images/button.png'),
logo: require('./images/logo.png'),
placeholder: require('./images/placeholder.png')
}
export default images
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 {
<TouchableOpacity style={styles.touchable} onPress={this.props.onPress}>
<View style={styles.view}>
<Text style={styles.text}>{this.props.title}</Text>
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>
)
}
}
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 imageFileNames = () => {
.readdirSync('src/res/images')
return file.endsWith('.png')
return file.replace('@2x.png', '').replace('@3x.png', '')
return Array.from(new Set(array))
let properties = imageFileNames()
return `${name}: require('./images/${name}.png')`
const string = `const images = {
fs.writeFileSync('src/res/images.js', string, 'utf8')
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()
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”
"start": "node node_modules/react-native/local-cli/cli.js start",
"lint": "eslint *.js **/*.js",
"images": "node scripts/images.js"
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest",
"lint": "eslint *.js **/*.js",
"images": "node scripts/images.js"
}
"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