Open luchillo17 opened 6 months ago
As far as I can tell, @nx/express
will:
express
typesmain.ts
filewebpack
bundler by defaultOther than that, they're pretty much the same thing. There are no custom executors. Answering your questions:
[x] Why do we have 2 ways to make Express apps? Reasonably to provide less experienced users, that may not be aware of how code is generated at all, with no-brainer express boilerplate magic. We probably have more than 2 ways to make Express apps, although that would be just to make a point.
[x] What does the @nx/express
provide that @nx/node
with framework option express doesn't?
A main.ts
file, added express
types and a pre-configured bundler.
[x] Why is Webpack the only option for @nx/express
, why not ESBuild or other popular options?
I'd interpret that as an indicator that, from nrwl
or nx
perspective, Webpack may be the most appropriate option for such an app. That doesn't mean we can't change it or generate an application with @nx/node
using other bundler and boilerplate the main.ts
file ourselves.
I personally prefer having a custom workspace plugin that extends @nx/node
with a bespoke express boilerplate that includes (opinionated) middleware and configuration presets, similarly to what @nx/express
does.
TL;DR
@nx/express
appeals to the widespread popularity of express
and may indirectly attract/address users not familiarised with nx
inner workings.
Hi @moatorres thanks for the extensive explanation, let me state a few things about your input:
tsconfig.json
, tsconfig.app.json
, and tsconfig.spec.json
, and as far as I can tell, are almost identical.main.ts
file, the biggest difference in their template is where the constant for port
is, and the @nx/node
version has a host constant, while the @nx/express
adds assets
static serving by default, and I didn't have to tell it to use TS, that is the default for both it seems (1 point for @nx/express
for handling static assets from the get-go, @nx/node
does have an assets
option in the build target, but I don't see it working, my small test asset is nowhere to be seen in the dist folder, it seems usually you do this kind of stuff with esbuild-plugin-copy
, not sure if its used by @nx/esbuild
under the hood or not...).project.json
targets, the @nx/node
version has a 10-line build target and a serve target that uses @nx/js:node
executor, I would guess that would be equivalent to the @nx/express
Webpack config file.I have felt the difference mainly in the bundler, I had tons of issues enabling true ESM for Express when using Webpack (not saying is not possible, just that I couldn't make it work myself in the short time I tried locally), while ESbuild was easier to enable and enforce ESM (why ESM? top-level await and faster compile times, I don't care for ancient browsers, honestly thinking whether I should just ignore @nx/express
config and replace it with Vite or something, and there was also 1 library I was using that had an issue and the only version that worked was the ESM one).
Yup. It can be confusing. I have no idea why Webpack is used on @nx/express
's application generator configuration.
What I sometimes end up doing is extending plugins with:
nx g @nx/plugin:plugin my-plugin
Then editing the relevant generator.ts
plugin file:
import type { Tree } from '@nx/devkit'
import { formatFiles, updateJson } from '@nx/devkit'
import { applicationGenerator as nodeApplicationGenerator } from '@nx/node'
import type { Schema } from './schema'
import { initGenerator } from '../init/init'
export async function applicationGenerator(tree: Tree, schema: Schema) {
const options = normalizeOptions(tree, schema)
const initTask = await initGenerator(tree, {
...options,
skipFormat: true,
})
const applicationTask = await nodeApplicationGenerator(tree, {
...schema,
skipFormat: true,
})
addTypes(tree, options)
if (!options.skipFormat) await formatFiles(tree)
return async () => {
await initTask()
await applicationTask()
}
}
function addTypes(tree: Tree, options: NormalizedSchema) {
updateJson(tree, joinPathFragments(options.projectRoot, 'tsconfig.app.json'), (json) => {
json.compilerOptions.types = [...json.compilerOptions.types, 'express']
return json
})
}
Documentation issue
Is there a specific documentation page you are reporting?
@nx/express @nx/node generator express framework
Additional context or description
Originally I asked for context in Discord Default express app vs @nx/express generator, why different setup?.
In basic terms the default Express app we get when we create a new monorepo will be created using the
@nx/node
generator with the framework option set to Express, on the other hand, a plugin explicitly made for Express exists,@nx/express
and the application it generates is different than the one@nx/node
generates.In simple terms, one ends up with ESBuild as a bundler, the other with Webpack by default, and as the only option.
A few things should be more explicit in the docs:
@nx/express
provide that@nx/node
with framework optionexpress
doesn't?@nx/express
, why not ESBuild or other popular options?