Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

AdonisJS
AdonisJS

Posted on • Originally published atadonisjs.com

     

Announcing AdonisJS v6

Alright, sit tight, as this will be a long article. The work for v6 started with the goal of moving to ESM and improving the IoC container to be simple andhave fewer responsibilities.

But we have touched almost every part of the framework, smoothing out many rough edges, fixing some long pending issues, and rewriting some packages from scratch.

NOTE

Are you looking to migrate your applications from v5 to v6? Check out themigration-to-v6.adonisjs.com website for a complete list of breaking changes.

Also, we have created amigration CLI that can handle the majority of migration work for you.

Moving to ESM

ESM (ECMAScript Modules) vs CJS (CommonJS) might be a topic of debate among many JavaScript developers. But we are not here to discuss the merits and drawbacks of one or the other.

We went with ESM because it is part of the spec. Yes, CJS might live the entirety of this universe, but the fact that a project using CJS cannot easily import ESM modules is a big enough pain point for us.

Many prolific authors (whom we rely on) already started moving their packages to ESM. As a result, if we keep the AdonisJS source code in CJS, we cannot use the latest versions of their packages, which may also contain several security fixes.

Starting from v6, every new AdonisJS application will use TypeScript and ESM. Yes, you can still install and use packages written in CJS, as ESM allows that.

Stop relying on TypeScript compiler hooks

I am not a fan of hacking into tools, primarily when the code is written for public consumption. However, with AdonisJS v5, we hook into the TypeScript compiler API and rewrite the imports prefixed with the@ioc keyword to IoC container lookup calls.

For example, if you write the following import.

importRoutefrom'@ioc:Adonis/Core/Route'
Enter fullscreen modeExit fullscreen mode

We will compile it to

constRoute=global[Symbol.for('ioc.use')]('Adonis/Core/Route')
Enter fullscreen modeExit fullscreen mode

There are two problems with the above transformation.

  • We rely on the official compiler API. As a result, we cannot use other JIT tools like ESBuild or SWC written in other faster languages.
  • We have to inject a global IoC container variable to resolve the module from the container.

Do not worry if you do not understand the container usage in this example. We have removed all this magic, and imports in v6 are regular JavaScript imports.

If you have been using AdonisJS v5 for a long time, wonder what happened to@ioc prefixed imports. Remember, there were better ways to resolve dependencies from the container. We have found a much simpler way to resolve container dependenciesin the form of container services.

Type-safe routes and controllers binding

Earlier, we used magic strings to bind a controller to a route. For example, This is how the route + controller usage looks in v5.

Route.get('posts','PostsController.index')
Enter fullscreen modeExit fullscreen mode

The'PostsController.index' is a magic string because, for TypeScript, it has no real meaning and cannot detect and report errors.

Starting from v6, we no longer recommend using magic strings. You can directly import controllers and bind them on a route by reference. For example:

importPostsControllerfrom'#controllers/posts_controller'router.get('posts',[PostsController,'index'])
Enter fullscreen modeExit fullscreen mode

However, there was one nice thing about magic strings. They allowed us to import the controllers lazily. Since controllers import the rest of the codebase, importing them within the routes file impacts the application's boot time.

In v6, you can lazily import a controller by wrapping it inside a function and using dynamic import.

You can detect and automatically convert controller imports to a lazy import using ourESLint plugin.

constPostsController=()=>import('#controllers/posts_controller')router.get('posts',[PostsController,'index'])
Enter fullscreen modeExit fullscreen mode

Type-safe named middleware reference

In AdonisJS v5, you reference the named middleware defined inside thestart/kernel.ts file on a route as a string. For example:

Server.middleware.registerNamed({auth:()=>import('App/Middleware/Auth')})
Enter fullscreen modeExit fullscreen mode
Route.get('/me',()=>{}).middleware('auth')// Passing optionsRoute.get('/me',()=>{}).middleware('auth:web,api')
Enter fullscreen modeExit fullscreen mode

