# Upgrade to v2

Upgrade a project that was generated before v2 of PWA Kit to take advantage of the framework and tooling improvements made in v2.

:::note
Upgrading doesn’t automatically add any new storefront features from the Retail React App template, but you can manually add them using the latest Retail React App code as a reference.
:::

## What’s New

We’ve added lots of new features to PWA Kit v2, including:

🥳 **TypeScript support**. The build tools now support TypeScript by default—without having to update the configuration files for Babel or Webpack.

🧰 **An** **updated development server** that supports hot reloading on the server side and makes it possible to support hot reloading on the client side in a future release.

🤓 **An all-new command-line tool** called `pwa-kit-dev` that bundles our recommended development tools like Webpack, Babel, and Jest to support zero-config project templates.

🖌️ **Experimental support for non-React apps** for those users interested in using Managed Runtime to host other Express-based apps (not just the Retail React App).

## Upgrade Process

:::note
If you haven’t generated a PWA Kit project yet, see the [Quick Start](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/quick-start.md) guide to generate a new project using v2.
:::

We made the upgrade process from v1.5 to v2 as easy as possible—with changes required to only a small number of existing project files.

If you’re upgrading from v1.4 (or earlier), the process is the same as upgrading from v1.5, but with one extra step. Update all `import` statements involving `pwa-kit-react-sdk` so that the import path doesn’t include the `dist/` folder anymore.

```javascript
// Import with old path
- import {getAssetUrl} from 'pwa-kit-react-sdk/dist/ssr/universal/utils'

// Import with new path
+ import {getAssetUrl} from 'pwa-kit-react-sdk/ssr/universal/utils'
```

Read on to complete the remaining upgrade tasks (for both v1.5 and v1.4 users).

## Changes to package.json

To start the upgrade process, open `package.json` from the root directory of your project.

Add and install three new `pwa-kit-*` packages:

```json
"pwa-kit-dev": "2.0.0",
"pwa-kit-react-sdk": "2.0.0",
"pwa-kit-runtime": "2.0.0",
```

Remove the following dependencies. The new `pwa-kit-dev` tool now takes care of these dependencies for you. (If the version numbers don’t exactly match the ones you have in your project, remove them anyway.)

```json
"@babel/cli": "^7.4.4",
"@babel/core": "^7.4.5",
"@babel/parser": "^7.5.5",
"@babel/plugin-proposal-object-rest-spread": "^7.4.4",
"@babel/plugin-transform-async-to-generator": "^7.7.0",
"@babel/plugin-transform-modules-commonjs": "^7.4.4",
"@babel/plugin-transform-object-assign": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.6.2",
"@babel/preset-env": "^7.4.5",
"@babel/preset-react": "^7.0.0",
"@babel/register": "^7.4.4",
"@babel/runtime": "^7.7.2",
"@babel/runtime-corejs2": "^7.4.5",
"@babel/traverse": "^7.5.5",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.6.3",
"babel-loader": "^8.0.6",
"babel-plugin-dynamic-import-node-babel-7": "^2.0.7",
"babel-plugin-formatjs": "^10.2.3",
"@loadable/babel-plugin": "^5.13.2",
"@loadable/server": "^5.15.0",
"@loadable/webpack-plugin": "5.15.0",
"eslint": "7.31.0",
"eslint-config-prettier": "4.0.0",
"eslint-import-resolver-webpack": "0.10.0",
"eslint-plugin-header": "^3.1.1",
"eslint-plugin-import": "2.23.4",
"eslint-plugin-jsx-a11y": "6.4.1",
"eslint-plugin-prettier": "3.0.1",
"eslint-plugin-react": "7.24.0",
"jest": "^26.6.3",
"jest-cli": "^26.6.3",
"webpack": "^5.39.1",
"webpack-cli": "^4.7.2"
```

Convert these NPM scripts to use the new `pwa-kit-dev`:

```json
"scripts": {
    ...
    "format": "pwa-kit-dev format '\"**/*.{js,jsx}\"'",
    "lint": "pwa-kit-dev lint '\"**/*.{js,jsx}\"'",
    "prod:build": "npm run build-translations && pwa-kit-dev build",
    "push": "npm run prod:build && pwa-kit-dev push",
    "save-credentials": "pwa-kit-dev save-credentials",
    "start": "cross-env NODE_ICU_DATA=node_modules/full-icu pwa-kit-dev start",
    "test": "pwa-kit-dev test",
    ...
},
```

