Skip to content

Repository files navigation

au-rogue

Codemods that move an Aurelia 1 codebase toward Aurelia 2. It applies the changes that are safe to make mechanically, leaves everything else alone, and writes a report explaining what it did and what is left for you.

The tool is deliberately unambitious about the hard parts. Bootstrap, routing and anything with an ambiguous v2 equivalent is reported rather than rewritten, because a wrong automatic change in those areas costs more than doing it by hand.

Install

npm install -g au-rogue
# or
npx au-rogue --help

Usage

cd my-aurelia-1-app

# See what would change
npx au-rogue --dry

# Read au-rogue.report.md, then apply
npx au-rogue

Both a Markdown report (au-rogue.report.md) and a JSON one (au-rogue.report.json) are written. The Markdown report groups findings into "Needs review", "Changes applied" and "Guidance", and ends with a next-steps checklist.

Options

Option Default Purpose
--dry off Report without writing files
--sources <glob...> src/**/*.{ts,tsx,js,jsx} Source files to migrate
--templates <glob...> src/**/*.{html,au}, index.html Templates to migrate
--ignore <glob...> Extra paths to skip (node_modules, dist, build are always skipped)
--only <pass...> Run only these passes
--skip <pass...> Skip these passes
--list-passes Print the pass names and exit
--tsconfig <path> Load the project's tsconfig so types resolve
--router-hooks off Rename router hooks even on classes that might be dialogs
--compat off Add @aurelia/compat-v1 guidance to the report
--report-dir <dir> . Where to write the reports
--no-report Skip writing report files
--fail-on-warn off Exit non-zero if anything needs manual review
--quiet off Suppress everything but the summary

Passing --tsconfig is worth it. Without resolvable types the DI pass has to infer whether a constructor parameter's type is a runtime token; with them it knows.

Running the tool twice is safe. Every pass is idempotent, and a second run over migrated code makes no further changes.

What it changes

Imports. Aurelia 1 packages are remapped to their v2 equivalents, including symbol renames: HttpClient becomes IHttpClient from @aurelia/fetch-client, Router becomes IRouter from @aurelia/router, EventAggregator becomes the IEventAggregator token, bindingMode becomes BindingMode, and the thirty-odd aurelia-* packages collapse into aurelia and the scoped @aurelia/* ones. Symbols with no v2 counterpart stay where they are and get reported.

Dependency injection. @autoinject, @inject(A, B) and static inject = [A, B] all become resolve() class fields. Parameter properties convert directly; plain parameters convert when the constructor does nothing but assign them to this. v1 resolvers map across (Lazy.of(X)lazy(X), All.of(X)all(X), NewInstance.of(X)newInstanceOf(X)). A constructor left empty by the conversion is removed.

Lifecycle. bindbinding, unbindunbinding, detacheddetaching. Renames only happen on classes that look like Aurelia view-models, since plenty of ordinary classes have a bind() method. Router hooks (canActivatecanLoad, activateloading, canDeactivatecanUnload, deactivateunloading) are renamed only for classes that are clearly routed — Aurelia 1's dialog plugin used activate/deactivate too, so --router-hooks is there for when you know better.

Templates. <require><import>, <router-view><au-viewport>, <compose><au-compose> (with view/view-modeltemplate/component), <content><au-slot>, .delegate.trigger, .one-way.to-view, .call.bind with a lambda, view-model.refcomponent.ref, element.refref, replace-partau-slot, route-hrefload, and <template bindable="a, b"><bindable> elements. Templates written inline in @customElement({ template }) get the same treatment.

Template edits are applied as offset splices against the original file, so anything the rules don't touch — interpolations, quoting style, self-closing tags, whitespace, comments — comes out byte for byte identical.

Decorators. @computedFrom(...)@computed(...), @inlineView/@noView@customElement({ template }), and @bindable options renamed (defaultBindingModemode, changeHandlercallback).

Platform. PLATFORM.moduleName('x') is unwrapped to 'x', and the import is dropped once nothing uses it.

What it reports instead

  • Bootstrap. configure(aurelia) with aurelia.use.plugin(...) gets a worked example of the equivalent Aurelia.register(...).app(Root).start(), with the v1 plugins mapped to their v2 configurations where they exist.
  • Routing. configureRouter(), NavigationInstruction, router.generate() and router events are described with their v2 shape rather than rewritten.
  • Dependencies. The Aurelia 1 packages in package.json, with the exact npm install / npm uninstall commands to swap them.
  • tsconfig. experimentalDecorators and emitDecoratorMetadata are incompatible with Aurelia 2's TC39 decorators; importHelpers without tslib is flagged too.
  • Lifecycle traps. A property that shadows a v2 hook (the classic being loading = true next to a loading() route hook, which silently stops the hook from running), attached() without cleanup, DOM work in binding().
  • Lost preventDefault. Aurelia 1 called it for you on delegated events. Form submits, anchors with an href, and submit buttons inside a form are flagged individually; every other converted handler is covered by a single per-file note rather than a warning each.

Passes

--list-passes prints them. Every finding in the report is tagged with the pass and rule that produced it, so --only and --skip let you work through a large migration one concern at a time:

npx au-rogue --only templates          # just the HTML
npx au-rogue --skip lifecycle,router   # everything except the risky renames

Migration order

The tool covers the mechanical middle of a migration, not the whole of it. A workable order:

  1. Stand up an Aurelia 2 shell (npx makes aurelia) and rewrite main.ts.
  2. Register compatRegistration from @aurelia/compat-v1 so v1 syntax keeps working while you port.
  3. Copy src/ over and run au-rogue --dry, then au-rogue.
  4. Work through the report's "Needs review" section — routing first, since the app cannot navigate without it.
  5. Build, run the tests, and fix what falls out.
  6. Remove compatRegistration and drop the @aurelia/compat-v1 dependency. The migration is finished when nothing depends on it.

Development

pnpm install
pnpm test
pnpm run build

The examples/ directory holds a small Aurelia 1 app covering the patterns the tool handles; examples/run-migration.sh runs the tool against a copy of it.

License

MIT

About

Conservative codemods that migrate Aurelia 1 projects toward Aurelia 2. It edits only the parts that are safe to transform automatically, then writes a comprehensive report for everything else.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages