Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(compiler-cli): expose the linker as a Babel plugin (#41918)
This allows the linker to be used as a true Babel plugin. In a Babel configuration file, include the linker as follows: ```js { plugins: [ '@angular/compiler-cli/linker/babel', ] } ``` or, if you need to specify configuration options: ```js { plugins: [ ['@angular/compiler-cli/linker/babel', {linkerJitMode: true}], ] } ``` PR Close #41918
- Loading branch information
Showing
3 changed files
with
99 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
import {ConfigAPI, PluginObj} from '@babel/core'; | ||
|
||
import {NodeJSFileSystem} from '../../../src/ngtsc/file_system'; | ||
import {ConsoleLogger, LogLevel} from '../../../src/ngtsc/logging'; | ||
import {LinkerOptions} from '../../src/file_linker/linker_options'; | ||
|
||
import {createEs2015LinkerPlugin} from './es2015_linker_plugin'; | ||
|
||
/** | ||
* This is the Babel plugin definition that is provided as a default export from the package, such | ||
* that the plugin can be used using the module specifier of the package. This is the recommended | ||
* way of integrating the Angular Linker into a build pipeline other than the Angular CLI. | ||
* | ||
* When the module specifier `@angular/compiler-cli/linker/babel` is used as a plugin in a Babel | ||
* configuration, Babel invokes this function (by means of the default export) to create the plugin | ||
* instance according to the provided options. | ||
* | ||
* The linker plugin that is created uses the native NodeJS filesystem APIs to interact with the | ||
* filesystem. Any logging output is printed to the console. | ||
* | ||
* @param api Provides access to the Babel environment that is configuring this plugin. | ||
* @param options The plugin options that have been configured. | ||
*/ | ||
export function defaultLinkerPlugin(api: ConfigAPI, options: Partial<LinkerOptions>): PluginObj { | ||
api.assertVersion(7); | ||
|
||
return createEs2015LinkerPlugin({ | ||
...options, | ||
fileSystem: new NodeJSFileSystem(), | ||
logger: new ConsoleLogger(LogLevel.info), | ||
}); | ||
} |
56 changes: 56 additions & 0 deletions
56
packages/compiler-cli/linker/babel/test/babel_plugin_spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
import {transformSync} from '@babel/core'; | ||
|
||
describe('default babel plugin entry-point', () => { | ||
it('should work as a Babel plugin using the module specifier', () => { | ||
const result = transformSync( | ||
` | ||
import * as i0 from "@angular/core"; | ||
export class MyMod {} | ||
export class MyComponent {} | ||
MyMod.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyMod, declarations: [MyComponent] }); | ||
`, | ||
{ | ||
plugins: [ | ||
'@angular/compiler-cli/linker/babel', | ||
], | ||
filename: 'test.js', | ||
})!; | ||
|
||
expect(result).not.toBeNull(); | ||
expect(result.code).not.toContain('ɵɵngDeclareNgModule'); | ||
expect(result.code).toContain('i0.ɵɵdefineNgModule'); | ||
expect(result.code).not.toMatch(/declarations:\s*\[MyComponent]/); | ||
}); | ||
|
||
it('should be configurable', () => { | ||
const result = transformSync( | ||
` | ||
import * as i0 from "@angular/core"; | ||
export class MyMod {} | ||
export class MyComponent {} | ||
MyMod.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyMod, declarations: [MyComponent] }); | ||
`, | ||
{ | ||
plugins: [ | ||
['@angular/compiler-cli/linker/babel', {linkerJitMode: true}], | ||
], | ||
filename: 'test.js', | ||
})!; | ||
|
||
expect(result).not.toBeNull(); | ||
expect(result.code).not.toContain('ɵɵngDeclareNgModule'); | ||
expect(result.code).toContain('i0.ɵɵdefineNgModule'); | ||
expect(result.code).toMatch(/declarations:\s*\[MyComponent]/); | ||
}); | ||
}); |