Skip to content

Commit

Permalink
feat(nuxt): load nuxt config programmatically (#20185)
Browse files Browse the repository at this point in the history
  • Loading branch information
mandarini authored Nov 14, 2023
1 parent 06f887c commit bdc30ca
Show file tree
Hide file tree
Showing 12 changed files with 473 additions and 239 deletions.
2 changes: 2 additions & 0 deletions e2e/nuxt/src/nuxt.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ describe('Nuxt Plugin', () => {
expect(result).toContain(
`Successfully ran target build for project ${app}`
);
checkFilesExist(`dist/${app}/.nuxt/nuxt.d.ts`);
checkFilesExist(`dist/${app}/.output/nitro.json`);
});

it('should test application', async () => {
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
"@nestjs/schematics": "^9.1.0",
"@nestjs/swagger": "^6.0.0",
"@nestjs/testing": "^9.0.0",
"@nuxt/kit": "^3.8.1",
"@nuxt/schema":"^3.8.1",
"@ngrx/effects": "~16.0.0",
"@ngrx/router-store": "~16.0.0",
"@ngrx/store": "~16.0.0",
Expand Down
2 changes: 2 additions & 0 deletions packages/nuxt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
"dependencies": {
"nuxi": "npm:[email protected]",
"tslib": "^2.3.0",
"@nuxt/kit": "^3.8.1",
"@nuxt/schema": "^3.8.1",
"@nx/devkit": "file:../devkit",
"@nx/js": "file:../js",
"@nx/eslint": "file:../eslint",
Expand Down
51 changes: 16 additions & 35 deletions packages/nuxt/src/executors/build/build.impl.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ExecutorContext, joinPathFragments } from '@nx/devkit';
import { NuxtBuildExecutorOptions } from './schema';

// Required because nuxi is ESM package.
export function loadNuxiDynamicImport() {
return Function('return import("nuxi")')() as Promise<typeof import('nuxi')>;
}
import {
getCommonNuxtConfigOverrides,
loadNuxiDynamicImport,
loadNuxtKitDynamicImport,
} from '../../utils/executor-utils';

export async function* nuxtBuildExecutor(
options: NuxtBuildExecutorOptions,
Expand All @@ -13,40 +13,21 @@ export async function* nuxtBuildExecutor(
const projectRoot =
context.projectsConfigurations.projects[context.projectName].root;
const { runCommand } = await loadNuxiDynamicImport();
const { loadNuxtConfig } = await loadNuxtKitDynamicImport();
const config = await loadNuxtConfig({
cwd: joinPathFragments(context.root, projectRoot),
});

try {
await runCommand('build', [projectRoot], {
overrides: {
...options,
workspaceDir: context.root,
buildDir: joinPathFragments(context.root, options.outputPath, '.nuxt'),
typescript: {
typeCheck: true,
tsConfig: {
extends: joinPathFragments(
context.root,
projectRoot,
'tsconfig.app.json'
),
},
},
imports: {
autoImport: false,
},
nitro: {
output: {
dir: joinPathFragments(context.root, options.outputPath, '.output'),
serverDir: joinPathFragments(
context.root,
options.outputPath,
'.output/server'
),
publicDir: joinPathFragments(
context.root,
options.outputPath,
'.output/public'
),
},
},
...getCommonNuxtConfigOverrides(
config,
context.root,
projectRoot,
options.outputPath
),
},
});
return { success: true };
Expand Down
62 changes: 38 additions & 24 deletions packages/nuxt/src/executors/serve/serve.impl.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,42 @@
import { ExecutorContext, joinPathFragments } from '@nx/devkit';
import { NuxtServeExecutorOptions } from './schema';
import { createAsyncIterable } from '@nx/devkit/src/utils/async-iterable';

// Required because nuxi is ESM package.
export function loadNuxiDynamicImport() {
return Function('return import("nuxi")')() as Promise<typeof import('nuxi')>;
}
import {
getCommonNuxtConfigOverrides,
loadNuxiDynamicImport,
loadNuxtKitDynamicImport,
} from '../../utils/executor-utils';
import { NuxtOptions } from '@nuxt/schema';

export async function* nuxtServeExecutor(
options: NuxtServeExecutorOptions,
context: ExecutorContext
) {
const projectRoot =
context.projectsConfigurations.projects[context.projectName].root;

const { loadNuxtConfig } = await loadNuxtKitDynamicImport();
const config = await loadNuxtConfig({
cwd: joinPathFragments(context.root, projectRoot),
});

yield* createAsyncIterable<{ success: boolean; baseUrl: string }>(
async ({ next, error }) => {
try {
const { runCommand } = await loadNuxiDynamicImport();

await runCommand('dev', [projectRoot], {
overrides: getConfigOverrides(options, context.root, projectRoot),
// Options passed through CLI or project.json get precedence over nuxt.config.ts
overrides: getConfigOverrides(options, config, projectRoot, context),
});
next({
success: true,
baseUrl: `${options.https ? 'https' : 'http'}://${
options.host ?? 'localhost'
}:${options.port ?? '4200'}`,
// Options passed through CLI or project.json get precedence over nuxt.config.ts
baseUrl: `${
options.https ? 'https' : config.devServer.https ? 'https' : 'http'
}://${options.host ?? config.devServer.host ?? 'localhost'}:${
options.port ?? config.devServer.port ?? '4200'
}`,
});
} catch (err) {
console.error(err);
Expand All @@ -36,22 +48,24 @@ export async function* nuxtServeExecutor(

function getConfigOverrides(
options: NuxtServeExecutorOptions,
workspaceRoot: string,
projectRoot: string
config: NuxtOptions,
projectRoot: string,
context: ExecutorContext
): { [key: string]: any } {
const json: { [key: string]: any } = {
workspaceDir: workspaceRoot,
typescript: {
typeCheck: true,
tsConfig: {
extends: joinPathFragments(
workspaceRoot,
projectRoot,
'tsconfig.app.json'
),
},
},
};
let outputPath = '';
for (const [_targetName, targetConfig] of Object.entries(
context.projectsConfigurations.projects[context.projectName].targets
)) {
if (targetConfig.executor === '@nx/nuxt:build') {
outputPath = targetConfig.options.outputPath;
}
}
const json = getCommonNuxtConfigOverrides(
config,
context.root,
projectRoot,
outputPath
);

if (options.debug !== undefined) {
json.debug = options.debug;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,32 @@ import { defineNuxtConfig } from 'nuxt/config';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
srcDir: 'src',
buildDir: 'dist/my-app/.nuxt',
devtools: { enabled: true },
devServer: {
host: 'localhost',
port: 4200,
},
typescript: {
typeCheck: true,
tsConfig: {
extends: 'my-app/tsconfig.app.json',
},
},
imports: {
autoImport: false,
},
vite: {
plugins: [nxViteTsPaths()],
},
nitro: {
output: {
dir: 'dist/my-app/.output',
serverDir: 'dist/my-app/.output/server',
publicDir: 'dist/my-app/.output/public',
},
},
});
"
`;
Expand All @@ -55,12 +72,12 @@ exports[`app generated files content - as-provided general application should co
"targets": {
"serve": {
"executor": "@nx/nuxt:serve",
"outputs": ["{options.outputFile}"],
"outputs": ["{options.outputPath}"],
"options": {}
},
"build": {
"executor": "@nx/nuxt:build",
"outputs": ["{options.outputFile}"],
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/my-app"
}
Expand Down Expand Up @@ -209,17 +226,34 @@ import { defineNuxtConfig } from 'nuxt/config';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
srcDir: 'src',
buildDir: 'dist/myapp1/.nuxt',
devtools: { enabled: true },
devServer: {
host: 'localhost',
port: 4200,
},
typescript: {
typeCheck: true,
tsConfig: {
extends: 'myapp1/tsconfig.app.json',
},
},
imports: {
autoImport: false,
},
css: ['~/assets/css/styles.css'],
vite: {
plugins: [nxViteTsPaths()],
},
nitro: {
output: {
dir: 'dist/myapp1/.output',
serverDir: 'dist/myapp1/.output/server',
publicDir: 'dist/myapp1/.output/public',
},
},
});
"
`;
Expand All @@ -231,17 +265,34 @@ import { defineNuxtConfig } from 'nuxt/config';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
srcDir: 'src',
buildDir: 'dist/myapp3/.nuxt',
devtools: { enabled: true },
devServer: {
host: 'localhost',
port: 4200,
},
typescript: {
typeCheck: true,
tsConfig: {
extends: 'myapp3/tsconfig.app.json',
},
},
imports: {
autoImport: false,
},
css: ['~/assets/css/styles.less'],
vite: {
plugins: [nxViteTsPaths()],
},
nitro: {
output: {
dir: 'dist/myapp3/.output',
serverDir: 'dist/myapp3/.output/server',
publicDir: 'dist/myapp3/.output/public',
},
},
});
"
`;
Expand All @@ -253,17 +304,34 @@ import { defineNuxtConfig } from 'nuxt/config';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
srcDir: 'src',
buildDir: 'dist/myapp2/.nuxt',
devtools: { enabled: true },
devServer: {
host: 'localhost',
port: 4200,
},
typescript: {
typeCheck: true,
tsConfig: {
extends: 'myapp2/tsconfig.app.json',
},
},
imports: {
autoImport: false,
},
css: ['~/assets/css/styles.scss'],
vite: {
plugins: [nxViteTsPaths()],
},
nitro: {
output: {
dir: 'dist/myapp2/.output',
serverDir: 'dist/myapp2/.output/server',
publicDir: 'dist/myapp2/.output/public',
},
},
});
"
`;
Expand All @@ -275,15 +343,32 @@ import { defineNuxtConfig } from 'nuxt/config';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
srcDir: 'src',
buildDir: 'dist/myapp4/.nuxt',
devtools: { enabled: true },
devServer: {
host: 'localhost',
port: 4200,
},
typescript: {
typeCheck: true,
tsConfig: {
extends: 'myapp4/tsconfig.app.json',
},
},
imports: {
autoImport: false,
},
vite: {
plugins: [nxViteTsPaths()],
},
nitro: {
output: {
dir: 'dist/myapp4/.output',
serverDir: 'dist/myapp4/.output/server',
publicDir: 'dist/myapp4/.output/public',
},
},
});
"
`;
5 changes: 5 additions & 0 deletions packages/nuxt/src/generators/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ export async function applicationGenerator(tree: Tree, schema: Schema) {
dot: '.',
tmpl: '',
style: options.style,
projectRoot: options.appProjectRoot,
buildDirectory: joinPathFragments(`dist/${options.appProjectRoot}/.nuxt`),
nitroOutputDir: joinPathFragments(
`dist/${options.appProjectRoot}/.output`
),
}
);

Expand Down
Loading

1 comment on commit bdc30ca

@vercel
Copy link

@vercel vercel bot commented on bdc30ca Nov 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nx-dev – ./

nx-dev-git-master-nrwl.vercel.app
nx-dev-nrwl.vercel.app
nx.dev
nx-five.vercel.app

Please sign in to comment.