Skip to content

Commit

Permalink
feat: build assets when starting dev server and building assets
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Mar 3, 2023
1 parent a8864e9 commit c72034d
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 88 deletions.
81 changes: 42 additions & 39 deletions commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/

import { BaseCommand, flags } from '../modules/ace/main.js'
import { detectAssetsBundler, importAssembler, importTypeScript } from '../src/internal_helpers.js'

/**
* Serve command is used to run the AdonisJS HTTP server during development. The
Expand All @@ -30,57 +31,59 @@ export default class Build extends BaseCommand {
})
declare packageManager?: 'npm' | 'pnpm' | 'yarn'

/**
* Imports assembler and displays a human readable debugging message
*/
async #importAssembler(): Promise<typeof import('@adonisjs/assembler') | undefined> {
try {
return await this.app.import('@adonisjs/assembler')
} catch {
this.logger.error(
[
'Unable to import "@adonisjs/assembler"',
'',
'The "@adonisjs/assembler" package is a development dependency and therefore you should use the build command during development only.',
'',
'If you are using the build command inside a CI or with a deployment platform, make sure the NODE_ENV is set to "development"',
].join('\n')
)
this.exitCode = 1
}
}
@flags.boolean({
description: 'Build frontend assets',
showNegatedVariantInHelp: true,
default: true,
})
declare assets?: boolean

/**
* Imports typescript and displays a human readable debugging message
* Log a development dependency is missing
*/
async #importTypeScript() {
try {
return await this.app.import('typescript')
} catch {
this.logger.error(
[
'Unable to import "typescript"',
'',
'The "typescript" package is a development dependency and therefore you should use the build command during development only.',
'',
'If you are using the build command inside a CI or with a deployment platform, make sure the NODE_ENV is set to "development"',
].join('\n')
)
this.exitCode = 1
}
#logMissingDevelopmentDependency(dependency: string) {
this.logger.error(
[
`Cannot find package "${dependency}"`,
'',
`The "${dependency}" package is a development dependency and therefore you should use the serve command during development only.`,
'',
'If you are using the build command inside a CI or with a deployment platform, make sure the NODE_ENV is set to "development"',
].join('\n')
)
}

/**
* Build application
*/
async run() {
const assembler = await this.#importAssembler()
const ts = await this.#importTypeScript()
if (!assembler || !ts) {
const assembler = await importAssembler(this.app)
if (!assembler) {
this.#logMissingDevelopmentDependency('@adonisjs/assembler')
this.exitCode = 1
return
}

const ts = await importTypeScript(this.app)
if (!ts) {
this.#logMissingDevelopmentDependency('typescript')
this.exitCode = 1
return
}

const bundler = new assembler.Bundler(this.app.appRoot, ts.default, {})
const assetsBundler = await detectAssetsBundler(this.app)
const bundler = new assembler.Bundler(this.app.appRoot, ts, {
assets: assetsBundler
? {
serve: this.assets === false ? false : true,
driver: assetsBundler.name,
cmd: assetsBundler.devServerCommand,
}
: {
serve: false,
},
metaFiles: this.app.rcFile.metaFiles,
})

/**
* Share command logger with assembler, so that CLI flags like --no-ansi has
Expand Down
76 changes: 37 additions & 39 deletions commands/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
* file that was distributed with this source code.
*/

import type { CommandOptions } from '../types/ace.js'
import { BaseCommand, flags } from '../modules/ace/main.js'
import { CommandOptions } from '../types/ace.js'
import { detectAssetsBundler, importAssembler, importTypeScript } from '../src/internal_helpers.js'

/**
* Serve command is used to run the AdonisJS HTTP server during development. The
Expand All @@ -30,58 +31,52 @@ export default class Serve extends BaseCommand {
@flags.boolean({ description: 'Use polling to detect filesystem changes' })
declare poll?: boolean

/**
* Imports assembler and displays a human readable debugging message
*/
async #importAssembler(): Promise<typeof import('@adonisjs/assembler') | undefined> {
try {
return await this.app.import('@adonisjs/assembler')
} catch {
this.logger.error(
[
'Unable to import "@adonisjs/assembler"',
'',
'The "@adonisjs/assembler" package is a development dependency and therefore you should use the serve command during development only.',
'',
'If you are running your application in production, then use "node bin/server.js" command to start the HTTP server',
].join('\n')
)
this.exitCode = 1
}
}
@flags.boolean({
description: 'Start assets bundler dev server',
showNegatedVariantInHelp: true,
default: true,
})
declare assets?: boolean

/**
* Imports typescript and displays a human readable debugging message
* Log a development dependency is missing
*/
async #importTypeScript() {
try {
return await this.app.import('typescript')
} catch {
this.logger.error(
[
'Unable to import "typescript"',
'',
'The "typescript" package is a development dependency and therefore you should use the serve command during development only.',
'',
'If you are running your application in production, then use "node bin/server.js" command to start the HTTP server',
].join('\n')
)
this.exitCode = 1
}
#logMissingDevelopmentDependency(dependency: string) {
this.logger.error(
[
`Cannot find package "${dependency}"`,
'',
`The "${dependency}" package is a development dependency and therefore you should use the serve command during development only.`,
'',
'If you are running your application in production, then use "node bin/server.js" command to start the HTTP server',
].join('\n')
)
}