## Changes to babel.config.js

Open `babel.config.js` from the root directory of your project and **replace the entire file** with this one line:

```javascript
module.exports = require('pwa-kit-dev/configs/babel/babel-config')
```

If you have made any customizations to your Babel configuration, add them below the call to the `require()` function.

## Changes to webpack.config.js

If you haven’t customized the `webpack.config.js` file from the root directory of your project, delete it. A default configuration file is loaded automatically for you.

If you do have customizations, you must add them after calling the `require()` function first to get the base configuration:

```javascript
const config = require('pwa-kit-dev/configs/webpack/config')

// Add your customizations here
const clientConfig = config.find((cnf) => cnf.name === 'client')

module.exports = config
```

## Changes to ssr.js

In v2, the method being used to create the Express server has been changed. The `createApp` method has been deprecated and replaced with a method called `getRuntime`.

The `getRuntime` method returns a runtime object. You can use the `createHandler` method to create Managed Runtime compatible lambda handlers. The second argument is a callback function that gives you access to the Express app, allowing you to customize the Express app. For example you can use the callback function to implement custom endpoints.

```javascript
- import {createApp} from 'pwa-kit-react-sdk/ssr/server/express'
+ import {getRuntime} from 'pwa-kit-runtime/ssr/server/express'

const options = {
    // For example, if you have a different build directory, make sure this buildDir is correct
    buildDir: path.resolve(process.cwd(), 'my-build-dir'),
    ...
}

- const app = createApp(options)
+ const runtime = getRuntime()

const {handler} = runtime.createHandler(options, (app) => {
    ...
    // For example, if you have added a custom endpoint, you can bring its implementation to here
    app.get('/custom-endpoint', () => {})

    app.get('*', runtime.render)
})
// SSR requires that we export a single handler function called 'get', that
// supports AWS use of the server that we created above.
export const get = handler
```

In v2, `body-parser` library is removed from the express app. If you have custom endpoints that requires `req.body` parsed and populated, install the `body-parser` library by running `npm install body-parser` and include the body parser library in ssr.js:

```javascript
import bodyParser from 'body-parser'

const {handler} = runtime.createHandler(options, (app) => {
  // add this before the custom endpoints which access `req.body`
  app.use(bodyParser.json())
})
```

## Import getConfig Differently

Whenever `getConfig` is used, import it from the new `pwa-kit-runtime` package:

```javascript
- import {getConfig} from 'pwa-kit-react-sdk/ssr/universal/utils' // Old package
+ import {getConfig} from 'pwa-kit-runtime/utils/ssr-config' // New package
```

## Changes to worker/main.js

Open `worker/main.js` and add this new route:

```javascript
// Place your Workbox route configurations here, eg:
// workbox.routing.registerRoute(...)

// Never cache dev-server internals.
workbox.routing.registerRoute(
  /^http:\/\/localhost:3000\/__mrt/,
  new workbox.strategies.NetworkOnly()
)
```

## Proxy Settings

In v2, the proxy settings for each Managed Runtime environment must be defined explicitly. In v1, there was a fallback mechanism that allowed a Managed Runtime environment to use the same proxy settings as the local development environment. The fallback mechanism is not supported for v2 projects due to performance and maintenance issues.

To learn how to configure proxy settings for Managed Runtime environments using the Runtime Admin tool or the Managed Runtime API, see [Proxy Requests](/docs/commerce/b2c-commerce/guide/proxying-requests.md).

You can also take advantage of the new [environment-specific configurations](/docs/commerce/b2c-commerce/guide/configuration-options.md#environment-specific-configurations) feature in v2 to configure proxy settings for your Managed Runtime environments.

## Node 14 Support

Before v2, PWA Kit supported Node 12.x. With v2, you must ensure that your code works with Node 16+.

## Testing Your Changes

To test whether your changes have been made successfully, run the following commands:

1. `npm start` to verify that the app is able to run locally.
2. `npm run build` for verifying that the build process is successful.
3. `npm run push` (and deploy via Runtime Admin) to verify that deploying a bundle is successful.
