Skip to content

Provide entry point for umzug 'core' for better browser usage? [v3] #501

@patdx

Description

@patdx
  • Version: v3.0.0-beta.16
  • Storage: Custom wrapper for sql.js in the browser and @capacitor-community/sqlite
  • Node version: 14.17.3
  • Dev setup: Mobile iOS/Android app using Next.js, Ionic and Capacitor

Hello, I'm trying out the v3 beta for developing a mobile app, it's quite nice and feels lightweight . :)

I might be wrong but I got the impression from the changelog for v3 and the example here: https://github.com/sequelize/umzug/tree/master/examples/7.bundling-codegen that umzug v3 is going in a more platform-generic direction, so able to be used with webpack and browser targets easily.

Functionally, it does seem to work with webpack and browser already, however, I get the following webpack warnings on every recompile of my app:

warn  - ../../node_modules/@rushstack/ts-command-line/node_modules/colors/lib/extendStringPrototype.js
Critical dependency: the request of a dependency is an expression

../../node_modules/umzug/lib/umzug.js
Critical dependency: the request of a dependency is an expression
./node_modules/umzug/lib/umzug.js
Critical dependency: the request of a dependency is an expression

./node_modules/colors/lib/extendStringPrototype.js
Critical dependency: the request of a dependency is an expression

I am using Next.js, but to keep things simple, I created a super minimal reproduction example using create-react-app here: https://github.com/patdx/umzug-browser-demo. Just yarn and yarn start to see the warnings.

This kind of warning indicates a deoptimization where a lot of extra code may get loaded into the browser:

Webpack tries to resolve require calls statically to make a minimal bundle. When a library uses variables or expressions in a require call (such as require('' + 'nodent') in these lines of ajv), Webpack cannot resolve them statically and imports the entire package. source

For browser usage, it would be nice if there was a way to import just the Umzug core without any code that triggers these webpack warnings.

I tried importing directly from the umzug file instead:

import { Umzug } from "umzug/lib/umzug";

However this had no change, I think due to 2 parts:

The parts seem specific to Node.js and not essentially for umzug's core operation. I wonder if it is possible to shift these two parts into a separate file? Here is one idea how to do it:

// umzug-core.ts

export class UmzugCore {
  // everything from Umzug.ts 
}
// umzug.ts

export class Umzug extends UmzugCore {
  constructor(options: UmzugOptions<Ctx>) {
    // just a demo, I guess the API needs to be tweaked a little to preserve `readonly`
    if (!options.migration.resolve) {
      options.migration.resolve = Umzug.defaultResolver;
    }

    super(options);
  }

  static defaultResolver = { /* ... */ }

  protected getCli(options?: CommandLineParserOptions): UmzugCLI {
    return new UmzugCLI(this, options);
  }

  async runAsCLI(argv?: string[]): Promise<boolean> {
    const cli = this.getCli();
    return cli.execute(argv);
  }
}

(Note: It may be nice to do something similar with the default JSON storage adapter, which also depends on fs, but this doesn't seem to trigger an warning w/ create-react-app or Next.js.).

With this setup, I think the most common user, Node.js user, could continue to use the default import { Umzug } from 'umzug' with easy defaults for Node.js, and the more rare browser user could use something like import { UmzugCore } from 'umzug/lib/umzug-core'.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions