Flight 6
In this major release we have focused on updating core dependencies for Flight and it's build tools. This includes packages like Webpack, React and Apollo, all of which have undergone major releases themselves. Focus has also been on improving performance and resolve high and critical vulnerabilities in third-party libraries.
Breaking changes
-
Updated Apollo to 3.7. Apollo is no longer supporting libraries like
@apollo/react-hooks
and have all been moved inside the@apollo/client
package. In previous versions you were able to import from eitherapollo-react
or@apollo/react-hooks
etc. This is no longer supported, and all imports need to be updated to@apollo/client
. - Updating React to React 18.2 is not necessarily a breaking change but comes with a few caveats, the main one being the hydration process. When server-side rendering React 16, the HTML needed to be identical on the server and client. While this is still true, React 18 is not as forgiving as React 16.
-
A
linaria.config.js
is required in root directory.
Each breaking change is described in detail below.
Other changes
-
Flight 6 adds support for TypeScript
(4.9.5)
in your local project, you may add your own
tsconfig.json
- Flight 6 adds support for Tailwind (3.3.2)
- Flight 6 builds using latest Webpack (5.87.0)
- Flight 6 uses latest React (18.2.0)
- Flight 6 uses latest Apollo Client (3.7.15)
-
Flight 6 now code splits React, Node, Apollo and Sentry since these dependencies rarely change and are only included by the framework. Each output have the following structure
react-[flight-version].vendor.js
,node-[flight-version].vendor.js
etc. Which allows for a more agressive caching strategy. - Remove server side code leakage from Template Trend client bundle.
Migration steps
- Upgrade Flight dependencies.
- Upgrade React dependencies
- Update third-party libraries to support React 18. If not supported, replace with a compatible library.
-
Remove
graphql
,react-modal
and anythingapollo
frompackage.json
since we're relying on the ones from Flight. - Update Apollo throughout project
- Readd implementation if using GoogleFont or TypeKit components.
Upgrade Flight dependencies
"@jetshop/core": "^6.0.0",
"@jetshop/ui": "^6.0.0",
"@jetshop/intl": "^6.0.0",
"@jetshop/react-scripts": "^6.0.0",
If the project is using any other @jetshop-related packages, they should also be upgraded to lastest version to avoid any potential compatibility issues.
Update Apollo
This is easily done with search and replace throughout the project. If using hooks like useQuery
, useMutation
or useApolloClient
they should be imported from @apollo/client
. If you're still using Apollo render prop components like Query
or Mutation
, they should now be imported from @apollo/client/react/components
. Note that Flight previously allowed Apollo hooks to be imported from both react-apollo
and @apollo/react-hooks
. Make sure this is no longer the case and only import from @apollo/client
.
Apollo now clearly states the following:
⚠️ Note: To avoid a network request, all of a query's requested fields must already be present in the cache. If the detail view's query fetches field that the list view's query didn't, Apollo Client considers the cache hit to be incomplete, and it executes the full query over the network
In other words, make sure to always query the same fields on each view or component to enable correct caching.
More on debugging Apollo now includes local debugging information, read more about invariant violations and how to resolve them here: https://github.com/apollographql/invariant-packages.
Upgrade to React 18
"react": "^18",
"react-dom": "^18",
In most cases, simply upgrading to React ^18 may be all that you need to do. In other cases, you may encounter some hydration errors that need to be addressed. While React is still able to recover from some hydration errors, it is important to handle these errors as bugs and address them accordingly. Some common pitfalls in Flight projects include:
- Rendering different data on the server and the client.
-
Using checks like
typeof window !== 'undefined'
in your rendering logic.
Troubleshooting server and client data issues can be challenging. Commenting out specific code sections may be necessary to isolate the problematic component. Using -detailed-source-maps
(introduced in 6.0.2) argument on yarn start
enables more detailed sourcemaps.
Common culprits
Components using the search endpoint from StoreAPI are common culprits for causing hydration errors, since the endpoint might return the products in different orders between the server and the client. For these unavoidable cases, you may add the suppressHydrationWarning
prop to the rendering component.
Disabling and enabling JavaScript or performing a hard refresh can expose SSR issues. The server output should never display a loading state if not explicitly set.
Strict Mode
It is recommended to add StrictMode
in your Shop.[tsx|jsx|js]
, like so:
<React.StrictMode>
<MyApp />
</React.StrictMode>
Linaria or Tailwind?
Flight now supports Tailwind, and you are able to use both; however, using only one is recommended. If the project is using Linaria and @jetshop/ui
a linaria.config.js
is required in the root directory. In later Flight versions this is added by default, if this is not the case this file needs to be added with module.exports = {}
contents.
@jetshop/core
no longer dependens on @jetshop/ui
, which means you're allowed to run a Flight project without @jetshop/ui
and use Tailwind as your CSS framework instead. To use Tailwind, add a fully functional tailwind.config.js
in the root directory.
Readd GoogleFont and TypekitFont components
"store-css": "latest",
If the project is using any of the injectFont
and types
from @jetshop/core/components/Fonts/injectFont
as it's still available. You may keep the TypeScript extension since it's now supported.
Add the missing store-css
package to your project since it has been removed from @jetshop/core
. The css
function from store-css
now only supports one argument, change the function to do so (but since you're using TypeScript now you're already aware of this):
.css({
url: `previous_first_argument_url`,
crossOrigin: 'anonymous',
storage: 'session'
})
It is recommended to use locally hosted fonts and the CustomFont
component instead. Read more on the subject here.
Remove server side code from client bundle
Remove createFacebookTracker
from shop.config.(j|t)s
, if you're still using it, it should only be present in the server code from now on.
In the server entry, spread the rest of the config and add serverTrackersEntry
entry like so:
import createFacebookTracker from '@jetshop/core/server/tracking/facebook';
export default createApp(<Shop />, {
...config,
serverTrackers: [
createFacebookTracker({
// Settings is configured from admin
pixelId: undefined
token: undefined
})
]
});
State batching
In React 18 state changes work slightly differently from earlier versions. The state changes are sometimes batched together and executed all at once to improve performance. This might lead to situations where some components stop working unexpectedly after the upgrade to Flight 6. Typical such components are category menu flyouts with click detection, where the same click triggers the menu to open and then immediately closes it again. You can often work around this with useEffect
or a simple timeout. Test all interactive components thoroughly after upgrading, in both mobile and desktop layout.
Analyze final bundle(s)
Add "build:analyze": "ANALYZE=web yarn build",
as a part of package.json scripts, then run the command to inspect your bundle and remove any erroneously added dependencies before deploying it to production. Read more: https://github.com/webpack-contrib/webpack-bundle-analyzer.
Resolving multiple bn.js entries By specifying a pinned bn.js version as resolution, it is possible to resolve multiple entries. For example:
"resolutions": {
"format-message-estree-util": "npm:@jetshop/format-message-estree-util",
"bn.js": "^5.0.0"
}
Sentry
In previous Flight versions, Sentry modules were included by default in the bundle even if it was not used. In 6.0.4
we are conditionally including these modules if the USE_SENTRY=true
environment variable is present in the root .env
file.