/**
* Runs the HTTP server
*/
async run() {
const assembler = await this.#importAssembler()
const assembler = await importAssembler(this.app)
if (!assembler) {
this.#logMissingDevelopmentDependency('@adonisjs/assembler')
this.exitCode = 1
return
}

const assetsBundler = await detectAssetsBundler(this.app)
const devServer = new assembler.DevServer(this.app.appRoot, {
nodeArgs: this.parsed.nodeArgs,
scriptArgs: [],
assets: assetsBundler
? {
serve: this.assets === false ? false : true,
driver: assetsBundler.name,
cmd: assetsBundler.devServerCommand,
}
: {
serve: false,
},
metaFiles: this.app.rcFile.metaFiles,
})

Expand Down Expand Up @@ -109,11 +104,14 @@ export default class Serve extends BaseCommand {
* Start the development server
*/
if (this.watch) {
const ts = await this.#importTypeScript()
const ts = await importTypeScript(this.app)
if (!ts) {
this.#logMissingDevelopmentDependency('typescript')
this.exitCode = 1
return
}
await devServer.startAndWatch(ts.default, { poll: this.poll || false })

await devServer.startAndWatch(ts, { poll: this.poll || false })
} else {
await devServer.start()
}
Expand Down
1 change: 0 additions & 1 deletion modules/ace/shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ export function aceShell(cwd: URL) {
const result = await childProcess
process.exitCode = result.exitCode
} catch (error) {
console.error(error)
process.exitCode = 1
}
},
Expand Down
18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
"author": "virk,adonisjs",
"license": "MIT",
"devDependencies": {
"@adonisjs/assembler": "^6.1.0-0",
"@adonisjs/assembler": "^6.1.3-0",
"@commitlint/cli": "^17.4.4",
"@commitlint/config-conventional": "^17.4.4",
"@japa/assert": "^1.4.1",
Expand All @@ -111,7 +111,7 @@
"@japa/spec-reporter": "^1.3.3",
"@swc/core": "^1.3.37",
"@types/fs-extra": "^11.0.1",
"@types/node": "^18.14.2",
"@types/node": "^18.14.4",
"@types/pretty-hrtime": "^1.0.1",
"@types/sinon": "^10.0.13",
"@types/supertest": "^2.0.12",
Expand All @@ -124,7 +124,6 @@
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-adonis": "^3.0.3",
"eslint-plugin-prettier": "^4.2.1",
"fs-extra": "^11.1.0",
"get-port": "^6.1.2",
"github-label-sync": "^2.2.0",
"husky": "^8.0.3",
Expand All @@ -139,30 +138,31 @@
},
"dependencies": {
"@adonisjs/ace": "^12.3.0-0",
"@adonisjs/application": "^7.1.0-0",
"@adonisjs/bodyparser": "^9.3.0-0",
"@adonisjs/application": "^7.1.1-0",
"@adonisjs/bodyparser": "^9.3.1-0",
"@adonisjs/config": "^4.2.0-0",
"@adonisjs/encryption": "^5.1.2-0",
"@adonisjs/env": "^4.2.0-0",
"@adonisjs/events": "^8.4.7-0",
"@adonisjs/events": "^8.4.8-0",
"@adonisjs/fold": "^9.9.2-0",
"@adonisjs/hash": "^8.3.1-0",
"@adonisjs/http-server": "^6.8.0-0",
"@adonisjs/http-server": "^6.8.1-0",
"@adonisjs/logger": "^5.4.2-0",
"@adonisjs/validator": "^13.0.0-0",
"@adonisjs/validator": "^13.0.1-0",
"@poppinss/macroable": "^1.0.0-2",
"@poppinss/utils": "^6.5.0-0",
"@sindresorhus/is": "^5.3.0",
"@types/he": "^1.2.0",
"cuid": "^3.0.0",
"execa": "^7.0.0",
"fs-extra": "^11.1.0",
"he": "^1.2.0",
"pretty-hrtime": "^1.0.3",
"youch": "^3.2.3",
"youch-terminal": "^2.2.0"
},
"peerDependencies": {
"@adonisjs/assembler": "^6.1.0-0",
"@adonisjs/assembler": "^6.1.3-0",
"argon2": "^0.30.3",
"bcrypt": "^5.0.1"
},
Expand Down
59 changes: 59 additions & 0 deletions src/internal_helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* @adonisjs/core
*
* (c) AdonisJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import fs from 'fs-extra'
import { ApplicationService } from './types.js'

/**
* Imports assembler optionally
*/
export async function importAssembler(
app: ApplicationService
): Promise<typeof import('@adonisjs/assembler') | undefined> {
try {
return await app.import('@adonisjs/assembler')
} catch {}
}

/**
* Imports typescript optionally
*/
export async function importTypeScript(
app: ApplicationService
): Promise<typeof import('typescript') | undefined> {
try {
return await app.importDefault('typescript')
} catch {}
}

/**
* Detects the assets bundler in use. The rcFile.assetsBundler is
* used when exists.
*/
export async function detectAssetsBundler(app: ApplicationService) {
if (app.rcFile.assetsBundler) {
return app.rcFile.assetsBundler
}

if (await fs.exists(app.makePath('vite.config.js'))) {
return {
name: 'vite',
devServerCommand: 'vite',
buildCommand: 'vite build',
}
}

if (await fs.exists(app.makePath('webpack.config.js'))) {
return {
name: 'encore',
devServerCommand: 'encore dev-server',
buildCommand: 'encore',
}
}
}

0 comments on commit c72034d

Please sign in to comment.