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 either apollo-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

Copy
Copied
  "@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

Copy
Copied
  "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:

Copy
Copied
<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

Copy
Copied
  "store-css": "latest",

If the project is using any of the or components, copy the one(s) needed from here. Update the file to import 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):

Copy
Copied
.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:

Copy
Copied
import createFacebookTracker from '@jetshop/core/server/tracking/facebook';

export default createApp(<Shop />, {
  ...config,
  serverTrackers: [
    createFacebookTracker({
  // Settings is configured from admin
      pixelId: undefined
      token: undefined
    })
  ]
});

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:

Copy
Copied
"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.

Copyright © Norce 2023. All right reserved.