amplify-cli icon indicating copy to clipboard operation
amplify-cli copied to clipboard

Migrated graphql package from webpack to rspack

Open dfordp opened this issue 1 year ago • 0 comments

Description of changes

Utlized Codemods to automate the process of migrating the project and used this project for testing out the codemods

Update Dependencies in package.json

  • Added the following dependencies:
    • @rspack/core
    • @rspack/cli
  • Removed:
    • webpack
    • webpack-cli
    • webpack-dev-server

Install Dependencies

  • Installed the required Rspack dependencies for the project.

Update Scripts in package.json

  • Updated scripts to use rspack instead of webpack:
    - "serve": "webpack serve",
    + "serve": "rspack serve",
    
    
    

Replace Built-in Plugins

  • Replace webpack's built-in plugins with Rspack's equivalents in the configuration file.
  • Handles only supported and partially supported built-in plugins(as of October 11, 2024).
  • See [Webpack-aligned built-in plugins](https://rspack.dev/plugins/webpack/index) for updated info
  • Steps:
    • Replace the webpack object in the plugins array with the rspack object. Eg:

      - import webpack from 'webpack';
      + const rspack = require('@rspack/core');
      
      module.exports = {
          //...
          plugins: [
              - new webpack.DefinePlugin(),
              + new rspack.DefinePlugin
              // ...
          ],
      };
      

Migrate Community Plugins

  • Rspack supports most of the webpack community plugins and also offers alternative solutions for some currently unsupported plugins , which including a few of them it’s built-in packages.
  • Our codemods features community which now directly included or have had alternatives developed in rspack
  • Check [Plugin compat](https://rspack.dev/guide/compatibility/plugin) for Rspack's compatibility with webpack community plugins.
  • Some popular examples
    • Replace CopyWebpackPlugin with CopyRspackPlugin

      • Change the import statement from copy-webpack-plugin to the rspack one, and track the variable with which it has been initialized.
      • Replace CopyWebpackPlugin with a nested expression of the rspack object.
      - const CopyWebpackPlugin = require('copy-webpack-plugin');
      + const rspack = require('@rspack/core');
      
      module.exports = {
          //...
          plugins: [
              - new CopyWebpackPlugin({
              + new rspack.CopyRspackPlugin({
                  // ...
              }),
          ],
      };
      
      
    • Remove TsconfigPathsPlugin and Update Paths

      • Remove the TsconfigPathsPlugin Import:
      • Replace the plugins array containing TsconfigPathsPlugin with a tsConfig object.
      - const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
      
      module.exports = {
          resolve: {
              - plugins: [new TsconfigPathsPlugin({})],
              + tsConfig: {},
          },
      };
      
      
    • Replace CssExtractWebpackPlugin with CssExtractRspackPlugin

      • Replace Import: Change require('mini-css-extract-plugin') to require('@rspack/core').
      • Update Plugin Instantiation: Replace new CssExtractWebpackPlugin with new rspack.CssExtractRspackPlugin.
      • Update Loader: Change CssExtractWebpackPlugin.loader or 'style-loader' to rspack.CssExtractRspackPlugin.loader.
      • Add Type Property: Add type: 'javascript/auto' to the CSS rule object.
      - const CssExtractWebpackPlugin = require('mini-css-extract-plugin');
      + const rspack = require('@rspack/core');
      
      module.exports = {
          plugins: [
          - new CssExtractWebpackPlugin({
          + new rspack.CssExtractRspackPlugin({
                  // ...
              }),
          ],
          module: {
              rules: [
                  {
                      test: /\.css$/i,
                      - use: [CssExtractWebpackPlugin.loader, 'css-loader'],
                      + use: [rspack.CssExtractRspackPlugin.loader, 'css-loader'],
                      + type: 'javascript/auto',
                  },
              ],
          },
      };
      
    • Replace eslint-webpack-plugin with eslint-rspack-plugin

      • Locate the require('eslint-webpack-plugin') statement.
      • Change 'eslint-webpack-plugin' to 'eslint-rspack-plugin'.
      - const ESLintPlugin = require('eslint-webpack-plugin');
      + const ESLintPlugin = require('eslint-rspack-plugin');
      
    • Replace webpack-manifest-plugin with rspack-manifest-plugin

      • Locate the require('webpack-manifest-plugin') statement.
      • Change 'webpack-manifest-plugin' to 'rspack-manifest-plugin'.
      - const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
      + const { RspackManifestPlugin } = require('rspack-manifest-plugin');
      
      module.exports = {
          - plugins: [new WebpackManifestPlugin(options)],
          + plugins: [new RspackManifestPlugin(options)],
      };
      
      
    • Replace webpack-virtual-modules with rspack-plugin-virtual-module

      • Change the import module from webpack-virtual-modules to rspack-plugin-virtual-module and rename the variable to RspackVirtualModulePlugin.
      • Update the instantiation in the plugins array to use new RspackVirtualModulePlugin(...).
      - var VirtualModulesPlugin = require('webpack-virtual-modules');
      + var RspackVirtualModulePlugin = require('rspack-plugin-virtual-module');
      
      module.exports = {
          // ...
          plugins: [
               - new VirtualModulesPlugin({
               + new RspackVirtualModulePlugin({
                  // ...
              }),
          ],
      };
      
    • Replace workbox-webpack-plugin with @aaroon/workbox-rspack-plugin

      • Locate the require('workbox-webpack-plugin') statement.
      • Change 'workbox-webpack-plugin' to '@aaroon/workbox-rspack-plugin'.
      - const WorkboxPlugin = require('workbox-webpack-plugin');
      + const WorkboxPlugin = require(' @aaroon/workbox-rspack-plugin');
      
    • Replace CssMinimizerPlugin with LightningCssMinimizerRspackPlugin

      • Change the import statement to const rspack = require('@rspack/core');.
      • Track where the CssMinimizerPlugin variable is used.
      • Replace new CssMinimizerPlugin() with new rspack.LightningCssMinimizerRspackPlugin(options).
      - const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
      + const rspack = require('@rspack/core');
      
      module.exports = {
          optimization: {
              - minimizer: [new CssMinimizerPlugin()],
              + minimizer: [new rspack.LightningCssMinimizerRspackPlugin()],
          },
      }
      
    • Replace HtmlWebpackTagsPlugin with HtmlRspackTagsPlugin

      • Change const HtmlWebpackTagsPlugin = require('html-webpack-tags-plugin'); to const HtmlRspackTagsPlugin = require('html-rspack-tags-plugin');.
      • Change const HtmlWebpackPlugin = require('html-webpack-plugin'); to const rspack = require('@rspack/core');.
      • Replace new HtmlWebpackPlugin() with new rspack.HtmlRspackPlugin().
      • Replace new HtmlWebpackTagsPlugin(...) with new HtmlRspackTagsPlugin(...).
      - const HtmlWebpackTagsPlugin = require('html-webpack-tags-plugin');
      + const HtmlRspackTagsPlugin = require('html-rspack-tags-plugin');
      - const HtmlWebpackPlugin = require('html-webpack-plugin');
      + const rspack = require('@rspack/core');
      
      module.exports = {
          plugins: [
              - new HtmlWebpackPlugin(),
              + new rspack.HtmlRspackPlugin(),
              - new HtmlWebpackTagsPlugin({ tags: ['a.js', 'b.css'], append: true }),
              + new HtmlRspackTagsPlugin({ tags: ['a.js', 'b.css'], append: true }),
          ],
      };
      
    • Replace TerserPlugin with SwcJsMinimizerRspackPlugin

      • Replace const TerserPlugin = require('terser-webpack-plugin'); with const rspack = require('@rspack/core');.
      • Update minimizer: [new TerserPlugin(options)], to minimizer: [new rspack.SwcJsMinimizerRspackPlugin(options)],.
      - const TerserPlugin = require('terser-webpack-plugin');
      + const rspack = require('@rspack/core');
      
      module.exports = {
          optimization: {
              - minimizer: [new TerserPlugin(options)],
              + minimizer: [new rspack.SwcJsMinimizerRspackPlugin(options)],
          },
      };
      
      

Migrate Loaders

  • Replace Babel-loader with built-in SWC Loader

    • Locate the module.exports assignment in the code.
    • Identify the rules array within the module object.
    • Iterate through each rule object in the rules array.
    • Find the use array within each rule object.
    • Check for the presence of babel-loader in the use array.
    • Retain the test property from the original rule.
    • Remove the use array from the rule.
    • Add a new loader property with the value 'builtin:swc-loader'.
    • Define an options object with a jsc property.
    • Set jsc.parser with syntax: 'typescript' and tsx: true.
    • Add externalHelpers: true under jsc.
    • Configure jsc.transform.react with runtime: 'automatic'.
    • Set development and refresh flags to !prod under react.
    • Add an env property with targets: 'Chrome >= 48'.8'.
    module.exports = {
        module: {
            rules: [
                {
                    test: [/\.tsx?$/i],
                    - use: [
                    -    {
                    -        loader: 'babel-loader',
                    -        options: {
                    -            presets: ['@babel/preset-typescript'],
                    -        },
                    -    },
                    - ],
                    + loader: 'builtin:swc-loader',
                    + options: {
                    +    jsc: {
                    +        parser: {
                    +            syntax: 'typescript',
                    +            tsx: true,
                    +        },
                    +        externalHelpers: true,
                    +        transform: {
                    +            react: {
                    +                runtime: 'automatic',
                    +                development: !prod,
                    +                refresh: !prod,
                    +            },
                    +        },
                    +    },
                    +    env: {
                    +        targets: 'Chrome >= 48',
                    +    },
                    + },
                },
            ],
        },
    };
    
  • File-loader to asset/resource migration

    • Update the Webpack rule from use: ['file-loader'] to type: 'asset/resource' in your configuration file.
    module.exports = {
        module: {
            rules: [
                {
                    - use: ['file-loader'],
                    + type: 'asset/resource',
                },
            ],
        },
    };
    
    
  • Url-loader to asset/inline migration

    • Update the Webpack rule from use: ['url-loader'] to type: 'asset/inline' in your configuration file.
    module.exports = {
        module: {
            rules: [
                {
                   - use: ['url-loader'],
                   + type: 'asset/inline',
                },
            ],
        },
    };
    
    
  • Replace raw-loader with asset/source

    • Update the webpack rule from use: ['raw-loader'] to type: 'asset/source' in your configuration file.

      module.exports = {
          module: {
              rules: [
                  {
                      - use: ['raw-loader'],
                      + type: 'asset/source',
                  },
              ],
          },
      };
      
      

Impact Metrics and Performance Evaluation

The following metrics can be used to evaluate the impact of migrating to RSPack:

  1. Build Time Reduction
    • Measure build duration before and after the migration.
    • Reports from projects migrating to RSPack indicate 40-60% faster builds compared to Webpack.
  2. Bundle Size Optimization
    • Compare the sizes of production bundles. RSPack’s optimized output can lead to 10-20% smaller bundles.
  3. Developer Productivity
    • Track the time developers spend on build processes and troubleshooting.
    • Teams report fewer build-related issues post-migration due to better caching and parallel execution in RSPack.
  4. User Experience Improvements
    • Faster builds lead to quicker deployment cycles, benefiting end users through reduced page load times and smoother experiences.

https://rspack.dev/guide/migration/webpack

Checklist

  • [x] PR description included
  • [x] yarn test passes
  • [x] Tests are changed or added
  • [x] Relevant documentation is changed or added (and PR referenced)
  • [ ] New AWS SDK calls or CloudFormation actions have been added to relevant test and service IAM policies
  • [ ] Pull request labels are added

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

dfordp avatar Dec 01 '24 14:12 dfordp