Since we are referencing the middleware as a string and passing the options as a string, there is no type-safety.

Starting from v6, the named middleware are defined by reference using themiddleware collection exported from thestart/kernel.ts file.

exportconstmiddleware=router.named({auth:()=>import('#middleware/auth_middleware')})
Enter fullscreen modeExit fullscreen mode
import{middleware}from'#start/kernel'router.get('/',()=>{}).use(middleware.auth())// Passing optionsrouter.get('/',()=>{}).use(middleware.auth({guards:['web','api']}))
Enter fullscreen modeExit fullscreen mode

Type-safe AdonisRC file

We have moved from a JSON-based RCFile (.adonisrc.json) to a TypeScript-based RCFile (adonisrc.ts).

This change allows us to directly importservice providers,commands, andpreload files instead of defining their import path as strings.

As a result, TypeScript can detect and report broken imports. Also, you can have better IntelliSense when modifying the values in the RCFile.

Type-safe Event emitter

To make the event emitter type-safe, we define a list of known events as a TypeScript interface, and from thereon, the emitter API only allows dispatching and listening for known events.

interfaceEventsList{'user:registered':User,'http:request_completed':{duration:[number,number],ctx:HttpContext}}
Enter fullscreen modeExit fullscreen mode

The ability to define an events list as an interface also exists with the older version of AdonisJS.

However, with v6, you can alsodefine events as classes. Class-based events encapsulate the event identifier and the event data within the same class. The class constructor serves as the identifier, and an instance of the class holds the event data. For example:

// Defining eventimporttypeUserfrom'#models/user'import{BaseEvent}from'@adonisjs/core/events'exportdefaultclassUserRegisteredextendsBaseEvent{constructor(publicuser:User){}}
Enter fullscreen modeExit fullscreen mode
// Listening for class-based eventimportemitterfrom'@adonisjs/core/services/emitter'importUserRegisteredfrom'#events/user_registered'emitter.on(UserRegistered,function(event){console.log(event.user)})
Enter fullscreen modeExit fullscreen mode
// Dispatching class-based eventimportUserRegisteredfrom'#events/user_registered'constuser=newUser()UserRegistered.dispatch(user)
Enter fullscreen modeExit fullscreen mode

You canlearn about class-based events in the documentation.

Vite integration for bundling frontend assets

Vite has become the de facto standard for building frontend applications. With this release, we ship anofficial integration for using Vite inside AdonisJS applications.

Also, we no longer recommend usingWebpack Encore for new projects. However, we will continue to maintain this package for existing v5 applications.

New scaffolding system and codemods API

The scaffolding system and codemods API are used by the package creators to configure a package or by Ace commands to scaffold a resource.

We have written anin-depth guide on the same that you must read to learn more about it.

New validation library

The current validation module of AdonisJS has served us well, but it desperately needs some improvements. Right now:

  • It lacks a union data type. There is no way to validate a field as a string or a number.

  • The API to create custom rules is rough. We have witnessed many individuals struggling to create custom rules.

  • The state of the package codebase was not great. It made it harder for us to make big changes confidently. A significant rewrite was needed.

Finally, we developed a framework agnostic validation library calledVineJS. VineJS will be the official validation system for AdonisJS v6.

VineJS is much faster than the version used in V5, and it's also more comprehensive. It makes it easy to create custom rules and schema types and validate complex schemas.

You can learn more about VineJS in our introduction live stream.https://www.youtube.com/watch?v=YdBt0s8NA4I

What happens to the old validator?

We will maintain the old validator (without bringing any features) you can use while migrating apps to v6. However, we recommend using VineJS for new applications.

New and more Framework agnostic packages

Lately, we have decided to extract/create more framework-agnostic packages (wherever possible) with their dedicated documentation websites.

