/farm

Super fast web build tool written in Rust

Primary LanguageRustMIT LicenseMIT

npm package node compatibility build status


Farm

Super fast web build engine written in rust. yet another performant alternative besides webpack/vite

Webpack Vite Farm Compare
cold start 853ms 276ms 67ms Farm is faster: 12x webpack4x vite
HMR 43ms 23ms 2ms Farm is faster: 20x webpack10x vite
onload 83ms 310ms 57ms Farm is faster: 5x vite
accessible time 936ms 586ms 124ms Farm is faster: 8x webpack5x vite

Test Repo:https://github.com/farm-fe/performance-compare

Test Machine(Linux Mint 21.1 Cinnamon, 11th Gen Intel© Core™ i5-11400 @ 2.60GHz × 6, 15.5 GiB)


Features:

  • 🔥 Super Fast: Start a react / vue(incoming) project in milliseconds.
  • "1ms" HMR: Finish a HMR within 10ms for the most situations.
  • 🧰 Fully Pluggable: Support both rust plugins and js plugins.
  • ⚙️ Native Web Assets Compiling Supported: Support support compiling JS/TS/JSX/TSX, css, html natively.

Note:

  • See RFC-001 for design motivation and principle.
  • This project is still under development. Contributions are welcome.

This project is built on SWC Project, using swc for html/css/js/tsx/ts/jsx parsing, transforming, optimizing and codegen.


Getting Started

Create a new Farm Project

npx @farmfe/cli@latest create

Start the project:

cd farm-react && npm i && npm start

Configuring

Farm load configuration file from farm.config.ts. The available config as below:

export interface UserConfig {
  /** current root of this project, default to current working directory */
  root?: string;
  /** js plugin(which is a javascript object) and rust plugin(which is string refer to a .farm file or a package) */
  plugins?: (RustPlugin | JsPlugin)[];
  /** config related to compilation */
  compilation?: {
    input?: Record<string, string>;
    output?: {
      filename?: string;
      path?: string;
      publicPath?: string;
    };
    resolve?: {
      extensions?: string[];
      alias?: Record<string, string>;
      mainFields?: string[];
      conditions?: string[];
      symlinks: boolean;
    };
    external?: string[];
    mode?: 'development' | 'production';
    root?: string;
    runtime?: {
      path: string;
      plugins?: string[];
      swcHelpersPath?: string;
    };
    script?: {
      // specify target es version
      target?:
        | 'es3'
        | 'es5'
        | 'es2015'
        | 'es2016'
        | 'es2017'
        | 'es2018'
        | 'es2019'
        | 'es2020'
        | 'es2021'
        | 'es2022';
      // config swc parser
      parser?: {
        esConfig?: {
          jsx?: boolean;
          fnBind: boolean;
          // Enable decorators.
          decorators: boolean;

          // babel: `decorators.decoratorsBeforeExport`
          //
          // Effective only if `decorator` is true.
          decoratorsBeforeExport: boolean;
          exportDefaultFrom: boolean;
          // Stage 3.
          importAssertions: boolean;
          privateInObject: boolean;
          allowSuperOutsideMethod: boolean;
          allowReturnOutsideFunction: boolean;
        };
        tsConfig?: {
          tsx: boolean;
          decorators: boolean;
          /// `.d.ts`
          dts: boolean;
          noEarlyErrors: boolean;
        };
      };
    };
    partialBundling?: {
      moduleBuckets?: {
        name: string;
        test: string[];
      }[];
    };
    lazyCompilation?: boolean;
  };
  /** config related to dev server */
  server?: UserServerConfig;
}

export type RustPlugin =
  | string
  | [
      string,
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      Record<string, any>
    ];

export interface JsPlugin {
  resolve: JsPluginHook<
    {
      importers: string[];
      specifiers: string[];
    },
    PluginResolveHookParam,
    PluginResolveHookResult
  >;

  // load: JsPluginHook<{ filters: { ids: string[] }}>;
}