@startupjs/babel-plugin-dotenv
Advanced tools
Changelog
0.44.0 (2022-03-14)
No breaking changes
Fix multiple useValue
hook initialization at each rendering. Now the hook works like useState
in react.
const [value, $value] = useValue(Math.random())
return pug`
Button(onPress=() => $value.set(value + 1)) Increment
`
In this example, the value
did not increase when the button was clicked because the next initialization was performed with a new Math.random()
value.
Changelog
0.43.0 (2022-02-14)
No breaking changes
Added automatic caching for styles and creation of scoped models during react render.
This is considered to be an experimental feature. By default it's turned OFF
so nothing should break whatsoever.
To turn in ON
, pass observerCache: true
to the startupjs
preset in babel.config.js
:
['startupjs/babel.cjs', {
...,
observerCache: true
}]
To make sure caching is enabled, check the value of window.__startupjs__.DEBUG.cacheEnabled
in browser console.
Cache will be enabled for all components. You can explicitly prohibit a specific component from using cache by passing { cache: false }
to its observer()
:
export default observer(function Test ({ frequentlyChangedRandomColor }) {
return pug`
Div(style={ backgroundColor: frequentlyChangedRandomColor })
`
}, { cache: false })
After enabling caching you must carefully test your whole application because some components might have been relying on excessive renderings to function properly. So you might have to fix some things in your codebase to account for optimized rerenders.
Examples:
cache pure style
. This will only work if you have observer
imported in the current file, this way we don't screw up the 3rd-party libraries which don't use startupjs.
export default observer(function Test () {
return pug`
Div(style={ backgroundColor: 'red' })
`
})
cache pure styleName
or any combination of part
, style
, *Style
, *StyleName
export default observer(function Test () {
return pug`
Div.div
`
styl`
.div
background-color red
`
})
cache scoped model created with .at()
and .scope()
export default observer(function Games () {
const [games, $games] = useQuery('games', { active: true })
return pug`
each game in games
Game($game=$games.at(game.id))
`
})
const Game = observer(({ $game }) => {
const game = $game.get()
return pug`
Span= game.title
`
})
The last example is especially important since writing code in this way simplifies code a lot in many places. Now you can (and should) pass models whenever possible to child components as arguments, instead of passing an id
and using useDoc
or useLocalDoc
.
Earlier in situations when you run useQuery
in the parent component and then render each item as a separate component the only way to do it easily and properly was to pass an item id and then do a useLocalDoc
. And you had to use useLocalDoc
, otherwise useDoc
will create an additional doc-only subscription and wait for it. Now this usecase is handled for you automatically, you just create a scoped model for the item inline using $items.at(item.id)
and pass it as $item
into the child component.
So this change alone will save you from making extra queries in many situations and will make the code easier to follow and more performant overall.
Changelog
0.41.0 (2022-01-11)
You should not use pug
function without importing it anymore. Import it from startupjs
module:
import React from 'react'
import { pug, observer } from 'startupjs'
import { Span } from '@startupjs/ui'
export default observer(() => pug`
Span Hello World
`)
Update linter configuration to use new babel parser module
Replace babel-eslint
dependency with a new one. Run:
yarn remove babel-eslint && yarn add -D @babel/eslint-parser
Replace "parser"
in your .eslintrc.json
:
// replace line:
"parser": "babel-eslint",
// with the following:
"parser": "@babel/eslint-parser",
For proper TypeScript support copy the following tsconfig.json
file to the root of your project:
Changelog
0.40.0 (2021-11-12)
You can't use named imports from .json
files anymore. Instead import the whole json file and then do the manual destructuring:
// OLD
import { BORDER_WIDTH, STRIPE_PUBLIC_KEY } from './constants.json'
// NEW
import CONSTANTS from './constants.json'
const { BORDER_WIDTH, STRIPE_PUBLIC_KEY } = CONSTANTS
Webpack 5 changed the way it parses modules to use ESM modules wherever possible. Because of this some default
imports from old CommonJS modules might be imported not directly but inside the .default
field.
If you receive errors from React that it can't render something because it received an object
-- this probably means that you need to get your default import from .default
field manually:
// OLD
import DrawerLayout from 'react-native-drawer-layout-polyfill'
// NEW
import DrawerLayoutModule from 'react-native-drawer-layout-polyfill'
const DrawerLayout = DrawerLayoutModule.default || DrawerLayoutModule
Same goes for errors like object is not a function
when your default import is actually expected to be a function. You'll have to do the same trick as above.