Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A development toolkit used by AdonisJS to perform tasks like starting the dev server in watch mode, running tests in watch mode, and applying codemods to modify source files

License

NotificationsYou must be signed in to change notification settings

adonisjs/assembler


gh-workflow-imagenpm-imagelicense-image

Introduction

AdonisJS Assembler is a development toolkit used by AdonisJS to perform tasks likestarting the dev server in watch mode,running tests in watch mode, andapplying codemods to modify source files.

Assembler should always be installed as a development dependency. If your project needs Assembler APIs in production, you must reconsider your approach.

Goals

Assembler is built around the following goals.

  • Expose a coding interface and not a user interface. In other words, Assembler will never expose any CLI commands.
  • Encapsulate tasks under a single API. Instead of providing ten different utilities to run a dev server, Assembler will expose one API to run the dev server.
  • House all development APIs needed by AdonisJS. Therefore, the scope of the Assembler might increase over time.

Dev server

The development server can be started using theDevServer class. It will runbin/server.ts file from the AdonisJS project as a child process and monitor it for changes (in both HMR and watcher modes).

Every time there is a file change, theDevServer will execute the file watcher hooks and if needed will restart the development server.

You may import and use theDevServer as follows.

importtsfrom'typescript'import{DevServer}from'@adonisjs/assembler'constappRoot=newURL('./',import.meta.url)constdevServer=newDevServer(appRoot,{/**   * Arguments to pass to the "bin/server.ts" file   */scriptArgs:[],/**   * Arguments to pass to the Node.js CLI   */nodeArgs:[],/**   * An array of metaFiles to watch and re-start the   * HTTP server only if the "reloadServer" flag is   * true.   */metaFiles:[{pattern:'resources/views/**/*.edge',reloadServer:false,}]})devServer.onError((error)=>{process.exitCode=1})devServer.onClose((exitCode)=>{process.exitCode=exitCode})awaitdevServer.runAndWatch(ts)

You may start the dev server in HMR mode by settinghmr: true and calling thestart method.

