v1.3.0

  • 使用するvisual-parts-sdkをv1.3.0にアップデートしました。( プロジェクトの情報を取得するAPI が追加されました。これを使ってプロジェクトのUUIDを得ることで、intdash APIを使用してプロジェクトに紐づくリソースを参照することができます。)

  • 複数の依存パッケージを更新しました。

  • 上記パッケージの更新に伴い、webpack、Jestのメジャーバージョンを更新し、一部の設定ファイル、ソースコードを変更しました。詳細については後述の移行手順をご確認ください。

  • ビジュアルパーツをサーバーにをデプロイするときのNginxの設定を更新しました(デベロッパーガイドの記述のみの更新です)。

v1.2.0からv1.3.0への移行手順

data-viz-create-visual-parts-react v1.2.0を使用して作成したワークスペースは、以下の操作を行うことで、v1.3.0を使用して作成したワークスペースと同じ状態にすることができます。

注釈

  • この移行手順を実行しなくても、v1.2.0以下で作成したビジュアルパーツは継続して使用することが可能です。

  • 作成済みのワークスペースをv1.3.0に合わせたい場合のみ、この以降手順を実行してください。

  1. ワークスペース直下の package.json を以下のように更新することで、@data-viz-create-visual-parts-sdkを含む依存パッケージを更新します。

    package.json

    diff --git a/package.json b/package.json
    index 3205f8e..8ace43a 100644
    --- a/package.json
    +++ b/package.json
    @@ -58,105 +58,98 @@
         "test:watch": "jest --watchAll",
         "type-watch": "tsc -p . --noEmit --incremental -w"
       },
    -  "resolutions": {
    -    "@types/estree": "0.0.50",
    -    "@types/react": "17.0.33",
    -    "@types/react-dom": "17.0.10"
    -  },
       "dependencies": {
    -    "@aptpod/data-viz-visual-parts-sdk": "^1.2.0",
    +    "@aptpod/data-viz-visual-parts-sdk": "^1.3.0",
         "binary-search-bounds": "^2.0.5",
         "chart.js": "^2.9.4",
    -    "core-js": "3.10.2",
    -    "d3": "^6.6.2",
    -    "react": "17.0.2",
    +    "core-js": "3.26.1",
    +    "d3": "^6.7.0",
    +    "react": "^18.2.0",
         "react-chartjs-2": "^2.11.2",
    -    "react-dom": "17.0.2",
    +    "react-dom": "^18.2.0",
         "reboot.css": "1.0.4",
    -    "styled-components": "^5.2.3",
    +    "styled-components": "^5.3.6",
         "zod": "^1.11.17"
       },
       "devDependencies": {
    -    "@axe-core/react": "4.3.1",
    -    "@babel/core": "7.13.16",
    -    "@babel/eslint-parser": "^7.13.14",
    -    "@babel/eslint-plugin": "^7.13.16",
    -    "@storybook/addon-actions": "6.4.9",
    -    "@storybook/addons": "6.4.9",
    -    "@storybook/core": "^6.4.9",
    -    "@storybook/react": "6.4.9",
    +    "@axe-core/react": "4.5.1",
    +    "@babel/core": "7.20.2",
    +    "@babel/eslint-parser": "^7.19.1",
    +    "@babel/eslint-plugin": "^7.19.1",
    +    "@storybook/addon-actions": "^6.5.13",
    +    "@storybook/addon-essentials": "^6.5.13",
    +    "@storybook/addons": "^6.5.13",
    +    "@storybook/builder-webpack5": "^6.5.13",
    +    "@storybook/core": "^6.5.13",
    +    "@storybook/manager-webpack5": "^6.5.13",
    +    "@storybook/react": "^6.5.13",
         "@testing-library/react-hooks": "5.1.3",
    -    "@types/babel__core": "7.1.16",
    +    "@types/babel__core": "7.1.20",
         "@types/browserslist": "4.8.0",
         "@types/caniuse-lite": "1.0.1",
    -    "@types/chart.js": "^2.9.34",
    +    "@types/chart.js": "^2.9.37",
         "@types/core-js": "2.5.5",
    -    "@types/d3": "^6.7.5",
    -    "@types/eslint": "7.2.14",
    -    "@types/file-loader": "4.2.1",
    -    "@types/mini-css-extract-plugin": "1.4.3",
    -    "@types/optimize-css-assets-webpack-plugin": "5.0.4",
    -    "@types/prettier": "2.4.1",
    +    "@types/d3": "^7.4.0",
    +    "@types/eslint": "7.29.0",
    +    "@types/file-loader": "^5.0.1",
    +    "@types/jest": "^29.2.3",
    +    "@types/mini-css-extract-plugin": "2.5.0",
    +    "@types/optimize-css-assets-webpack-plugin": "5.0.5",
    +    "@types/prettier": "2.7.1",
         "@types/progress-bar-webpack-plugin": "2.1.2",
    -    "@types/prop-types": "15.7.4",
    -    "@types/react": "17.0.33",
    -    "@types/react-dom": "17.0.10",
    -    "@types/react-test-renderer": "17.0.1",
    -    "@types/styled-components": "^5.1.15",
    -    "@types/stylelint": "9.10.1",
    +    "@types/prop-types": "15.7.5",
    +    "@types/react": "^18.0.25",
    +    "@types/react-dom": "^18.0.9",
    +    "@types/react-test-renderer": "^18.0.0",
    +    "@types/styled-components": "^5.1.26",
    +    "@types/stylelint": "13.13.3",
         "@types/terser-webpack-plugin": "5.0.4",
         "@types/testing-library__react-hooks": "3.4.1",
    -    "@types/webpack": "5.28.0",
    -    "@types/webpack-bundle-analyzer": "3.9.4",
    -    "@types/webpack-dev-server": "^3.11.6",
    +    "@types/webpack": "^5.28.0",
    +    "@types/webpack-bundle-analyzer": "^4.6.0",
    +    "@types/webpack-dev-server": "^4.7.2",
         "@typescript-eslint/eslint-plugin": "^4.33.0",
         "@typescript-eslint/parser": "^4.33.0",
         "@typescript-eslint/typescript-estree": "^4.33.0",
         "babel-eslint": "10.1.0",
    -    "babel-loader": "8.2.3",
    -    "browserslist": "4.17.6",
    -    "caniuse-lite": "1.0.30001271",
    +    "babel-loader": "^9.1.0",
    +    "browserslist": "4.21.4",
         "cross-env": "^7.0.3",
    -    "css-loader": "5.2.7",
    -    "del-cli": "^3.0.1",
    -    "eslint": "7.24.0",
    +    "css-loader": "^6.7.2",
    +    "del-cli": "^5.0.0",
    +    "eslint": "7.32.0",
         "eslint-config-prettier": "^7.2.0",
         "eslint-import-resolver-webpack": "^0.13.2",
    -    "eslint-plugin-compat": "^3.9.0",
    +    "eslint-plugin-compat": "^3.13.0",
         "eslint-plugin-flowtype": "^5.10.0",
    -    "eslint-plugin-flowtype-errors": "^4.4.0",
    -    "eslint-plugin-import": "^2.22.1",
    +    "eslint-plugin-flowtype-errors": "^4.5.0",
    +    "eslint-plugin-import": "^2.26.0",
         "eslint-plugin-jest": "^24.7.0",
    -    "eslint-plugin-jsx-a11y": "^6.4.1",
    +    "eslint-plugin-jsx-a11y": "^6.6.1",
         "eslint-plugin-prettier": "^3.4.1",
    -    "eslint-plugin-react": "^7.23.2",
    -    "eslint-plugin-react-hooks": "^4.2.0",
    +    "eslint-plugin-react": "^7.31.10",
    +    "eslint-plugin-react-hooks": "^4.6.0",
         "eslint-plugin-unicorn": "^24.0.0",
    -    "file-loader": "6.2.0",
    -    "html-loader": "2.1.2",
    +    "file-loader": "^6.2.0",
    +    "html-loader": "^4.2.0",
         "husky": "^4.3.6",
    -    "image-webpack-loader": "7.0.1",
    -    "jest": "26.6.3",
    +    "image-webpack-loader": "^8.1.0",
    +    "jest": "^29.3.1",
         "lint-staged": "^10.5.4",
    -    "mini-css-extract-plugin": "1.5.1",
    +    "mini-css-extract-plugin": "^2.6.1",
         "npm-run-all": "4.1.5",
    -    "optimize-css-assets-webpack-plugin": "5.0.8",
    -    "prettier": "2.2.1",
    +    "optimize-css-assets-webpack-plugin": "^6.0.1",
    +    "prettier": "2.7.1",
         "progress-bar-webpack-plugin": "2.1.0",
    -    "prop-types": "15.7.2",
    +    "prop-types": "15.8.1",
         "react-storybook-addon-props-combinations": "1.1.0",
    -    "react-test-renderer": "17.0.2",
    -    "reg-keygen-git-hash-plugin": "0.10.17",
    -    "reg-notify-gitlab-plugin": "0.10.17",
    -    "reg-notify-slack-plugin": "0.10.17",
    -    "reg-publish-s3-plugin": "0.10.17",
    -    "reg-suit": "0.10.17",
    -    "regenerator-runtime": "0.13.9",
    -    "sort-package-json": "1.49.0",
    -    "source-map-loader": "^1.1.3",
    +    "react-test-renderer": "18.2.0",
    +    "regenerator-runtime": "0.13.10",
    +    "sort-package-json": "2.1.0",
    +    "source-map-loader": "^4.0.1",
         "storycap": "3.0.4",
    -    "style-loader": "2.0.0",
    -    "stylelint": "13.12.0",
    +    "style-loader": "^3.3.1",
    +    "stylelint": "13.13.1",
         "stylelint-a11y": "^1.2.3",
         "stylelint-config-prettier": "^8.0.2",
         "stylelint-config-property-sort-order-smacss": "^7.1.0",
    @@ -164,16 +157,16 @@
         "stylelint-config-styled-components": "^0.1.1",
         "stylelint-no-unsupported-browser-features": "^4.1.4",
         "stylelint-processor-styled-components": "^1.10.0",
    -    "terser-webpack-plugin": "4.2.3",
    -    "ts-jest": "26.4.4",
    -    "ts-loader": "8.1.0",
    -    "typescript": "^4.5.2",
    +    "terser-webpack-plugin": "^5.3.6",
    +    "ts-jest": "^29.0.3",
    +    "ts-loader": "9.4.1",
    +    "typescript": "^4.9.3",
         "url-loader": "4.1.1",
         "utility-types": "^3.10.0",
    -    "webpack": "4.46.0",
    -    "webpack-bundle-analyzer": "4.4.2",
    -    "webpack-cli": "^3.3.12",
    -    "webpack-dev-server": "^3.11.2"
    +    "webpack": "^5.75.0",
    +    "webpack-bundle-analyzer": "4.7.0",
    +    "webpack-cli": "^4.10.0",
    +    "webpack-dev-server": "^4.11.1"
       },
       "engines": {
         "node": ">=10.23.0"
     
    

    上記のパッチを適用後、以下のコマンドを実行してパッケージをインストールしてください。

    $ npm i
    
  2. ワークスペース直下にあるwebpackの設定ファイルを以下のように更新します。

    webpack.dev.js

    diff --git a/webpack.dev.js b/webpack.dev.js
    index 55f3444..d3d5214 100644
    --- a/webpack.dev.js
    +++ b/webpack.dev.js
    @@ -24,10 +24,6 @@ module.exports = {
           'storybook/src': path.join(__dirname, '.storybook/src'),
         },
       },
    -  node: {
    -    fs: 'empty',
    -    Buffer: false,
    -  },
       module: {
         rules: [
           // js(x) or ts(x)
    @@ -118,11 +114,13 @@ module.exports = {
         },
       ],
       devServer: {
    -    writeToDisk: true,
    -    contentBase: path.join(__dirname, 'debug'),
    +    devMiddleware: {
    +      writeToDisk: true,
    +    },
    +    static: {
    +      directory: path.join(__dirname, 'debug'),
    +    },
         port: 8080,
         compress: true,
    -    // dissable live reloading.
    -    inline: false,
       },
     }
     
    

    webpack.prod.js

    diff --git a/webpack.prod.js b/webpack.prod.js
    index be7c2e5..93ca950 100644
    --- a/webpack.prod.js
    +++ b/webpack.prod.js
    @@ -2,9 +2,8 @@ const path = require('path')
     const webpack = require('webpack')
     const TerserPlugin = require('terser-webpack-plugin')
     const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    -const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
    -const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
    -  .BundleAnalyzerPlugin
    +const BundleAnalyzerPlugin =
    +  require('webpack-bundle-analyzer').BundleAnalyzerPlugin
     const ProgressBarPlugin = require('progress-bar-webpack-plugin')
    
     /**
    @@ -23,6 +22,9 @@ module.exports = {
         path: path.join(__dirname, 'build'),
         filename: '[name].js',
         chunkFilename: '[name].[chunkhash].js',
    +    // 空文字列で固定化。
    +    // Visual Parts SDK から取得する baseURLを使用してリソースURLを絶対パスに変換するため。
    +    publicPath: '',
       },
       resolve: {
         extensions: ['.js', '.jsx', '.ts', '.tsx'],
    @@ -35,10 +37,6 @@ module.exports = {
           'scheduler/tracing': 'scheduler/tracing-profiling',
         },
       },
    -  node: {
    -    fs: 'empty',
    -    Buffer: false,
    -  },
       module: {
         rules: [
           // ts or tsx
    @@ -97,7 +95,6 @@ module.exports = {
         minimizer: [
           // 圧縮
           new TerserPlugin({
    -        cache: false,
             parallel: true,
             terserOptions: {
               output: {
    @@ -114,7 +111,6 @@ module.exports = {
               banner: () => LICENSE_TEXT,
             },
           }),
    -      new OptimizeCSSAssetsPlugin({}),
         ],
       },
       plugins: [
    @@ -133,7 +129,7 @@ module.exports = {
               analyzerMode: 'static',
             })
           : undefined,
    -  ].filter((v) => v),
    +  ].filter(Boolean),
       performance: {
         hints: 'warning',
       },
     
    
  3. Storybookの設定ファイルを以下のように更新します。

    .storybook/main.js

    diff --git a/.storybook/main.js b/.storybook/main.js
    index 4c1d1f0..bab6727 100644
    --- a/.storybook/main.js
    +++ b/.storybook/main.js
    @@ -1,69 +1,31 @@
     const path = require('path')
    -const webpack = require('webpack')
    
     module.exports = {
       stories: ['../src/**/*.stories.tsx'],
    -  addons: ['@storybook/addon-actions/register', 'storycap/register'],
    -  webpackFinal: async (config /*, { configType } */) => {
    +  addons: ['@storybook/addon-essentials'],
    +  framework: '@storybook/react',
    +  core: {
    +    builder: 'webpack5',
    +  },
    +  typescript: {
    +    check: false,
    +    reactDocgen: false,
    +  },
    +  reactOptions: {
    +    fastRefresh: true,
    +  },
    +  webpackFinal: async (config) => {
         config.node = {
    -      fs: 'empty',
           __dirname: true,
           __filename: true,
         }
    
    -    config.resolve = {
    -      extensions: ['.js', '.jsx', '.ts', '.tsx'],
    -      alias: {
    -        src: path.join(__dirname, '../src'),
    -        'storybook/src': path.join(__dirname, './src'),
    -      },
    +    config.resolve.alias = {
    +      ...config.resolve.alias,
    +      src: path.join(__dirname, '../src'),
    +      'storybook/src': path.join(__dirname, './src'),
         }
    
    -    config.module.rules = config.module.rules
    -      // Remove default CSS loader
    -      .filter((rule) => !rule.test.toString().includes('.css'))
    -      .reduce((acc, rule) => [...acc, rule], [
    -        // add CSS Modules loader
    -        {
    -          test: /\.css$/,
    -          exclude: /reboot\.css$/,
    -          use: [
    -            'style-loader',
    -            {
    -              loader: 'dts-css-modules-loader',
    -              options: {
    -                namedExport: true,
    -              },
    -            },
    -            {
    -              loader: 'css-loader',
    -              options: {
    -                sourceMap: true,
    -                modules: {
    -                  mode: 'local',
    -                  localIdentName: '[folder]__[local]__[hash:base64:5]',
    -                },
    -                importLoaders: 1,
    -              },
    -            },
    -            'postcss-loader',
    -          ],
    -        },
    -        // add reboot.css loader
    -        {
    -          test: /reboot\.css$/,
    -          use: ['style-loader', 'css-loader'],
    -        },
    -      ])
    -
    -    config.plugins.push(
    -      new webpack.DefinePlugin({
    -        'process.env.NODE_ENV': JSON.stringify('development'),
    -        __DEVELOPMENT__: true,
    -        __DEVTOOLS__: true,
    -      }),
    -    )
    -
         return config
       },
     }
     
    

    .storybook/preview.js

    diff --git a/.storybook/preview.js b/.storybook/preview.js
    index f827a52..157ee35 100644
    --- a/.storybook/preview.js
    +++ b/.storybook/preview.js
    @@ -1,22 +1,12 @@
     import 'reboot.css'
     import React from 'react'
     import { addDecorator } from '@storybook/react'
    -import { setDefaults } from 'react-storybook-addon-props-combinations'
     import { withScreenshot } from 'storycap'
    
    -import { FONT_FAMILIES, FONT_LOADER_SPECS } from './src/constant/font'
    -import { FontStyle } from './src/components/font-style'
    -import { FontProvider } from './src/components/font-provider'
    -import { StyledGlobal } from './src/style'
    -
    -setDefaults({
    -  showSource: true,
    -  style: {
    -    padding: '20px',
    -    margin: '10px',
    -    border: '1px solid #dfe2e5',
    -  },
    -})
    +import { FONT_FAMILIES, FONT_LOADER_SPECS } from 'storybook/src/constant/font'
    +import { FontStyle } from 'storybook/src/components/font-style'
    +import { FontProvider } from 'storybook/src/components/font-provider'
    +import { StyledGlobal } from 'storybook/src/style'
    
     addDecorator(withScreenshot)
     addDecorator((storyFn) => (
     
    
  4. ワークスペース直下にあるJestの設定ファイルを以下のように更新します。

    jest.config.js

    diff --git a/jest.config.js b/jest.config.js
    index 8b27711..bb48485 100644
    --- a/jest.config.js
    +++ b/jest.config.js
    @@ -56,11 +56,7 @@ module.exports = {
       // globalTeardown: null,
    
       // A set of global variables that need to be available in all test environments
    -  globals: {
    -    'ts-jest': {
    -      tsConfig: 'tsconfig.json',
    -    },
    -  },
    +  // globals: {}
    
       // An array of directory names to be searched recursively up from the requiring module's location
       // moduleDirectories: [
    @@ -159,7 +155,12 @@ module.exports = {
    
       // A map from regular expressions to paths to transformers
       transform: {
    -    '^.+\\.(ts|tsx)$': 'ts-jest',
    +    '^.+\\.(ts|tsx)$': [
    +      'ts-jest',
    +      {
    +        tsConfig: 'tsconfig.json',
    +      },
    +    ],
       },
    
       // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
    @@ -178,4 +179,6 @@ module.exports = {
    
       // Whether to use watchman for file crawling
       // watchman: true,
    +
    +  preset: 'ts-jest',
     }
     
    
  5. React関連のファイルを以下のように更新します。

    注釈

    これらはReactをv18にアップデートしたことによる更新です。

    .storybook/src/components/font-provider/component.tsx

    diff --git a/.storybook/src/components/font-provider/component.tsx b/.storybook/src/components/font-provider/component.tsx
    index 67b88a8..7cab59e 100644
    --- a/.storybook/src/components/font-provider/component.tsx
    +++ b/.storybook/src/components/font-provider/component.tsx
    @@ -3,9 +3,12 @@ import { FontFamilies } from '@aptpod/data-viz-visual-parts-sdk'
    
     import { Context } from './context'
    
    -export const FontProvider: React.FC<{ fontFamilies: FontFamilies }> = (
    -  props,
    -) => {
    +type Props = {
    +  fontFamilies: FontFamilies
    +  children: React.ReactNode
    +}
    +
    +export const FontProvider: React.FC<Props> = (props) => {
       return (
         <Context.Provider value={props.fontFamilies}>
           {props.children}
     
    

    src/utils/components/transform/scale/component.tsx

    diff --git a/src/utils/components/transform/scale/component.tsx b/src/utils/components/transform/scale/component.tsx
    index 97d64d6..334057b 100644
    --- a/src/utils/components/transform/scale/component.tsx
    +++ b/src/utils/components/transform/scale/component.tsx
    @@ -8,6 +8,7 @@ type Props = {
       originalHeight: number
       width: number
       height: number
    +  children: React.ReactNode
     }
    
     export const Scale: FC<Props> = memo((props) => {
     
    

    以下4つのファイルでは、react-dom v18へのマイグレーションのために同じ修正を行います。

    src/entrypoint/samples/horizontal-bars/index.tsx

    diff --git a/src/entrypoint/samples/horizontal-bars/index.tsx b/src/entrypoint/samples/horizontal-bars/index.tsx
    index 40e40c9..f4720b3 100644
    --- a/src/entrypoint/samples/horizontal-bars/index.tsx
    +++ b/src/entrypoint/samples/horizontal-bars/index.tsx
    @@ -5,7 +5,7 @@ import {
       ExposerEvent,
     } from '@aptpod/data-viz-visual-parts-sdk'
     import React from 'react'
    -import { render, unmountComponentAtNode } from 'react-dom'
    +import { createRoot, Root } from 'react-dom/client'
    
     // Shadow DOM に適用するStyle
     import { StyledShadowStyle } from '../../../styles/shadow'
    @@ -45,13 +45,15 @@ const metadata: Metadata = {
      * Renderer クラスを継承したPluginRendererを定義します。
      */
     class PluginRenderer extends Renderer {
    +  private root: Root | undefined
    +
       /**
        * 描画を実行します。 1回だけコールします。
        * 状態を変更する場合は、 ExposerEvent のイベントを利用し、 element のDOMを再描画します。
        */
    -  // eslint-disable-next-line class-methods-use-this
       render(el: HTMLElement, comm: ExposerEvent) {
    -    render(
    +    this.root = createRoot(el)
    +    this.root.render(
           <StyleSheetManagerWrapper>
             {/* comm.renderingProfile は Data Visualizer v3.3.0 以降で利用可能です。 */}
             <ReactProfilerWrapper onProfile={comm.renderingProfile?.emit}>
    @@ -61,16 +63,16 @@ class PluginRenderer extends Renderer {
               </>
             </ReactProfilerWrapper>
           </StyleSheetManagerWrapper>,
    -      el,
         )
       }
       /**
    -   * element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。
    -   * HTMLElement は、 render メソッドに引数として渡された HTMLElement (コンテナ)と同じです。
    +   * render メソッドで指定した element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。
    +   *
    +   * ※ 引数の _el は React v18 に更新したことで、引数 el は使用しなくなりましたが、互換性を維持するため引数の定義は現状維持となっています。
        */
    -  // eslint-disable-next-line class-methods-use-this
    -  dispose(el: HTMLElement) {
    -    unmountComponentAtNode(el)
    +  dispose(_el: HTMLElement) {
    +    this.root?.unmount()
    +    this.root = undefined
       }
     }
     
    

    src/entrypoint/samples/line-graph/index.tsx

    diff --git a/src/entrypoint/samples/line-graph/index.tsx b/src/entrypoint/samples/line-graph/index.tsx
    index 19e9605..e850fdf 100644
    --- a/src/entrypoint/samples/line-graph/index.tsx
    +++ b/src/entrypoint/samples/line-graph/index.tsx
    @@ -5,7 +5,7 @@ import {
       ExposerEvent,
     } from '@aptpod/data-viz-visual-parts-sdk'
     import React from 'react'
    -import { render, unmountComponentAtNode } from 'react-dom'
    +import { createRoot, Root } from 'react-dom/client'
    
     // Shadow DOM に適用するStyle
     import { StyledShadowStyle } from '../../../styles/shadow'
    @@ -44,13 +44,15 @@ const metadata: Metadata = {
      * Renderer クラスを継承したPluginRendererを定義します。
      */
     class PluginRenderer extends Renderer {
    +  private root: Root | undefined
    +
       /**
        * 描画を実行します。 1回だけコールします。
        * 状態を変更する場合は、 ExposerEvent のイベントを利用し、 element のDOMを再描画します。
        */
    -  // eslint-disable-next-line class-methods-use-this
       render(el: HTMLElement, comm: ExposerEvent) {
    -    render(
    +    this.root = createRoot(el)
    +    this.root.render(
           <StyleSheetManagerWrapper>
             {/* comm.renderingProfile は Data Visualizer v3.3.0 以降で利用可能です。 */}
             <ReactProfilerWrapper onProfile={comm.renderingProfile?.emit}>
    @@ -60,16 +62,16 @@ class PluginRenderer extends Renderer {
               </>
             </ReactProfilerWrapper>
           </StyleSheetManagerWrapper>,
    -      el,
         )
       }
       /**
    -   * element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。
    -   * HTMLElement は、 render メソッドに引数として渡された HTMLElement (コンテナ)と同じです。
    +   * render メソッドで指定した element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。
    +   *
    +   * ※ 引数の _el は React v18 に更新したことで、引数 el は使用しなくなりましたが、互換性を維持するため引数の定義は現状維持となっています。
        */
    -  // eslint-disable-next-line class-methods-use-this
    -  dispose(el: HTMLElement) {
    -    unmountComponentAtNode(el)
    +  dispose(_el: HTMLElement) {
    +    this.root?.unmount()
    +    this.root = undefined
       }
     }
     
    

    src/entrypoint/samples/sensor-value/index.tsx

    diff --git a/src/entrypoint/samples/sensor-value/index.tsx b/src/entrypoint/samples/sensor-value/index.tsx
    index 1054a2e..6fbcc0a 100644
    --- a/src/entrypoint/samples/sensor-value/index.tsx
    +++ b/src/entrypoint/samples/sensor-value/index.tsx
    @@ -5,7 +5,7 @@ import {
       ExposerEvent,
     } from '@aptpod/data-viz-visual-parts-sdk'
     import React from 'react'
    -import { render, unmountComponentAtNode } from 'react-dom'
    +import { createRoot, Root } from 'react-dom/client'
    
     // Shadow DOM に適用するStyle
     import { StyledShadowStyle } from '../../../styles/shadow'
    @@ -43,14 +43,15 @@ const metadata: Metadata = {
      * Renderer クラスを継承したPluginRendererを定義します。
      */
     class PluginRenderer extends Renderer {
    +  private root: Root | undefined
    +
       /**
        * 描画を実行します。 1回だけコールします。
        * 状態を変更する場合は、 ExposerEvent のイベントを利用し、 element のDOMを再描画します。
        */
    -  // eslint-disable-next-line class-methods-use-this
       render(el: HTMLElement, comm: ExposerEvent) {
    -    // Reactを使用した描画
    -    render(
    +    this.root = createRoot(el)
    +    this.root.render(
           <StyleSheetManagerWrapper>
             {/* comm.renderingProfile は Data Visualizer v3.3.0 以降で利用可能です。 */}
             <ReactProfilerWrapper onProfile={comm.renderingProfile?.emit}>
    @@ -60,16 +61,16 @@ class PluginRenderer extends Renderer {
               </>
             </ReactProfilerWrapper>
           </StyleSheetManagerWrapper>,
    -      el,
         )
       }
       /**
    -   * element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。
    -   * HTMLElement は、 render メソッドに引数として渡された HTMLElement (コンテナ)と同じです。
    +   * render メソッドで指定した element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。
    +   *
    +   * ※ 引数の _el は React v18 に更新したことで、引数 el は使用しなくなりましたが、互換性を維持するため引数の定義は現状維持となっています。
        */
    -  // eslint-disable-next-line class-methods-use-this
    -  dispose(el: HTMLElement) {
    -    unmountComponentAtNode(el)
    +  dispose(_el: HTMLElement) {
    +    this.root?.unmount()
    +    this.root = undefined
       }
     }
     
    

    src/entrypoint/samples/time-series-text/index.tsx

    diff --git a/src/entrypoint/samples/time-series-text/index.tsx b/src/entrypoint/samples/time-series-text/index.tsx
    index fbe5d50..ffe9d20 100644
    --- a/src/entrypoint/samples/time-series-text/index.tsx
    +++ b/src/entrypoint/samples/time-series-text/index.tsx
    @@ -5,7 +5,7 @@ import {
       ExposerEvent,
     } from '@aptpod/data-viz-visual-parts-sdk'
     import React from 'react'
    -import { render, unmountComponentAtNode } from 'react-dom'
    +import { createRoot, Root } from 'react-dom/client'
    
     // Shadow DOM に適用するStyle
     import { StyledShadowStyle } from '../../../styles/shadow'
    @@ -44,13 +44,15 @@ const metadata: Metadata = {
      * Renderer クラスを継承したPluginRendererを定義します。
      */
     class PluginRenderer extends Renderer {
    +  private root: Root | undefined
    +
       /**
        * 描画を実行します。 1回だけコールします。
        * 状態を変更する場合は、 ExposerEvent のイベントを利用し、 element のDOMを再描画します。
        */
    -  // eslint-disable-next-line class-methods-use-this
       render(el: HTMLElement, comm: ExposerEvent) {
    -    render(
    +    this.root = createRoot(el)
    +    this.root.render(
           <StyleSheetManagerWrapper>
             {/* comm.renderingProfile は Data Visualizer v3.3.0 以降で利用可能です。 */}
             <ReactProfilerWrapper onProfile={comm.renderingProfile?.emit}>
    @@ -60,16 +62,16 @@ class PluginRenderer extends Renderer {
               </>
             </ReactProfilerWrapper>
           </StyleSheetManagerWrapper>,
    -      el,
         )
       }
       /**
    -   * element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。
    -   * HTMLElement は、 render メソッドに引数として渡された HTMLElement (コンテナ)と同じです。
    +   * render メソッドで指定した element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。
    +   *
    +   * ※ 引数の _el は React v18 に更新したことで、引数 el は使用しなくなりましたが、互換性を維持するため引数の定義は現状維持となっています。
        */
    -  // eslint-disable-next-line class-methods-use-this
    -  dispose(el: HTMLElement) {
    -    unmountComponentAtNode(el)
    +  dispose(_el: HTMLElement) {
    +    this.root?.unmount()
    +    this.root = undefined
       }
     }