Viject

repository·main·Indexed 43 days ago

https://github.com/bhbs/viject

A migration utility for automating the transition of React applications from react-scripts (Create React App) to Vite. Viject version 1.5.2 rewrites npm scripts, manages dependencies, moves index.html, transforms .js files containing JSX into .jsx, and generates a vite.config.(js|ts) file to maintain CRA compatibility.

Tokens
2.2K
Snippets
8
Records
10
Agent score
55%

What's inside Viject

  1. Supported features in Viject migration

    main

    Viject supports a wide range of features commonly used in Create React App environments.

    Styles and Assets

    • Supported: Stylesheets (Standard, CSS Modules, Sass), Post-Processing CSS, Images, Fonts, Files, the public folder, and Code Splitting.
    • Partial/Experimental Support: CSS Reset, Loading .graphql files.

    Build and Development

    • Supported: Bootstrap, TypeScript, Routers, Custom Environment Variables, Performance Measurement, and Production Builds.
    • Partial/Experimental Support: Flow, Relay, and Progressive Web Apps (PWA).
    • Testing: For migrating tests, refer to the Vitest migration guide.

    Back-End Integration

    • Supported: Proxying API requests in development and fetching data with AJAX requests.
  2. Migrate a React app from CRA to Vite using Viject

    main

    Viject is a tool designed to perform a one-shot migration of React applications from react-scripts (Create React App) to Vite. It automates the heavy lifting by rewriting npm scripts, adding necessary dependencies, moving index.html, transforming .js files containing JSX into .jsx, and generating a vite.config.(js|ts) file that includes plugins to maintain CRA compatibility. This allows for a gradual migration where differences are absorbed by the Vite configuration.

    cd <YOUR_APP>
    npx viject
  3. Migrate a project using Viject

    main

    Viject is a migration tool designed to automate the transformation of a project (likely from a standard JS setup to a Vite-based JSX setup). When executed, it performs the following sequence of operations:

    1. Git Status Check: Verifies that the repository is clean (no untracked files or uncommitted changes). If the repository is dirty, the process aborts to prevent data loss.
    2. Package Configuration: Rewrites package.json with the necessary dependencies and scripts.
    3. Type Definitions: Overwrites .d.ts files to match the new project structure.
    4. Vite Configuration: If vite.config.ts or vite.config.js does not exist, it generates a new Vite configuration.
    5. HTML Migration: Moves index.html to the appropriate application entry point if required.
    6. Syntax Conversion: Converts existing .js files to .jsx to support JSX syntax.

    After the migration completes, you must install dependencies and start the development server using your preferred package manager.

    # After running the migration, follow these next steps:
    
    # npm
    npm install
    npm run dev
    
    # yarn
    yarn install
    yarn dev
    
    # pnpm
    pnpm install
    pnpm dev
  4. Configure Playwright for Viject E2E testing

    main

    Viject uses Playwright for end-to-end testing. The configuration is defined in playwright.config.ts and targets the ./e2e directory.

    Key settings include:

    • testDir: Set to ./e2e.
    • timeout: Global test timeout is 30 seconds.
    • expect.timeout: Assertion timeout is 5 seconds.
    • fullyParallel: Enabled (true).
    • retries: Set to 0.
    • reporter: Uses the html reporter.
    • forbidOnly: Prevents running only a single test in CI environments (controlled by process.env.CI).
    • workers: Uses 1 worker in CI, otherwise defaults to system availability.

    To run tests, ensure the local development server is started via the webServer configuration, which executes cd projects/kitchensink; npm run start on port 3000.

    import { defineConfig, devices } from "@playwright/test";
    
    export default defineConfig({
    	testDir: "./e2e",
    	timeout: 30 * 1000,
    	expect: {
    		timeout: 5000,
    	},
    	fullyParallel: true,
    	forbidOnly: !!process.env.CI,
    	retries: 0,
    	workers: process.env.CI ? 1 : undefined,
    	reporter: "html",
    	use: {
    		actionTimeout: 0,
    		baseURL: "http://localhost:3000/PUBLIC_URL/",
    		trace: "on-first-retry",
    	},
    	projects: [
    		{
    			name: "chromium",
    			use: { ...devices["Desktop Chrome"] },
    		},
    		{
    			name: "firefox",
    			use: { ...devices["Desktop Firefox"] },
    		},
    		{
    			name: "webkit",
    			use: { ...devices["Desktop Safari"] },
    		},
    	],
    	webServer: {
    		command: "cd projects/kitchensink; npm run start",
    		port: 3000,
    	},
    });
  5. Advanced Configuration and Environment Variables

    main

    Viject handles several environment variables used in CRA to ensure compatibility during the migration.

    Fully Supported Variables:

    • BROWSER
    • HOST
    • PORT
    • HTTPS
    • PUBLIC_URL
    • BUILD_PATH
    • GENERATE_SOURCEMAP
    • FAST_REFRESH

    Partially Supported Variables:

    • BROWSER_ARGS
    • INLINE_RUNTIME_CHUNK
    • IMAGE_INLINE_SIZE_LIMIT
    • TSC_COMPILE_ON_ERROR
    • ESLINT_NO_DEV_ERRORS
    • DISABLE_ESLINT_PLUGIN

    Not Supported:

    • WDS_SOCKET_HOST
    • WDS_SOCKET_PATH
    • WDS_SOCKET_PORT
    • CI
    • REACT_EDITOR
    • CHOKIDAR_USEPOLLING
    • DISABLE_NEW_JSX_TRANSFORM
  6. Convert .js files to .jsx using convertJS2JSX

    main

    The convertJS2JSX function automates the process of renaming .js files to .jsx within the src directory. It recursively scans the src folder, reads the content of every .js file, and uses an AST parser to detect if the file contains JSX syntax. If JSX is detected, the file is renamed by appending an x to the extension (e.g., file.js becomes file.jsx).

    import { convertJS2JSX } from './path/to/convert';
    
    // This will scan the 'src' directory and rename files containing JSX
    convertJS2JSX();
  7. Detect project options with getOptions()

    main

    Call getOptions() to automatically detect the project's configuration. It scans the filesystem for specific configuration files and package settings to return an Options object.

    Detected features include:

    • jsConfig: Presence of a JavaScript configuration file.
    • tsConfig: Presence of a TypeScript configuration file.
    • svg: Presence of any .svg files within the source directory.
    • proxy: The proxy key defined in package.json.
    • setupProxy: Presence of a proxy setup file.
    • setupTestsJs: Presence of a JavaScript test setup file.
    • setupTestsTs: Presence of a TypeScript test setup file.
    import { getOptions } from './src/options.js';
    
    const options = getOptions();
    console.log(options.tsConfig); // true if tsconfig.json exists
  8. Reference: Playwright 'use' options for Viject

    main

    The use object in the Playwright configuration defines default settings for every test. In Viject, these are configured to point to the local development server.

    use: {
    	actionTimeout: 0,
    	baseURL: "http://localhost:3000/PUBLIC_URL/",
    	trace: "on-first-retry",
    }
  9. Reference: Playwright projects for Viject

    main

    Viject defines three browser projects to ensure cross-browser compatibility. Each project uses specific device descriptors from Playwright.

    projects: [
    	{
    		name: "chromium",
    		use: { ...devices["Desktop Chrome"] },
    	},
    	{
    		name: "firefox",
    		use: { ...devices["Desktop Firefox"] },
    	},
    	{
    		name: "webkit",
    		use: { ...devices["Desktop Safari"] },
    	},
    ],
  10. The Options configuration schema

    main

    The Options type defines the configuration state detected within a project. These options determine which features (like TypeScript support, SVG handling, or proxy settings) are active based on the presence of specific files or configuration keys in the project structure.

    export type Options = {
    	jsConfig: boolean;
    	tsConfig: boolean;
    	svg: boolean;
    	proxy: boolean;
    	setupProxy: boolean;
    	setupTestsJs: boolean;
    	setupTestsTs: boolean;
    };