feat(react): migrate next builders to devkit (#4861)
This commit is contained in:
parent
956dfe6509
commit
fd18b5edec
@ -68,6 +68,8 @@ describe('create-nx-workspace', () => {
|
||||
style: 'css',
|
||||
appName,
|
||||
});
|
||||
|
||||
expectNoAngularDevkit();
|
||||
});
|
||||
|
||||
it('should be able to create an web-components workspace', () => {
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
"excludedFiles": ["./src/migrations/**"],
|
||||
"rules": {
|
||||
"no-restricted-imports": [
|
||||
"warn",
|
||||
"error",
|
||||
"@nrwl/workspace",
|
||||
"@angular-devkit/core",
|
||||
"@angular-devkit/schematics",
|
||||
|
||||
@ -1,19 +1,35 @@
|
||||
{
|
||||
"$schema": "@angular-devkit/architect/src/builders-schema.json",
|
||||
"builders": {
|
||||
"executors": {
|
||||
"build": {
|
||||
"implementation": "./src/builders/build/build.impl",
|
||||
"schema": "./src/builders/build/schema.json",
|
||||
"implementation": "./src/executors/build/build.impl",
|
||||
"schema": "./src/executors/build/schema.json",
|
||||
"description": "Build a Next.js app"
|
||||
},
|
||||
"server": {
|
||||
"implementation": "./src/builders/server/server.impl",
|
||||
"schema": "./src/builders/server/schema.json",
|
||||
"implementation": "./src/executors/server/server.impl",
|
||||
"schema": "./src/executors/server/schema.json",
|
||||
"description": "Serve a Next.js app"
|
||||
},
|
||||
"export": {
|
||||
"implementation": "./src/builders/export/export.impl",
|
||||
"schema": "./src/builders/export/schema.json",
|
||||
"implementation": "./src/executors/export/export.impl",
|
||||
"schema": "./src/executors/export/schema.json",
|
||||
"description": "Export a Next.js app. The exported application is located at dist/$outputPath/exported."
|
||||
}
|
||||
},
|
||||
"builders": {
|
||||
"build": {
|
||||
"implementation": "./src/executors/build/compat",
|
||||
"schema": "./src/executors/build/schema.json",
|
||||
"description": "Build a Next.js app"
|
||||
},
|
||||
"server": {
|
||||
"implementation": "./src/executors/server/compat",
|
||||
"schema": "./src/executors/server/schema.json",
|
||||
"description": "Serve a Next.js app"
|
||||
},
|
||||
"export": {
|
||||
"implementation": "./src/executors/export/compat",
|
||||
"schema": "./src/executors/export/schema.json",
|
||||
"description": "Export a Next.js app. The exported application is located at dist/$outputPath/exported."
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,9 +37,7 @@
|
||||
"@nrwl/jest": "*",
|
||||
"@nrwl/linter": "*",
|
||||
"@nrwl/web": "*",
|
||||
"@angular-devkit/architect": "~0.1102.0",
|
||||
"@angular-devkit/schematics": "~11.2.0",
|
||||
"@angular-devkit/core": "~11.2.0",
|
||||
"@nrwl/workspace": "*",
|
||||
"@svgr/webpack": "^5.4.0",
|
||||
"chalk": "4.1.0",
|
||||
"copy-webpack-plugin": "6.0.3",
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
import {
|
||||
BuilderContext,
|
||||
BuilderOutput,
|
||||
createBuilder,
|
||||
} from '@angular-devkit/architect';
|
||||
import build from 'next/dist/build';
|
||||
import { PHASE_PRODUCTION_BUILD } from 'next/dist/next-server/lib/constants';
|
||||
import * as path from 'path';
|
||||
import { copySync } from 'fs-extra';
|
||||
import { from, Observable } from 'rxjs';
|
||||
import { concatMap, map, tap } from 'rxjs/operators';
|
||||
import { prepareConfig } from '../../utils/config';
|
||||
import { NextBuildBuilderOptions } from '../../utils/types';
|
||||
import { createPackageJson } from './lib/create-package-json';
|
||||
import { createNextConfigFile } from './lib/create-next-config-file';
|
||||
import { join } from 'path';
|
||||
|
||||
try {
|
||||
require('dotenv').config();
|
||||
} catch (e) {}
|
||||
|
||||
export default createBuilder<NextBuildBuilderOptions>(run);
|
||||
|
||||
export function run(
|
||||
options: NextBuildBuilderOptions,
|
||||
context: BuilderContext
|
||||
): Observable<BuilderOutput> {
|
||||
const root = path.resolve(context.workspaceRoot, options.root);
|
||||
const config = prepareConfig(PHASE_PRODUCTION_BUILD, options, context);
|
||||
return from(build(root, config as any)).pipe(
|
||||
concatMap(() => from(createPackageJson(options, context))),
|
||||
concatMap(() => from(createNextConfigFile(options, context))),
|
||||
tap(() => {
|
||||
copySync(join(root, 'public'), join(options.outputPath, 'public'));
|
||||
}),
|
||||
map(() => ({ success: true }))
|
||||
);
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
import {
|
||||
BuilderContext,
|
||||
BuilderOutput,
|
||||
createBuilder,
|
||||
scheduleTargetAndForget,
|
||||
targetFromTargetString,
|
||||
} from '@angular-devkit/architect';
|
||||
import exportApp from 'next/dist/export';
|
||||
import { PHASE_EXPORT } from 'next/dist/next-server/lib/constants';
|
||||
import * as path from 'path';
|
||||
import { from, Observable, of } from 'rxjs';
|
||||
import { concatMap, map } from 'rxjs/operators';
|
||||
import { prepareConfig } from '../../utils/config';
|
||||
import {
|
||||
NextBuildBuilderOptions,
|
||||
NextExportBuilderOptions,
|
||||
} from '../../utils/types';
|
||||
|
||||
try {
|
||||
require('dotenv').config();
|
||||
} catch (e) {}
|
||||
|
||||
export default createBuilder<NextExportBuilderOptions>(run);
|
||||
|
||||
function run(
|
||||
options: NextExportBuilderOptions,
|
||||
context: BuilderContext
|
||||
): Observable<BuilderOutput> {
|
||||
const buildTarget = targetFromTargetString(options.buildTarget);
|
||||
const build$ = scheduleTargetAndForget(context, buildTarget);
|
||||
|
||||
return build$.pipe(
|
||||
concatMap((r) => {
|
||||
if (!r.success) return of(r);
|
||||
return from(context.getTargetOptions(buildTarget)).pipe(
|
||||
concatMap((buildOptions: NextBuildBuilderOptions) => {
|
||||
const root = path.resolve(context.workspaceRoot, buildOptions.root);
|
||||
const config = prepareConfig(PHASE_EXPORT, buildOptions, context);
|
||||
return from(
|
||||
exportApp(
|
||||
root,
|
||||
{
|
||||
statusMessage: 'Exporting',
|
||||
silent: options.silent,
|
||||
threads: options.threads,
|
||||
outdir: `${buildOptions.outputPath}/exported`,
|
||||
} as any,
|
||||
config
|
||||
)
|
||||
).pipe(map(() => ({ success: true })));
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
@ -1,106 +0,0 @@
|
||||
import {
|
||||
BuilderContext,
|
||||
BuilderOutput,
|
||||
createBuilder,
|
||||
scheduleTargetAndForget,
|
||||
targetFromTargetString,
|
||||
} from '@angular-devkit/architect';
|
||||
import * as chalk from 'chalk';
|
||||
import * as fs from 'fs';
|
||||
import {
|
||||
PHASE_DEVELOPMENT_SERVER,
|
||||
PHASE_PRODUCTION_SERVER,
|
||||
} from 'next/dist/next-server/lib/constants';
|
||||
import * as path from 'path';
|
||||
import { from, Observable, of, throwError } from 'rxjs';
|
||||
import { catchError, concatMap, switchMap, tap } from 'rxjs/operators';
|
||||
import { prepareConfig } from '../../utils/config';
|
||||
import {
|
||||
NextBuildBuilderOptions,
|
||||
NextServeBuilderOptions,
|
||||
NextServer,
|
||||
NextServerOptions,
|
||||
ProxyConfig,
|
||||
} from '../../utils/types';
|
||||
import { customServer } from './lib/custom-server';
|
||||
import { defaultServer } from './lib/default-server';
|
||||
|
||||
try {
|
||||
require('dotenv').config();
|
||||
} catch (e) {}
|
||||
|
||||
export default createBuilder<NextServeBuilderOptions>(run);
|
||||
|
||||
const infoPrefix = `[ ${chalk.dim(chalk.cyan('info'))} ] `;
|
||||
const readyPrefix = `[ ${chalk.green('ready')} ]`;
|
||||
|
||||
export function run(
|
||||
options: NextServeBuilderOptions,
|
||||
context: BuilderContext
|
||||
): Observable<BuilderOutput> {
|
||||
const buildTarget = targetFromTargetString(options.buildTarget);
|
||||
const baseUrl = `http://${options.hostname || 'localhost'}:${options.port}`;
|
||||
|
||||
return from(context.getTargetOptions(buildTarget)).pipe(
|
||||
concatMap((buildOptions: NextBuildBuilderOptions) => {
|
||||
const root = path.resolve(context.workspaceRoot, buildOptions.root);
|
||||
|
||||
const config = prepareConfig(
|
||||
options.dev ? PHASE_DEVELOPMENT_SERVER : PHASE_PRODUCTION_SERVER,
|
||||
buildOptions,
|
||||
context
|
||||
);
|
||||
|
||||
const settings: NextServerOptions = {
|
||||
dev: options.dev,
|
||||
dir: root,
|
||||
staticMarkup: options.staticMarkup,
|
||||
quiet: options.quiet,
|
||||
conf: config,
|
||||
port: options.port,
|
||||
path: options.customServerPath,
|
||||
hostname: options.hostname,
|
||||
};
|
||||
|
||||
const server: NextServer = options.customServerPath
|
||||
? customServer
|
||||
: defaultServer;
|
||||
|
||||
// look for the proxy.conf.json
|
||||
let proxyConfig: ProxyConfig;
|
||||
const proxyConfigPath = options.proxyConfig
|
||||
? path.join(context.workspaceRoot, options.proxyConfig)
|
||||
: path.join(root, 'proxy.conf.json');
|
||||
if (fs.existsSync(proxyConfigPath)) {
|
||||
context.logger.info(
|
||||
`${infoPrefix} found proxy configuration at ${proxyConfigPath}`
|
||||
);
|
||||
proxyConfig = require(proxyConfigPath);
|
||||
}
|
||||
|
||||
return from(server(settings, proxyConfig)).pipe(
|
||||
catchError((err) => {
|
||||
if (options.dev) {
|
||||
throw err;
|
||||
} else {
|
||||
throw new Error(
|
||||
`Could not start production server. Try building your app with \`nx build ${context.target.project}\`.`
|
||||
);
|
||||
}
|
||||
}),
|
||||
tap(() => {
|
||||
context.logger.info(`${readyPrefix} on ${baseUrl}`);
|
||||
}),
|
||||
switchMap(
|
||||
(e) =>
|
||||
new Observable<BuilderOutput>((obs) => {
|
||||
obs.next({
|
||||
baseUrl,
|
||||
success: true,
|
||||
});
|
||||
})
|
||||
)
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
@ -1,8 +1,9 @@
|
||||
import { MockBuilderContext } from '@nrwl/workspace/testing';
|
||||
import { ExecutorContext } from '@nrwl/devkit';
|
||||
|
||||
import * as build from 'next/dist/build';
|
||||
import { getMockContext } from '../../utils/testing';
|
||||
|
||||
import { NextBuildBuilderOptions } from '../../utils/types';
|
||||
import { run } from './build.impl';
|
||||
import buildExecutor from './build.impl';
|
||||
|
||||
jest.mock('fs-extra');
|
||||
jest.mock('next/dist/build');
|
||||
@ -13,12 +14,21 @@ jest.mock('./lib/create-package-json', () => {
|
||||
});
|
||||
|
||||
describe('Next.js Builder', () => {
|
||||
let context: MockBuilderContext;
|
||||
let context: ExecutorContext;
|
||||
let options: NextBuildBuilderOptions;
|
||||
|
||||
beforeEach(async () => {
|
||||
context = await getMockContext();
|
||||
|
||||
context = {
|
||||
root: '/root',
|
||||
cwd: '/root',
|
||||
projectName: 'my-app',
|
||||
targetName: 'build',
|
||||
workspace: {
|
||||
version: 2,
|
||||
projects: {},
|
||||
},
|
||||
isVerbose: false,
|
||||
};
|
||||
options = {
|
||||
root: 'apps/wibble',
|
||||
outputPath: 'dist/apps/wibble',
|
||||
@ -34,7 +44,7 @@ describe('Next.js Builder', () => {
|
||||
});
|
||||
|
||||
it('should call next build', async () => {
|
||||
await run(options, context).toPromise();
|
||||
await buildExecutor(options, context);
|
||||
|
||||
expect(build.default).toHaveBeenCalledWith(
|
||||
'/root/apps/wibble',
|
||||
31
packages/next/src/executors/build/build.impl.ts
Normal file
31
packages/next/src/executors/build/build.impl.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { ExecutorContext } from '@nrwl/devkit';
|
||||
|
||||
import build from 'next/dist/build';
|
||||
import { PHASE_PRODUCTION_BUILD } from 'next/dist/next-server/lib/constants';
|
||||
|
||||
import { join, resolve } from 'path';
|
||||
import { copySync } from 'fs-extra';
|
||||
|
||||
import { prepareConfig } from '../../utils/config';
|
||||
import { NextBuildBuilderOptions } from '../../utils/types';
|
||||
import { createPackageJson } from './lib/create-package-json';
|
||||
import { createNextConfigFile } from './lib/create-next-config-file';
|
||||
|
||||
try {
|
||||
require('dotenv').config();
|
||||
} catch (e) {}
|
||||
|
||||
export default async function buildExecutor(
|
||||
options: NextBuildBuilderOptions,
|
||||
context: ExecutorContext
|
||||
) {
|
||||
const root = resolve(context.root, options.root);
|
||||
const config = prepareConfig(PHASE_PRODUCTION_BUILD, options, context);
|
||||
await build(root, config as any);
|
||||
createPackageJson(options, context);
|
||||
createNextConfigFile(options, context);
|
||||
|
||||
copySync(join(root, 'public'), join(options.outputPath, 'public'));
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
5
packages/next/src/executors/build/compat.ts
Normal file
5
packages/next/src/executors/build/compat.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { convertNxExecutor } from '@nrwl/devkit';
|
||||
|
||||
import buildExecutor from './build.impl';
|
||||
|
||||
export default convertNxExecutor(buildExecutor);
|
||||
@ -1,15 +1,17 @@
|
||||
import { ExecutorContext } from '@nrwl/devkit';
|
||||
|
||||
import { copyFileSync, existsSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { BuilderContext } from '@angular-devkit/architect';
|
||||
|
||||
import { NextBuildBuilderOptions } from '../../../utils/types';
|
||||
|
||||
export async function createNextConfigFile(
|
||||
export function createNextConfigFile(
|
||||
options: NextBuildBuilderOptions,
|
||||
context: BuilderContext
|
||||
context: ExecutorContext
|
||||
) {
|
||||
const nextConfigPath = options.nextConfig
|
||||
? join(context.workspaceRoot, options.nextConfig)
|
||||
: join(context.workspaceRoot, options.root, 'next.config.js');
|
||||
? join(context.root, options.nextConfig)
|
||||
: join(context.root, options.root, 'next.config.js');
|
||||
|
||||
if (existsSync(nextConfigPath)) {
|
||||
copyFileSync(nextConfigPath, join(options.outputPath, 'next.config.js'));
|
||||
@ -1,16 +1,22 @@
|
||||
import { BuilderContext } from '@angular-devkit/architect';
|
||||
import { ExecutorContext } from '@nrwl/devkit';
|
||||
|
||||
import { writeFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { readJsonFile } from '@nrwl/workspace';
|
||||
|
||||
import { createProjectGraph } from '@nrwl/workspace/src/core/project-graph';
|
||||
import { calculateProjectDependencies } from '@nrwl/workspace/src/utils/buildable-libs-utils';
|
||||
import { readJsonFile } from '@nrwl/workspace/src/utilities/fileutils';
|
||||
import { calculateProjectDependencies } from '@nrwl/workspace/src/utilities/buildable-libs-utils';
|
||||
|
||||
import { NextBuildBuilderOptions } from '../../../utils/types';
|
||||
|
||||
function getProjectDeps(context: BuilderContext, rootPackageJson: any) {
|
||||
function getProjectDeps(context: ExecutorContext, rootPackageJson: any) {
|
||||
const projGraph = createProjectGraph();
|
||||
const { dependencies: deps } = calculateProjectDependencies(
|
||||
projGraph,
|
||||
context
|
||||
context.root,
|
||||
context.projectName,
|
||||
context.targetName,
|
||||
context.configurationName
|
||||
);
|
||||
const depNames = deps
|
||||
.map((d) => d.node)
|
||||
@ -36,20 +42,18 @@ function getProjectDeps(context: BuilderContext, rootPackageJson: any) {
|
||||
};
|
||||
}
|
||||
|
||||
export async function createPackageJson(
|
||||
export function createPackageJson(
|
||||
options: NextBuildBuilderOptions,
|
||||
context: BuilderContext
|
||||
context: ExecutorContext
|
||||
) {
|
||||
const rootPackageJson = readJsonFile(
|
||||
join(context.workspaceRoot, 'package.json')
|
||||
);
|
||||
const rootPackageJson = readJsonFile(join(context.root, 'package.json'));
|
||||
const { dependencies, devDependencies } = getProjectDeps(
|
||||
context,
|
||||
rootPackageJson
|
||||
);
|
||||
|
||||
const outPackageJson = {
|
||||
name: context.target.project,
|
||||
name: context.projectName,
|
||||
version: '0.0.1',
|
||||
scripts: {
|
||||
start: 'next start',
|
||||
@ -1,5 +1,6 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/schema",
|
||||
"cli": "nx",
|
||||
"title": "Next Build",
|
||||
"description": "Build a Next.js app",
|
||||
"type": "object",
|
||||
5
packages/next/src/executors/export/compat.ts
Normal file
5
packages/next/src/executors/export/compat.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { convertNxExecutor } from '@nrwl/devkit';
|
||||
|
||||
import exportExecutor from './export.impl';
|
||||
|
||||
export default convertNxExecutor(exportExecutor);
|
||||
52
packages/next/src/executors/export/export.impl.ts
Normal file
52
packages/next/src/executors/export/export.impl.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import {
|
||||
ExecutorContext,
|
||||
parseTargetString,
|
||||
readTargetOptions,
|
||||
runExecutor,
|
||||
} from '@nrwl/devkit';
|
||||
import exportApp from 'next/dist/export';
|
||||
import { PHASE_EXPORT } from 'next/dist/next-server/lib/constants';
|
||||
import { resolve } from 'path';
|
||||
import { prepareConfig } from '../../utils/config';
|
||||
import {
|
||||
NextBuildBuilderOptions,
|
||||
NextExportBuilderOptions,
|
||||
} from '../../utils/types';
|
||||
|
||||
try {
|
||||
require('dotenv').config();
|
||||
} catch (e) {}
|
||||
|
||||
export default async function exportExecutor(
|
||||
options: NextExportBuilderOptions,
|
||||
context: ExecutorContext
|
||||
) {
|
||||
const buildTarget = parseTargetString(options.buildTarget);
|
||||
const build = await runExecutor(buildTarget, {}, context);
|
||||
|
||||
for await (const result of build) {
|
||||
if (!result.success) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
const buildOptions = readTargetOptions<NextBuildBuilderOptions>(
|
||||
buildTarget,
|
||||
context
|
||||
);
|
||||
const root = resolve(context.root, buildOptions.root);
|
||||
const config = prepareConfig(PHASE_EXPORT, buildOptions, context);
|
||||
|
||||
await exportApp(
|
||||
root,
|
||||
{
|
||||
statusMessage: 'Exporting',
|
||||
silent: options.silent,
|
||||
threads: options.threads,
|
||||
outdir: `${buildOptions.outputPath}/exported`,
|
||||
} as any,
|
||||
config
|
||||
);
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
{
|
||||
"cli": "nx",
|
||||
"title": "Next Export",
|
||||
"description": "Export a Next.js app. The exported application is located at dist/$outputPath/exported.",
|
||||
"type": "object",
|
||||
5
packages/next/src/executors/server/compat.ts
Normal file
5
packages/next/src/executors/server/compat.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { convertNxExecutor } from '@nrwl/devkit';
|
||||
|
||||
import serverExecutor from './server.impl';
|
||||
|
||||
export default convertNxExecutor(serverExecutor);
|
||||
@ -1,4 +1,5 @@
|
||||
{
|
||||
"cli": "nx",
|
||||
"title": "Next Serve",
|
||||
"description": "Serve a Next.js app",
|
||||
"type": "object",
|
||||
98
packages/next/src/executors/server/server.impl.ts
Normal file
98
packages/next/src/executors/server/server.impl.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import {
|
||||
ExecutorContext,
|
||||
logger,
|
||||
parseTargetString,
|
||||
readTargetOptions,
|
||||
} from '@nrwl/devkit';
|
||||
import {
|
||||
PHASE_DEVELOPMENT_SERVER,
|
||||
PHASE_PRODUCTION_SERVER,
|
||||
} from 'next/dist/next-server/lib/constants';
|
||||
|
||||
import * as chalk from 'chalk';
|
||||
import { existsSync } from 'fs';
|
||||
import { join, resolve } from 'path';
|
||||
|
||||
import { prepareConfig } from '../../utils/config';
|
||||
import {
|
||||
NextBuildBuilderOptions,
|
||||
NextServeBuilderOptions,
|
||||
NextServer,
|
||||
NextServerOptions,
|
||||
ProxyConfig,
|
||||
} from '../../utils/types';
|
||||
import { customServer } from './lib/custom-server';
|
||||
import { defaultServer } from './lib/default-server';
|
||||
|
||||
try {
|
||||
require('dotenv').config();
|
||||
} catch (e) {}
|
||||
|
||||
const infoPrefix = `[ ${chalk.dim(chalk.cyan('info'))} ] `;
|
||||
const readyPrefix = `[ ${chalk.green('ready')} ]`;
|
||||
|
||||
export default async function* serveExecutor(
|
||||
options: NextServeBuilderOptions,
|
||||
context: ExecutorContext
|
||||
) {
|
||||
const buildTarget = parseTargetString(options.buildTarget);
|
||||
const baseUrl = `http://${options.hostname || 'localhost'}:${options.port}`;
|
||||
const buildOptions = readTargetOptions<NextBuildBuilderOptions>(
|
||||
buildTarget,
|
||||
context
|
||||
);
|
||||
const root = resolve(context.root, buildOptions.root);
|
||||
const config = prepareConfig(
|
||||
options.dev ? PHASE_DEVELOPMENT_SERVER : PHASE_PRODUCTION_SERVER,
|
||||
buildOptions,
|
||||
context
|
||||
);
|
||||
const settings: NextServerOptions = {
|
||||
dev: options.dev,
|
||||
dir: root,
|
||||
staticMarkup: options.staticMarkup,
|
||||
quiet: options.quiet,
|
||||
conf: config,
|
||||
port: options.port,
|
||||
path: options.customServerPath,
|
||||
hostname: options.hostname,
|
||||
};
|
||||
|
||||
const server: NextServer = options.customServerPath
|
||||
? customServer
|
||||
: defaultServer;
|
||||
|
||||
// look for the proxy.conf.json
|
||||
let proxyConfig: ProxyConfig;
|
||||
const proxyConfigPath = options.proxyConfig
|
||||
? join(context.root, options.proxyConfig)
|
||||
: join(root, 'proxy.conf.json');
|
||||
|
||||
if (existsSync(proxyConfigPath)) {
|
||||
logger.info(
|
||||
`${infoPrefix} found proxy configuration at ${proxyConfigPath}`
|
||||
);
|
||||
proxyConfig = require(proxyConfigPath);
|
||||
}
|
||||
|
||||
try {
|
||||
await server(settings, proxyConfig);
|
||||
logger.info(`${readyPrefix} on ${baseUrl}`);
|
||||
|
||||
yield {
|
||||
baseUrl,
|
||||
success: true,
|
||||
};
|
||||
|
||||
// This Promise intentionally never resolves, leaving the process running
|
||||
await new Promise<{ success: boolean }>(() => {});
|
||||
} catch (e) {
|
||||
if (options.dev) {
|
||||
throw e;
|
||||
} else {
|
||||
throw new Error(
|
||||
`Could not start production server. Try building your app with \`nx build ${context.projectName}\`.`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import { PHASE_PRODUCTION_BUILD } from 'next/dist/next-server/lib/constants';
|
||||
import { TsconfigPathsPlugin } from 'tsconfig-paths-webpack-plugin';
|
||||
import { createWebpackConfig, prepareConfig } from './config';
|
||||
import { NextBuildBuilderOptions } from '@nrwl/next';
|
||||
|
||||
jest.mock('tsconfig-paths-webpack-plugin');
|
||||
jest.mock('next/dist/next-server/server/config', () => ({
|
||||
@ -93,7 +94,7 @@ describe('Next.js webpack config builder', () => {
|
||||
fileReplacements: [],
|
||||
nextConfig: require.resolve('./config.fixture'),
|
||||
customValue: 'test',
|
||||
},
|
||||
} as NextBuildBuilderOptions,
|
||||
{ workspaceRoot: '/root' } as any
|
||||
);
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { ExecutorContext, offsetFromRoot } from '@nrwl/devkit';
|
||||
import {
|
||||
PHASE_DEVELOPMENT_SERVER,
|
||||
PHASE_EXPORT,
|
||||
@ -9,8 +10,6 @@ import { join, resolve } from 'path';
|
||||
import { TsconfigPathsPlugin } from 'tsconfig-paths-webpack-plugin';
|
||||
import { Configuration } from 'webpack';
|
||||
import { FileReplacement, NextBuildBuilderOptions } from './types';
|
||||
import { BuilderContext } from '@angular-devkit/architect';
|
||||
import { offsetFromRoot } from '@nrwl/devkit';
|
||||
import { normalizeAssets } from '@nrwl/web/src/utils/normalize';
|
||||
import { createCopyPlugin } from '@nrwl/web/src/utils/config';
|
||||
|
||||
@ -122,7 +121,7 @@ export function prepareConfig(
|
||||
| typeof PHASE_DEVELOPMENT_SERVER
|
||||
| typeof PHASE_PRODUCTION_SERVER,
|
||||
options: NextBuildBuilderOptions,
|
||||
context: BuilderContext
|
||||
context: ExecutorContext
|
||||
) {
|
||||
const config = loadConfig(phase, options.root, null);
|
||||
const userWebpack = config.webpack;
|
||||
@ -134,7 +133,7 @@ export function prepareConfig(
|
||||
config.distDir = join(config.outdir, '.next');
|
||||
config.webpack = (a, b) =>
|
||||
createWebpackConfig(
|
||||
context.workspaceRoot,
|
||||
context.root,
|
||||
options.root,
|
||||
options.fileReplacements,
|
||||
options.assets
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
import { Architect } from '@angular-devkit/architect';
|
||||
import { TestingArchitectHost } from '@angular-devkit/architect/testing';
|
||||
import { schema } from '@angular-devkit/core';
|
||||
import { MockBuilderContext } from '@nrwl/workspace/testing';
|
||||
import { join } from 'path';
|
||||
|
||||
export async function getTestArchitect() {
|
||||
const architectHost = new TestingArchitectHost('/root', '/root');
|
||||
const registry = new schema.CoreSchemaRegistry();
|
||||
registry.addPostTransform(schema.transforms.addUndefinedDefaults);
|
||||
|
||||
const architect = new Architect(architectHost, registry);
|
||||
|
||||
await architectHost.addBuilderFromPackage(join(__dirname, '../..'));
|
||||
|
||||
return [architect, architectHost] as [Architect, TestingArchitectHost];
|
||||
}
|
||||
|
||||
export async function getMockContext() {
|
||||
const [architect, architectHost] = await getTestArchitect();
|
||||
|
||||
const context = new MockBuilderContext(architect, architectHost);
|
||||
await context.addBuilderFromPackage(join(__dirname, '../..'));
|
||||
return context;
|
||||
}
|
||||
@ -1,5 +1,3 @@
|
||||
import { JsonObject } from '@angular-devkit/core';
|
||||
|
||||
export type NextServer = (
|
||||
options: NextServerOptions,
|
||||
proxyConfig?: ProxyConfig
|
||||
@ -25,12 +23,12 @@ export interface NextServerOptions {
|
||||
hostname: string;
|
||||
}
|
||||
|
||||
export interface FileReplacement extends JsonObject {
|
||||
export interface FileReplacement {
|
||||
replace: string;
|
||||
with: string;
|
||||
}
|
||||
|
||||
export interface NextBuildBuilderOptions extends JsonObject {
|
||||
export interface NextBuildBuilderOptions {
|
||||
root: string;
|
||||
outputPath: string;
|
||||
fileReplacements: FileReplacement[];
|
||||
@ -38,7 +36,7 @@ export interface NextBuildBuilderOptions extends JsonObject {
|
||||
nextConfig?: string;
|
||||
}
|
||||
|
||||
export interface NextServeBuilderOptions extends JsonObject {
|
||||
export interface NextServeBuilderOptions {
|
||||
dev: boolean;
|
||||
port: number;
|
||||
staticMarkup: boolean;
|
||||
@ -49,7 +47,7 @@ export interface NextServeBuilderOptions extends JsonObject {
|
||||
proxyConfig?: string;
|
||||
}
|
||||
|
||||
export interface NextExportBuilderOptions extends JsonObject {
|
||||
export interface NextExportBuilderOptions {
|
||||
buildTarget: string;
|
||||
silent: boolean;
|
||||
threads: number;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user