Skip to content

Commit

Permalink
feat(angular): add buildLibsFromSource option to @nrwl/angular:webpac…
Browse files Browse the repository at this point in the history
…k-browser executor (#9334)
  • Loading branch information
leosvelperez committed Mar 15, 2022
1 parent ac464b9 commit a82edb1
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 22 deletions.
8 changes: 8 additions & 0 deletions docs/generated/api-angular/executors/webpack-browser.md
Expand Up @@ -69,6 +69,14 @@ Type: `array`

Budget thresholds to ensure parts of your application stay within boundaries which you set.

### buildLibsFromSource

Default: `true`

Type: `boolean`

Read buildable libraries from source instead of building them separately.

### buildOptimizer

Default: `true`
Expand Down
10 changes: 8 additions & 2 deletions docs/shared/guides/setup-incremental-builds-angular.md
Expand Up @@ -67,7 +67,10 @@ Change your Angular app’s “build” target executor to `@nrwl/angular:webpac
"build": {
"executor": "@nrwl/angular:webpack-browser",
"outputs": ["{options.outputPath}"],
"options": { ... },
"options": {
"buildLibsFromSource": false
...
},
"configurations": { ... },
"defaultConfiguration": "production"
},
Expand Down Expand Up @@ -111,7 +114,10 @@ Note: you can specify the `--parallel` flags as part of the options property on
"build": {
"executor": "@nrwl/angular:webpack-browser",
"outputs": ["{options.outputPath}"],
"options": { ... },
"options": {
"buildLibsFromSource": false
...
},
"configurations": { ... }
},
"serve": {
Expand Down
4 changes: 4 additions & 0 deletions e2e/angular-core/src/projects.test.ts
Expand Up @@ -155,6 +155,10 @@ describe('Angular Projects', () => {
// update the angular.json
updateProjectConfig(app, (config) => {
config.targets.build.executor = '@nrwl/angular:webpack-browser';
config.targets.build.options = {
...config.targets.build.options,
buildLibsFromSource: false,
};
return config;
});

Expand Down
9 changes: 9 additions & 0 deletions e2e/angular-extensions/src/tailwind.test.ts
Expand Up @@ -9,6 +9,7 @@ import {
runCLI,
uniq,
updateFile,
updateProjectConfig,
} from '@nrwl/e2e/utils';

describe('Tailwind support', () => {
Expand Down Expand Up @@ -357,6 +358,14 @@ describe('Tailwind support', () => {
runCLI(
`generate @nrwl/angular:app ${appWithTailwind} --add-tailwind --no-interactive`
);
updateProjectConfig(appWithTailwind, (config) => {
config.targets.build.executor = '@nrwl/angular:webpack-browser';
config.targets.build.options = {
...config.targets.build.options,
buildLibsFromSource: false,
};
return config;
});
updateTailwindConfig(
`apps/${appWithTailwind}/tailwind.config.js`,
spacing.projectVariant1
Expand Down
6 changes: 6 additions & 0 deletions packages/angular/migrations.json
Expand Up @@ -156,6 +156,12 @@
"version": "13.8.4",
"description": "Karma coverage is broken since Angular 13 upgarde and the karma config is severely out of date. Bring it up to date fixing the coverage issue.",
"factory": "./src/migrations/update-13-8-4/migrate-karma-conf"
},
"set-build-libs-from-source": {
"cli": "nx",
"version": "13.9.0-beta.4",
"description": "Set buildLibsFromSource property to false to not break existing usage.",
"factory": "./src/migrations/update-13-9-0/set-build-libs-from-source"
}
},
"packageJsonUpdates": {
Expand Down
5 changes: 5 additions & 0 deletions packages/angular/src/builders/webpack-browser/schema.json
Expand Up @@ -371,6 +371,11 @@
}
},
"additionalProperties": false
},
"buildLibsFromSource": {
"type": "boolean",
"description": "Read buildable libraries from source instead of building them separately.",
"default": true
}
},
"additionalProperties": false,
Expand Down
Expand Up @@ -12,10 +12,11 @@ import {
calculateProjectDependencies,
checkDependentProjectsHaveBeenBuilt,
createTmpTsConfig,
DependentBuildableProjectNode,
} from '@nrwl/workspace/src/utilities/buildable-libs-utils';
import { existsSync } from 'fs';
import { join } from 'path';
import { from, Observable, of } from 'rxjs';
import { Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { merge } from 'webpack-merge';
import { resolveCustomWebpackConfig } from '../utilities/webpack';
Expand All @@ -24,13 +25,15 @@ export type BrowserBuilderSchema = Schema & {
customWebpackConfig?: {
path: string;
};
buildLibsFromSource?: boolean;
};

function buildApp(
options: BrowserBuilderSchema,
context: BuilderContext
): Observable<BuilderOutput> {
const { customWebpackConfig, ...delegateOptions } = options;
const { buildLibsFromSource, customWebpackConfig, ...delegateOptions } =
options;
// If there is a path to custom webpack config
// Invoke our own support for custom webpack config
if (customWebpackConfig && customWebpackConfig.path) {
Expand Down Expand Up @@ -91,29 +94,37 @@ function run(
options: BrowserBuilderSchema,
context: BuilderContext
): Observable<BuilderOutput> {
const { target, dependencies } = calculateProjectDependencies(
readCachedProjectGraph(),
context.workspaceRoot,
context.target.project,
context.target.target,
context.target.configuration
);

options.tsConfig = createTmpTsConfig(
join(context.workspaceRoot, options.tsConfig),
context.workspaceRoot,
target.data.root,
dependencies
);
process.env.NX_TSCONFIG_PATH = options.tsConfig;
options.buildLibsFromSource ??= true;
let dependencies: DependentBuildableProjectNode[];

return of(
checkDependentProjectsHaveBeenBuilt(
if (!options.buildLibsFromSource) {
const result = calculateProjectDependencies(
readCachedProjectGraph(),
context.workspaceRoot,
context.target.project,
context.target.target,
context.target.configuration
);
dependencies = result.dependencies;

options.tsConfig = createTmpTsConfig(
join(context.workspaceRoot, options.tsConfig),
context.workspaceRoot,
result.target.data.root,
dependencies
)
);
}
process.env.NX_TSCONFIG_PATH = options.tsConfig;

return of(
!options.buildLibsFromSource
? checkDependentProjectsHaveBeenBuilt(
context.workspaceRoot,
context.target.project,
context.target.target,
dependencies
)
: true
).pipe(
switchMap((result) => {
if (result) {
Expand Down
@@ -0,0 +1,63 @@
import {
addProjectConfiguration,
ProjectConfiguration,
readProjectConfiguration,
Tree,
} from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import migration from './set-build-libs-from-source';

describe('set-build-libs-from-source migration', () => {
let tree: Tree;

beforeEach(() => {
tree = createTreeWithEmptyWorkspace(2);
});

it('should not error when project does not have targets', async () => {
addProjectConfiguration(tree, 'app1', { root: 'apps/app1' });

await expect(migration(tree)).resolves.not.toThrow();
});

it('should not update when not using the @nrwl/angular:webpack-browser executor', async () => {
const project: ProjectConfiguration = {
root: 'apps/app1',
targets: { build: { executor: '@nrwl/angular:package' } },
};
addProjectConfiguration(tree, 'app1', project);

await migration(tree);

const resultingProject = readProjectConfiguration(tree, 'app1');
expect(project).toStrictEqual(resultingProject);
});

it('should set buildLibsFromSource to false', async () => {
addProjectConfiguration(tree, 'app1', {
root: 'apps/app1',
targets: { build: { executor: '@nrwl/angular:webpack-browser' } },
});

await migration(tree);

const project = readProjectConfiguration(tree, 'app1');
expect(project.targets.build.options).toStrictEqual({
buildLibsFromSource: false,
});
});

it('should support any target name using @nrwl/angular:webpack-browser', async () => {
addProjectConfiguration(tree, 'app1', {
root: 'apps/app1',
targets: { 'build-base': { executor: '@nrwl/angular:webpack-browser' } },
});

await migration(tree);

const project = readProjectConfiguration(tree, 'app1');
expect(project.targets['build-base'].options).toStrictEqual({
buildLibsFromSource: false,
});
});
});
@@ -0,0 +1,30 @@
import {
formatFiles,
getProjects,
Tree,
updateProjectConfiguration,
} from '@nrwl/devkit';

export default async function (tree: Tree) {
const projects = getProjects(tree);

for (const [projectName, project] of projects) {
if (!project.targets) {
continue;
}

let shouldUpdate = false;
Object.values(project.targets).forEach((target) => {
if (target.executor === '@nrwl/angular:webpack-browser') {
shouldUpdate = true;
target.options = { ...target.options, buildLibsFromSource: false };
}
});

if (shouldUpdate) {
updateProjectConfiguration(tree, projectName, project);
}
}

await formatFiles(tree);
}

1 comment on commit a82edb1

@vercel
Copy link

@vercel vercel bot commented on a82edb1 Mar 15, 2022

Choose a reason for hiding this comment

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

Please sign in to comment.