mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-15 01:54:04 +08:00
feat(@angular-devkit/build-angular): integrate JIT mode linker
With this change we intergate JIT mode linker into the Angular CLI. Closes #20281
This commit is contained in:
parent
8862a9f07c
commit
2616ef0d3f
@ -16,7 +16,10 @@ export interface ApplicationPresetOptions {
|
||||
translation?: unknown;
|
||||
};
|
||||
|
||||
angularLinker?: boolean;
|
||||
angularLinker?: {
|
||||
shouldLink: boolean;
|
||||
jitMode: boolean;
|
||||
};
|
||||
|
||||
forceES5?: boolean;
|
||||
forceAsyncTransformation?: boolean;
|
||||
@ -124,13 +127,14 @@ export default function (api: unknown, options: ApplicationPresetOptions) {
|
||||
const plugins = [];
|
||||
let needRuntimeTransform = false;
|
||||
|
||||
if (options.angularLinker) {
|
||||
if (options.angularLinker?.shouldLink) {
|
||||
// Babel currently is synchronous so import cannot be used
|
||||
const {
|
||||
createEs2015LinkerPlugin,
|
||||
} = require('@angular/compiler-cli/linker/babel');
|
||||
} = require('@angular/compiler-cli/linker/babel') as typeof import('@angular/compiler-cli/linker/babel');
|
||||
|
||||
plugins.push(createEs2015LinkerPlugin({
|
||||
linkerJitMode: options.angularLinker.jitMode,
|
||||
logger: createNgtscLogger(options.diagnosticReporter),
|
||||
fileSystem: {
|
||||
resolve: path.resolve,
|
||||
@ -138,7 +142,9 @@ export default function (api: unknown, options: ApplicationPresetOptions) {
|
||||
dirname: path.dirname,
|
||||
relative: path.relative,
|
||||
readFile: fs.readFileSync,
|
||||
},
|
||||
// Node.JS types don't overlap the Compiler types.
|
||||
// tslint:disable-next-line: no-any
|
||||
} as any,
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -10,11 +10,9 @@ import { custom } from 'babel-loader';
|
||||
import { ScriptTarget } from 'typescript';
|
||||
import { ApplicationPresetOptions } from './presets/application';
|
||||
|
||||
interface AngularCustomOptions {
|
||||
interface AngularCustomOptions extends Pick<ApplicationPresetOptions, 'angularLinker' | 'i18n'> {
|
||||
forceAsyncTransformation: boolean;
|
||||
forceES5: boolean;
|
||||
shouldLink: boolean;
|
||||
i18n: ApplicationPresetOptions['i18n'];
|
||||
}
|
||||
|
||||
function requiresLinking(
|
||||
@ -41,20 +39,25 @@ export default custom<AngularCustomOptions>(() => {
|
||||
});
|
||||
|
||||
return {
|
||||
async customOptions({ i18n, scriptTarget, ...rawOptions }, { source }) {
|
||||
async customOptions({ i18n, scriptTarget, aot, ...rawOptions }, { source }) {
|
||||
// Must process file if plugins are added
|
||||
let shouldProcess = Array.isArray(rawOptions.plugins) && rawOptions.plugins.length > 0;
|
||||
|
||||
const customOptions: AngularCustomOptions = {
|
||||
forceAsyncTransformation: false,
|
||||
forceES5: false,
|
||||
shouldLink: false,
|
||||
angularLinker: undefined,
|
||||
i18n: undefined,
|
||||
};
|
||||
|
||||
// Analyze file for linking
|
||||
customOptions.shouldLink = await requiresLinking(this.resourcePath, source);
|
||||
shouldProcess ||= customOptions.shouldLink;
|
||||
if (await requiresLinking(this.resourcePath, source)) {
|
||||
customOptions.angularLinker = {
|
||||
shouldLink: true,
|
||||
jitMode: aot !== true,
|
||||
};
|
||||
shouldProcess = true;
|
||||
}
|
||||
|
||||
// Analyze for ES target processing
|
||||
const esTarget = scriptTarget as ScriptTarget | undefined;
|
||||
@ -109,10 +112,7 @@ export default custom<AngularCustomOptions>(() => {
|
||||
[
|
||||
require('./presets/application').default,
|
||||
{
|
||||
angularLinker: customOptions.shouldLink,
|
||||
forceES5: customOptions.forceES5,
|
||||
forceAsyncTransformation: customOptions.forceAsyncTransformation,
|
||||
i18n: customOptions.i18n,
|
||||
...customOptions,
|
||||
diagnosticReporter: (type, message) => {
|
||||
switch (type) {
|
||||
case 'error':
|
||||
|
@ -493,6 +493,7 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration {
|
||||
options: {
|
||||
cacheDirectory: findCachePath('babel-webpack'),
|
||||
scriptTarget: wco.scriptTarget,
|
||||
aot: buildOptions.aot,
|
||||
},
|
||||
},
|
||||
...buildOptimizerUseRule,
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { writeFile } from '../../../utils/fs';
|
||||
import { getActivePackageManager } from '../../../utils/packages';
|
||||
import { ng, silentYarn } from '../../../utils/process';
|
||||
import { updateJsonFile } from '../../../utils/project';
|
||||
import { getGlobalVariable } from '../../../utils/env';
|
||||
import { writeFile } from '../../../utils/fs';
|
||||
import { ng } from '../../../utils/process';
|
||||
import { updateJsonFile } from '../../../utils/project';
|
||||
|
||||
export default async function () {
|
||||
if ((getGlobalVariable('argv')['ve'])) {
|
||||
@ -13,8 +12,7 @@ export default async function () {
|
||||
await ng('generate', 'library', 'my-lib');
|
||||
|
||||
// Enable partial compilation mode (linker) for the library
|
||||
// Enable ivy for production as well (current schematic disables ivy in production)
|
||||
await updateJsonFile('projects/my-lib/tsconfig.lib.prod.json', config => {
|
||||
await updateJsonFile('projects/my-lib/tsconfig.lib.json', config => {
|
||||
const { angularCompilerOptions = {} } = config;
|
||||
angularCompilerOptions.enableIvy = true;
|
||||
angularCompilerOptions.compilationMode = 'partial';
|
||||
@ -51,7 +49,7 @@ export default async function () {
|
||||
template: '<lib-my-lib></lib-my-lib>'
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'app';
|
||||
title = 'test-project';
|
||||
|
||||
constructor(myLibService: MyLibService) {
|
||||
console.log(myLibService);
|
||||
@ -85,18 +83,23 @@ export default async function () {
|
||||
});
|
||||
`);
|
||||
|
||||
await runLibraryTests();
|
||||
await runLibraryTests(true);
|
||||
// Build library in partial mode (development)
|
||||
await ng('build', 'my-lib', '--configuration=development');
|
||||
|
||||
// AOT linking
|
||||
await runTests();
|
||||
|
||||
// JIT linking
|
||||
await updateJsonFile('angular.json', config => {
|
||||
const build = config.projects['test-project'].architect.build;
|
||||
build.options.aot = false;
|
||||
build.configurations.production.buildOptimizer = false;
|
||||
});
|
||||
|
||||
await runTests();
|
||||
}
|
||||
|
||||
async function runLibraryTests(prodMode = false): Promise<void> {
|
||||
const args = ['build', 'my-lib'];
|
||||
if (!prodMode) {
|
||||
args.push('--configuration=development');
|
||||
}
|
||||
|
||||
await ng(...args);
|
||||
|
||||
async function runTests(): Promise<void> {
|
||||
// Check that the tests succeeds both with named project, unnamed (should test app), and prod.
|
||||
await ng('e2e');
|
||||
await ng('e2e', 'test-project', '--devServerTarget=test-project:serve:production');
|
||||
|
Loading…
x
Reference in New Issue
Block a user