-
Notifications
You must be signed in to change notification settings - Fork 82
/
Copy pathindex.ts
133 lines (112 loc) · 3.94 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import {
BrowserBuilder,
NormalizedBrowserBuilderSchema
} from '@angular-devkit/build-angular';
import { Path, virtualFs } from '@angular-devkit/core';
import * as fs from 'fs';
import { Observable } from 'rxjs';
import { BuilderConfiguration, BuildEvent } from '@angular-devkit/architect';
import { tap } from 'rxjs/operators';
interface PluginBuilderSchema extends NormalizedBrowserBuilderSchema {
/**
* A string of the form `path/to/file#exportName` that acts as a path to include to bundle
*/
modulePath: string;
/**
* A name of compiled bundle
*/
pluginName: string;
/**
* A comma-delimited list of shared lib names used by current plugin
*/
sharedLibs: string;
}
export default class PluginBuilder extends BrowserBuilder {
private options: PluginBuilderSchema;
private entryPointPath: string;
patchEntryPoint(contents: string) {
fs.writeFileSync(this.entryPointPath, contents);
}
buildWebpackConfig(
root: Path,
projectRoot: Path,
host: virtualFs.Host<fs.Stats>,
options: PluginBuilderSchema
) {
const { pluginName, sharedLibs } = this.options;
if (!this.options.modulePath) {
throw Error('Please define modulePath!');
}
if (!pluginName) {
throw Error('Please provide pluginName!');
}
const config = super.buildWebpackConfig(root, projectRoot, host, options);
// Make sure we are producing a single bundle
delete config.entry.polyfills;
delete config.optimization.runtimeChunk;
delete config.optimization.splitChunks;
delete config.entry.styles;
config.externals = {
rxjs: 'rxjs',
'@angular/core': 'ng.core',
'@angular/common': 'ng.common',
'@angular/forms': 'ng.forms',
'@angular/router': 'ng.router',
tslib: 'tslib'
// put here other common dependencies
};
if (sharedLibs) {
config.externals = [config.externals];
const sharedLibsArr = sharedLibs.split(',');
sharedLibsArr.forEach(sharedLibName => {
const factoryRegexp = new RegExp(`${sharedLibName}.ngfactory$`);
config.externals[0][sharedLibName] = sharedLibName; // define external for code
config.externals.push((context, request, callback) => {
if (factoryRegexp.test(request)) {
return callback(null, sharedLibName); // define external for factory
}
callback();
});
});
}
const ngCompilerPluginInstance = config.plugins.find(
x => x.constructor && x.constructor.name === 'AngularCompilerPlugin'
);
if (ngCompilerPluginInstance) {
ngCompilerPluginInstance._entryModule = this.options.modulePath;
}
// preserve path to entry point
// so that we can clear use it within `run` method to clear that file
this.entryPointPath = config.entry.main[0];
const [modulePath, moduleName] = this.options.modulePath.split('#');
const factoryPath = `${
modulePath.includes('.') ? modulePath : `${modulePath}/${modulePath}`
}.ngfactory`;
const entryPointContents = `
export * from '${modulePath}';
export * from '${factoryPath}';
import { ${moduleName}NgFactory } from '${factoryPath}';
export default ${moduleName}NgFactory;
`;
this.patchEntryPoint(entryPointContents);
config.output.filename = `${pluginName}.js`;
config.output.library = pluginName;
config.output.libraryTarget = 'umd';
// workaround to support bundle on nodejs
config.output.globalObject = `(typeof self !== 'undefined' ? self : this)`;
return config;
}
run(
builderConfig: BuilderConfiguration<PluginBuilderSchema>
): Observable<BuildEvent> {
this.options = builderConfig.options;
// I don't want to write it in my scripts every time so I keep it here
builderConfig.options.deleteOutputPath = false;
return super.run(builderConfig).pipe(
tap(() => {
// clear entry point so our main.ts is always empty
this.patchEntryPoint('');
})
);
}
}