constdevServer=newDevServer(appRoot,{hmr:true,// ...rest of the config})awaitdevServer.start()

Test runner

TheTestRunner is used to execute thebin/test.ts file of your AdonisJS application. Like theDevServer, theTestRunner allows you to watch for file changes and re-run the tests. The following steps are taken to re-run tests in watch mode.

  • If the changed file is a test file, only tests for that file will be re-run.
  • Otherwise, all tests will re-run with respect to the initial filters applied when running thenode ace test command.

Usage

You may import and use theTestRunner as follows.

importtsfrom'typescript'import{TestRunner}from'@adonisjs/assembler'constappRoot=newURL('./',import.meta.url)construnner=newTestRunner(appRoot,{/**   * Arguments to pass to the "bin/test.ts" file   */scriptArgs:[],/**   * Arguments to pass to the Node.js CLI   */nodeArgs:[],/**   * An array of suites and their glob patterns   */suites:[{name:'unit',files:['tests/unit/**/*.spec.ts']},{name:'functional',files:['tests/functional/**/*.spec.ts']}],/**   * Initial set of filters to apply. These filters   * will be re-applied when re-running tests in   * watch mode   */filters:{suites:['unit'],tags:['@slow']}})awaitrunner.runAndWatch(ts)

You can run tests without the watcher using therun method.

awaitrunner.run()

Bundler

TheBundler is used to create the production build of an AdonisJS application. The following steps are performed to generate the build.

  • Clean up the existing build directory.
  • Create JavaScript build usingtsc (The TypeScript's official compiler).
  • Copy theace.js file to the build folder. Since the ace file ends with the.js extension, it is not compiled by the TypeScript compiler.
  • Copypackage.json and thelock-file of the package manager you are using to thebuild folder. This operation only supportsbun | npm | yarn | pnpm. For other bundlers, you will have to copy the lock file manually.
  • The end.

Usage

You may import and use theBundler as follows.

importtsfrom'typescript'import{Bundler}from'@adonisjs/assembler'constappRoot=newURL('./',import.meta.url)constbundler=newBundler(appRoot,ts,{/**   * Metafiles to copy to the build folder   */metaFiles:[{pattern:'resources/views/**/*.edge',reloadServer:false,}],})

Codemods

Assembler also exports certain codemods to modify the source files of an AdonisJS project to configure packages.

The codemods relies on the defaults of AdonisJS and will not work if a project does not follow the defaults. This is an intentional limit since we only have limited time to craft codemods that work with every possible setup.

Usage

You may import and use theCodemods as follows.

import{CodeTransformer}from'@adonisjs/assembler/code_transformer'constappRoot=newURL('./',import.meta.url)consttransformer=newCodeTransformer(appRoot)

defineEnvValidations

Define validation rules for environment variables. The method accepts a key-value pair of variables. Thekey is the env variable name, and thevalue is the validation expression as a string.

Important

This codemod expects thestart/env.ts file to exist and must have theexport default await Env.create method call.

Also, the codemod does not overwrite the existing validation rule for a given environment variable. This is done to respect in-app modifications.

consttransformer=newCodeTransformer(appRoot)try{awaittransformer.defineEnvValidations({leadingComment:'App environment variables',variables:{PORT:'Env.schema.number()',HOST:'Env.schema.string()',}})}catch(error){console.error('Unable to define env validations')console.error(error)}

Output

import{Env}from'@adonisjs/core/env'exportdefaultawaitEnv.create(newURL('../',import.meta.url),{PORT:Env.schema.number(),HOST:Env.schema.string(),})

addMiddlewareToStack

Register AdonisJS middleware to one of the known middleware stacks. The method accepts the middleware stack and an array of middleware to register.

The middleware stack could be one ofserver | router | named.

Important

This codemod expects thestart/kernel.ts file to exist and must have a function call for the middleware stack for which you are trying to register a middleware.

consttransformer=newCodeTransformer(appRoot)try{awaittransformer.addMiddlewareToStack('router',[{path:'@adonisjs/core/bodyparser_middleware'}])}catch(error){console.error('Unable to register middleware')console.error(error)}

Output

importrouterfrom'@adonisjs/core/services/router'router.use([()=>import('@adonisjs/core/bodyparser_middleware')])

You may define named middleware as follows.

consttransformer=newCodeTransformer(appRoot)try{awaittransformer.addMiddlewareToStack('named',[{name:'auth',path:'@adonisjs/auth/auth_middleware'}])}catch(error){console.error('Unable to register middleware')console.error(error)}

updateRcFile

Registerproviders,commands, definemetaFiles andcommandAliases to theadonisrc.ts file.

Important

This codemod expects theadonisrc.ts file to exist and must have anexport default defineConfig function call.

consttransformer=newCodeTransformer(appRoot)try{awaittransformer.updateRcFile((rcFile)=>{rcFile.addProvider('@adonisjs/lucid/db_provider').addCommand('@adonisjs/lucid/commands'),.setCommandAlias('migrate','migration:run')})}catch(error){console.error('Unable to update adonisrc.ts file')console.error(error)}

Output

import{defineConfig}from'@adonisjs/core/app'exportdefaultdefineConfig({commands:[()=>import('@adonisjs/lucid/commands')],providers:[()=>import('@adonisjs/lucid/db_provider')],commandAliases:{migrate:'migration:run'}})

addJapaPlugin

Register a Japa plugin to thetests/bootstrap.ts file.

Important

This codemod expects thetests/bootstrap.ts file to exist and must have theexport const plugins: Config['plugins'] export.

consttransformer=newCodeTransformer(appRoot)constimports=[{isNamed:false,module:'@adonisjs/core/services/app',identifier:'app'},{isNamed:true,module:'@adonisjs/session/plugins/api_client',identifier:'sessionApiClient'}]constpluginUsage='sessionApiClient(app)'try{awaittransformer.addJapaPlugin(pluginUsage,imports)}catch(error){console.error('Unable to register japa plugin')console.error(error)}

Output

importappfrom'@adonisjs/core/services/app'import{sessionApiClient}from'@adonisjs/session/plugins/api_client'exportconstplugins:Config['plugins']=[sessionApiClient(app)]

addVitePlugin

Register a Vite plugin to thevite.config.ts file.

Important

This codemod expects thevite.config.ts file to exist and must have theexport default defineConfig function call.

consttransformer=newCodeTransformer(appRoot)constimports=[{isNamed:false,module:'@vitejs/plugin-vue',identifier:'vue'},]constpluginUsage='vue({ jsx: true })'try{awaittransformer.addVitePlugin(pluginUsage,imports)}catch(error){console.error('Unable to register vite plugin')console.error(error)}

Output

import{defineConfig}from'vite'importvuefrom'@vitejs/plugin-vue'exportdefaultdefineConfig({plugins:[vue({jsx:true})]})

addPolicies

Register AdonisJS bouncer policies to the list ofpolicies object exported from theapp/policies/main.ts file.

Important

This codemod expects theapp/policies/main.ts file to exist and must export apolicies object from it.

consttransformer=newCodeTransformer(appRoot)try{awaittransformer.addPolicies([{name:'PostPolicy',path:'#policies/post_policy'}])}catch(error){console.error('Unable to register policy')console.error(error)}

Output

exportconstpolicies={UserPolicy:()=>import('#policies/post_policy')}

Index generator

TheIndexGenerator is a core concept in Assembler that is used to watch the filesystem and create barrel files or types from a source directory.

For example, the core of the framework uses the following config to generate controllers, events, and listeners barrel file.

importhooksfrom'@adonisjs/assembler/hooks'exportdefaulthooks.init((type,parent,indexGenerator)=>{indexGenerator.add('controllers',{source:'./app/controllers',importAlias:'#controllers',as:'barrelFile',exportName:'controllers',removeSuffix:'controllers',output:'./.adonisjs/server/controllers.ts',})indexGenerator.add('events',{source:'./app/events',importAlias:'#events',as:'barrelFile',exportName:'events',output:'./.adonisjs/server/events.ts',})indexGenerator.add('listeners',{source:'./app/listeners',importAlias:'#listeners',as:'barrelFile',exportName:'listeners',removeSuffix:'listener',output:'./.adonisjs/server/listeners.ts',})})

Once the configurations have been registered with theIndexGenerator, it will scan the needed directories and generate the output files. Additionally, the file watchers will re-trigger the index generation when a file is added or removed from the source directory.

Barrel file generation

Barrel files provide a single entry point by exporting a collection of lazily imported entities, recursively gathered from a source directory. TheIndexGenerator automates this process by scanning nested directories and generating import mappings that mirror the file structure.

For example, given the followingcontrollers directory structure:

app/controllers/├── auth/│   ├── login_controller.ts│   └── register_controller.ts├── blog/│   ├── posts_controller.ts│   └── post_comments_controller.ts└── users_controller.ts

When processed with the controllers configuration, theIndexGenerator produces a barrel file that reflects the directory hierarchy as nested objects, using capitalized file names as property keys.

exportconstcontrollers={auth:{Login:()=>import('#controllers/auth/login_controller'),Register:()=>import('#controllers/auth/register_controller'),},blog:{Posts:()=>import('#controllers/blog/posts_controller'),PostComments:()=>import('#controllers/blog/post_comments_controller'),},Users:()=>import('#controllers/users_controller'),}

Types generation

To generate a types file, register a custom callback that takes an instance of theVirtualFileSystem and updates the output string via thebuffer object.

The collection is represented as key–value pairs:

  • Key — the relative path (without extension) from the root of the source directory.
  • Value — an object containing the file'simportPath,relativePath, andabsolutePath.
importhooksfrom'@adonisjs/assembler/hooks'exportdefaulthooks.init((type,parent,indexGenerator)=>{indexGenerator.add('inertiaPages',{source:'./inertia/pages',as:(vfs,buffer)=>{buffer.write(`declare module '@adonisjs/inertia' {`).indent()buffer.write(`export interface Pages {`).indent()constfiles=vfs.asList()Object.keys(files).forEach((filePath)=>{buffer.write(`'${filePath}': InferPageProps<typeof import('${file.importPath}').default>`)})buffer.dedent().write('}')buffer.dedent().write('}')},output:'./.adonisjs/server/inertia_pages.d.ts',})})

Contributing

One of the primary goals of AdonisJS is to have a vibrant community of users and contributors who believe in the framework's principles.

We encourage you to read thecontribution guide before contributing to the framework.

Code of Conduct

To ensure that the AdonisJS community is welcoming to all, please review and abide by theCode of Conduct.

License

AdonisJS Assembler is open-sourced software licensed under theMIT license.

About

A development toolkit used by AdonisJS to perform tasks like starting the dev server in watch mode, running tests in watch mode, and applying codemods to modify source files

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

Contributors15


[8]ページ先頭

©2009-2025 Movatter.jp