As a result, we are happy to announce that you can use the following packages with any Node.js framework of your choice.

  • Japa - A backend focused testing framework for Node.js.

  • Edge - In the age of complex frontend libraries and frameworks, Edge embraces old-school server-side rendering. Edge is a simple, Modern, and batteries-included template engine for Node.js.

  • VineJS - VineJS is a data validation library for the Node.js runtime. It is at least 9 times faster than Zod and Yup.

  • Bento Cache - Bentocache is a robust multi-tier caching library for the Node.js runtime.

  • Verrou - Verrou is a library for managing locks in a Node.js application.

Improved documentation

There were some lapses in AdonisJS's documentation. For example, topics like IoC Container and Service providers were undocumented. Also, some of the guides should have been more comprehensive.

With AdonisJS v6, we have spent significant time covering all the framework aspects within the documentation. Following are some of the newly added topics.

Better testing experience

We keep testing as one of the top priorities of the framework. Not only do we pre-configure a testing environment for your applications, but we also ensure the core APIs for the framework are testing-friendly.

Starting from v6, we ship:

Changes to the folder structure

While 80% of the folder structure of a v6 application remains the same, we move fromPascalCase tosnake_case for naming files and folders.

Whysnake_case? - Last year, I documented the rules and conventions I follow when writing code. I briefly talk about thereasons behind opting forsnake_case.

NOTE

Thesnake_case naming convention is part of the official starter kits. However, you have the freedom to create and use custom starter kits with the naming conventions of your choice.

The rest 20% of folder structure changes include:

  • Move entry point files to thebin folder. You will no longer seeserver.ts andtest.ts inside the application's root. These files are now inside thebin directory.

  • Remove the.adonisrc.json file in favor of theadonisrc.ts file.Learn more.

  • Rename thecontracts directory totypes.

  • Move theControllers directory outside theHttp directory. As a result, there is noHttp directory in a v6 app. Controllers live directly inside theapp directory.

  • Move theenv.ts file from the project root to thestart directory.

MJML support and additional mail transports

The@adonisjs/mail package now bundles additional transports forResend and theBrevo mail services. Additionally, it contributes the@mjml Edge tag to write email content using theMJML markup language.

The contents of the following template will be auto-compiled to HTML on the fly when sending the email.Learn more

@mjml()<mjml><mj-body><mj-section><mj-column><mj-text>            Hello World!</mj-text></mj-column></mj-section></mj-body></mjml>@end
Enter fullscreen modeExit fullscreen mode

Sunsetting packages

The following packages are no longer used with a brand new AdonisJS v6 application.

  • Remove@adonisjs/encore in favor of Vite. However, the package is compatible with v6 and can be used until you decide to move to Vite.

  • Remove@adonisjs/validator in favor of VineJS. However, the package is compatible with v6 and can be used until you decide to move to VineJS.

  • Remove@adonisjs/sink in favor of the new scaffolding system and code mods API. No longer support v6 applications.

  • Remove@adonisjs/require-ts in favor of TSNode + SWC. No longer support v6 applications.

  • Remove@adonisjs/view in favor of directly using Edge.js. No longer support v6 applications.

Other changes

Following is the list of additional notable changes in the v6 release.

  • Support loading additional dot-env files other than the.env file.Learn more

  • The@adonisjs/logger package uses the latest version of Pino and supports defining multiple loggers.Learn more

  • Support for experimentalpartitioned andpriority cookie options.

  • Remove support for serving static files from the framework core in favor of the new@adonisjs/static package.

  • Remove support for CORS from the framework core in favor of the new@adonisjs/cors package.

Ready to get started

Head to theofficial documentation to learn more about AdonisJS and create a new project. Or check out theLet's Learn AdonisJS 6 course fromTom at Adocasts.

Additional Links

Top comments(1)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
corners2wall profile image
Corners 2 Wall
Average frontend developer
  • Joined

Sorry but looks strange

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

A fully featured MVC framework for Node.js. Comes with its own SQL ORM, Auth module, Test runner, and a lot more.
  • Location
    Global
  • Joined

More fromAdonisJS

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp