5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

実際に業務で行った Amplify v5->v6 の移行作業

Last updated at Posted at 2024-06-19

記事の目的

aws-amplify の v6 から Next.JS に寄り添った機能を提供するようになり、我が社で使っていた amplify を v5->v6 へアップグレードすることになった。
その際に実際に起きた変更点や docs からは掴みにくい点、かかった時間について述べる

ちなみに変更ファイル数 61, 変更行数 約30k行, 作業時間は 25時間 ほどであった.
変更行の内訳

  • package-lock.json 19k 行 (63%)
  • amplify が自動生成する graphQL の query や 型定義 9.7k 行 (32%)
  • 残り, 手動による書き換え 1k 行 (3%)

package.json

一部抜粋
変更の前後で package.jsondependencies がどう変わったかを載せる

package.json dependencies
- "@aws-amplify/api": "^5.1.0",
- "@aws-amplify/api-graphql": "^3.2.0",
+ "@aws-amplify/api-graphql": "^4.1.4",
- "@aws-amplify/storage": "^4.5.17",
- "@aws-amplify/ui": "^5.6.1",
- "@aws-amplify/ui-react": "^4.6.1",
+ "@aws-amplify/adapter-nextjs": "^1.2.3",
+ "@aws-amplify/ui-react": "^6.1.12",
+ "@aws-crypto/sha256-js": "^5.2.0",
- "aws-amplify": "^5.2.1",
+ "aws-amplify": "^6.3.4",
- "next": "13.4.2",
+ "next": "^14.2.3",

:point_up: point

@aws-amplify/api, @aws-amplify/storage といったように、 aws-amplify package に付随した package を一部インストール不要になり、 aws-amplify 内に組み込まれるようになった. ただし一部残ったものもある. プロジェクトによっては不要かもしれない

  1. @aws-amplify/api-graphql
    1. このパッケージから排出される GraphQLOptionsV6, GraphQLResult が必要だっためインストール
  2. @aws-amplify/adapter-nextjs
    1. Next のサーバーサイドでの処理を遂行するための機能を提供したもの
    2. request や cookies をもとに認証をサーバーで行なうための機能がメイン
  3. @aws-amplify/ui-react
    1. front で認証結果を React.Provider を活用して早期アクセスを可能にするもの( <Authenticator.Provider> )。自前で Provider を書いたりしたら別に要らない
    2. amplify/ui を使っていたらいるのかも? amplify/ui は使っていないので詳しくない
  4. @aws-crypto/sha256-js
    1. @aws-amplify/ui-react の内部で使っているらしく、明示的に install しないとエラーになった

migration 作業内容

migration に費やした時間は主に以下であった

  1. v5 で提供された package を v6 のものへ変更していくコードの変更
  2. 元のままでは動かなくなった jest の設定の修正
  3. SSR コードの書き換え

コードの変更

基本的には下記の migration guide に従って書き換えていくだけで大抵は対応できる.

  1. auth
  2. storage
  3. rest API

graphQL API はなぜか上記と同じように migration guide を用意してくれてなかったので、このセクションでは graphQL の migration を一部紹介と、上記の docs からはわかりにくかった変更内容を紹介する

graphQL の migration

公式の docs はないが、他の package の migration を踏んだら、 graphQL の migration 方法もなんとなく見当がつくので、そこまで困らないと思う.

API call 方法

v5

callAppSync.ts
import {API} from 'aws-amplify';
import * as mutations from './graphql/mutations';

const todoDetails = {
  name: 'Todo 1',
  description: 'Learn AWS AppSync'
};

API.graphql({
    query: mutations.createTodo,
    variables: { input: todoDetails }
})

v6

import { generateClient } from 'aws-amplify/api';
import * as mutations from './graphql/mutations';

const client = generateClient();

const todoDetails = {
  name: 'Todo 1',
  description: 'Learn AWS AppSync'
};

const newTodo = await client.graphql({
  query: mutations.createTodo,
  variables: { input: todoDetails }
});

client 生成時 (generateClient ) にデフォルトとなる認証方式を設定できたりして、 API client の作成がちょっと楽になった.

その他わかりにくかった点

apiURLの取得方法
amplify の環境を pull したときにできる config を用いて backend リソースへアクセスするための URL の取得方法. どこにも変更書いてないと思う

v5

import {API} from 'aws-amplify';
const apiUrl = await API.endpoint('someApi')

v6

import {Amplify} from 'aws-amplify';
 const apiUrl = Amplify.getConfig().API?.REST?.someApi.endpoint;

session token の取得方法
これはどこかに書いてたかも

v5

import {API, Auth} from 'aws-amplify';

const token = await Auth.currentSession()).getIdToken().getJwtToken()
const auth = `Bearer ${token}`

v6

import {fetchAuthSession} from 'aws-amplify/auth';

const token = await fetchAuthSession().tokens?.idToken?.toString()
const auth = `Bearer ${token}`

jest.config の変更

我々の config の設定がまずかったのか、既存の以下の jest の設定のままでは、エラーが出るようになった

jest.config.js
const nextJest = require('next/jest');

const createJestConfig = nextJest({
  dir: './',
});

/** @type {import('jest').Config} */
const customJestConfig = {
  testEnvironment: 'jest-environment-jsdom',
  globals: {
    'ts-jest': {
      useESM: true,
    },
  },
  preset: 'ts-jest/presets/default-esm',
  transform: {},
  extensionsToTreatAsEsm: ['.tsx', '.ts'],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
    uuid: require.resolve('uuid'),
  },
};

module.exports = createJestConfig(customJestConfig);

:point_down: error message

  ● Test suite failed to run
    Jest encountered an unexpected token
    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
    By default "node_modules" folder is ignored by transformers.
    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation
    Details:
    /builds/strategitjp/joint/basis/ui/hosting/node_modules/rxjs/dist/esm5/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { Observable } from './internal/Observable';
                                                                                      ^^^^^^
    SyntaxError: Unexpected token 'export'
      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1505:14)

ts-jest の設定を見直したりしてみたりしたが変わらず、これを参考に transformIgnorePatterns を変えてみたが変わらずエラー。
初心に戻って Next が公式で提供している jest の設定にしてみたら通過。

preset がよくなかったのかな・・・?
jest の config は CJS, ESM の歴史も把握しとく必要があってなかなか複雑

行き詰まったら公式に倣うこと

SSR の設定

以下が公式の migration
素晴らしいほどに Next の SSR がしやすくなっている.

request, response instance を withSSRContext に渡してサーバー処理を行うのが v5 だったが、 cookie だけでその処理を実現できるようになっており、 server component をかけるようになった。

ただし、なぜか我々のコードでは以下のエラーが出ていた

No current user
underlyingError: Error: Network error

が、原因は msw の設定がまずかったらしい。
msw はその時点で使っていなかったので、削除することで無事 SSR できるようになった.

まとめ

変更点はそれなりにあるが、総じてみると、「変更の仕方を知ってれば全然大したことない変更量だな」と感じた。
プロジェクトの依存パッケージのアップグレードは課題として挙げられがちだが、今回の amplify のアップグレードはかなり楽な方であったであろう。(何より詰まったら AWS がサポートしてくれるので :sweat: )

さて、我々にはまだ mantine の v6 -> v7 作業が残っている... :angel:

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?