Upgrading from 4.1.0 to 4.2.0

This article will guide you through the process of upgrading your existing Webiny project v4.1.0 to v4.2.0. Unfortunately, automatic updates are not possible when we introduce slight changes to the project structure or configuration so we have to do it manually.

before we begin

This article assumes that your project is in the original state for v4.1.0. If you've modified the project in any way, pay extra attention to the modifications we're introducing and apply your changes accordingly.

1. Commit your local changes

Make sure you commit all of your local changes so you can undo the migration in case something goes wrong. To make sure everything is committed, run git status.

2. Update project files

Verify which project template you used to create your Webiny project. Open your webiny.root.js and look at template key. If it contains a package name @webiny/cwp-template-full - you have a full Webiny project. If it's @webiny/cwp-template-cms, your project is a cms project, accordingly.

webiny.root.js

In this update we greatly improved how CLI plugins and hooks are being registered and processed. In this file, we now require all the plugins directly, which allows us to use factory functions with options (if necessary). Hooks are now also plugins, and not a separate concept, unlike in the 4.1.0.

Open your webiny.root.js and update the cli section to look like this:

webiny.root.js
cli: {
plugins: [
require("@webiny/cli-plugin-deploy-components")(),
require("@webiny/cwp-template-full/hooks/api")(),
require("@webiny/cwp-template-full/hooks/apps")(),
require("@webiny/cli-plugin-scaffold"),
require("@webiny/cli-plugin-scaffold-graphql-service"),
require("@webiny/cli-plugin-scaffold-lambda")
];
}

apps/admin/webiny.config.js

Injection of ENV variables into React was also restructured. In the previous version, we used to inject values from api stack directly into .env.json of each React app, right after api stack deployment. We no longer do that. Instead, we load whatever ENV variables we want, and set them into process.env, right before initiating a webpack build. This gives us, developers, more freedom to handle ENV variables however we want. It also removes any special meaning from .env.json and simplifies project state management.

Open your apps/admin/webiny.config.js file and replace the whole file contents with the following:

apps/admin/webiny.config.js
const { startApp, buildApp, buildAppHandler } = require("@webiny/project-utils");
const { setEnvironmentFromState } = require("@webiny/cli-plugin-deploy-components/utils");
const map = {
REACT_APP_USER_POOL_REGION: "${cognito.userPool.Region}",
REACT_APP_GRAPHQL_API_URL: "${cdn.url}/graphql",
REACT_APP_API_URL: "${cdn.url}",
REACT_APP_USER_POOL_ID: "${cognito.userPool.Id}",
REACT_APP_USER_POOL_WEB_CLIENT_ID: "${cognito.appClients[0].ClientId}"
};
module.exports = {
commands: {
async start({ env, stack, ...options }, context) {
// Set environment variables for given project environment and stack.
// This will load state values using the provided map and
// populate process.env, overwriting existing values.
await setEnvironmentFromState({ env, stack, map }, context);
// Start local development
await startApp(options, context);
},
async build({ env, stack, ...options }, context) {
// Set environment variables for given project environment and stack.
// This will load state values using the provided map and
// populate process.env, overwriting existing values.
await setEnvironmentFromState({ env, stack, map }, context);
// Bundle app for deployment
await buildApp(options, context);
// Build Lambda handler which will serve files to CDN
await buildAppHandler(options, context);
}
}
};

apps/admin/package.json

Since we no longer have our api stack values in .env.json, we are now free to use any stack we want, with any environment we want for any app script. This unlocks different possibilities for development, like, experimental stacks, quickly switching APIs our local app is accessing, etc.

Open the apps/admin/package.json and replace the scripts section with the following:

apps/admin/package.json
"scripts": {
"start": "env-cmd -r .env.json -e default webiny run start --env=local --stack=api",
"build:dev": "env-cmd -r .env.json -e default webiny run build --env=dev --stack=api",
"build:prod": "env-cmd -r .env.json -e default webiny run build --env=prod --stack=api"
},

stop here!

The following 2 files only apply to the full project template. If your project is a cms, you should skip them, and continue at 3. Updating dependencies.

apps/site/webiny.config.js

Open apps/site/webiny.config.js and replace the whole file contents with the following:

apps/site/webiny.config.js
const {
startApp,
buildApp,
buildAppHandlerWithSSR,
buildAppSSR
} = require("@webiny/project-utils");
const { setEnvironmentFromState } = require("@webiny/cli-plugin-deploy-components/utils");
const map = {
REACT_APP_GRAPHQL_API_URL: "${cdn.url}/graphql",
REACT_APP_API_URL: "${cdn.url}"
};
module.exports = {
commands: {
async start({ env, stack, ...options }, context) {
// Set environment variables for given project environment and stack.
// This will load state values using the provided map and
// populate process.env, overwriting existing values.
await setEnvironmentFromState({ env, stack, map }, context);
// Start local development
await startApp(options, context);
},
async build({ env, stack, ...options }, context) {
// Set environment variables for given project environment and stack.
// This will load state values using the provided map and
// populate process.env, overwriting existing values.
await setEnvironmentFromState({ env, stack, map }, context);
// Bundle app for deployment
await buildApp(options, context);
// Build Lambda handler which will serve files to CDN
await buildAppHandlerWithSSR(options, context);
},
async buildSsr({ env, stack, ...options }, context) {
// Set environment variables for given project environment and stack.
// This will load state values using the provided map and
// populate process.env, overwriting existing values.
await setEnvironmentFromState({ env, stack, map }, context);
// Build app for deployment
await buildApp(options, context);
// Build SSR bundle using app build output
await buildAppSSR({ ...options, app: __dirname }, context);
}
}
};

apps/site/package.json

Open apps/site/package.json and replace the scripts section with the following:

"scripts": {
"build:dev": "env-cmd -r .env.json -e default webiny run build --env=dev --stack=api",
"build:prod": "env-cmd -r .env.json -e default webiny run build --env=prod --stack=api",
"build:ssr:dev": "env-cmd -r .env.json -e default webiny run build-ssr --env=dev --stack=api",
"build:ssr:prod": "env-cmd -r .env.json -e default webiny run build-ssr --env=prod --stack=api",
"start": "env-cmd -r .env.json -e default webiny run start --env=local --stack=api"
},

3. Updating dependencies

Now your project files are up-to-date, and we can update the dependencies:

rm yarn.lock && yarn

To verify that your project is, in fact, 4.2.0, run: yarn list @webiny/cli. The output should be similar to this:

yarn list @webiny/cli
โ””โ”€ @webiny/[email protected]

If your @webiny packages are still at the 4.1.0 version, try upgrading them using one of the following commands:

yarn upgrade --scope=@webiny
// or
yarn upgrade-interactive

4. Deploy your API

If you've reached this point successfully, the last thing to do is to deploy your api:

yarn webiny deploy api --env=local

And you're ready for development! ๐Ÿš€


need help?

If you've encountered problems with anything in this guide, please do reach out to us using our Github or even better - our Slack Community. We'll be glad to help!

Last updated on by Pavel Denisjuk