-
-
Notifications
You must be signed in to change notification settings - Fork 80
/
Copy pathindex.ts
123 lines (104 loc) · 4.06 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
import * as webpackMerge from 'webpack-merge';
import * as path from 'path';
import * as fs from 'fs';
import { findUp } from '@angular/cli/utilities/find-up';
export default (config, options) => {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
const libraryName = getLibraryName(options);
const singleSpaConfig = {
output: {
library: libraryName,
libraryTarget: (options && options.customWebpackConfig && options.customWebpackConfig.libraryTarget) || 'umd',
jsonpFunction: 'webpackJsonp' + libraryName,
},
externals: {
'zone.js': 'Zone',
},
devServer: {
historyApiFallback: false,
contentBase: path.resolve(process.cwd(), 'src'),
headers: {
'Access-Control-Allow-Headers': '*',
},
},
module: {
rules: [
{
parser: {
system: false
}
}
]
}
};
// @ts-ignore
const mergedConfig: any = webpackMerge.smart(config, singleSpaConfig);
if (mergedConfig.output.libraryTarget === 'system') {
// Don't used named exports when exporting in System.register format.
delete mergedConfig.output.library;
}
// eslint-disable-next-line @typescript-eslint/no-use-before-define
removePluginByName(mergedConfig.plugins, 'IndexHtmlWebpackPlugin');
// eslint-disable-next-line @typescript-eslint/no-use-before-define
removeMiniCssExtract(mergedConfig);
if (Array.isArray(mergedConfig.entry.styles)) {
// We want the global styles to be part of the "main" entry. The order of strings in this array
// matters -- only the last item in the array will have its exports become the exports for the entire
// webpack bundle
mergedConfig.entry.main = [...mergedConfig.entry.styles, ...mergedConfig.entry.main];
}
// Remove bundles
delete mergedConfig.entry.polyfills;
delete mergedConfig.entry.styles;
delete mergedConfig.optimization.runtimeChunk;
delete mergedConfig.optimization.splitChunks;
return mergedConfig;
};
function removePluginByName(plugins, name) {
const pluginIndex = plugins.findIndex(plugin => plugin.constructor.name === name);
if (pluginIndex > -1) {
plugins.splice(pluginIndex, 1);
}
}
function removeMiniCssExtract(config) {
removePluginByName(config.plugins, 'MiniCssExtractPlugin');
config.module.rules.forEach(rule => {
if (rule.use) {
const cssMiniExtractIndex = rule.use.findIndex(use => typeof use === 'string' && use.includes('mini-css-extract-plugin'));
if (cssMiniExtractIndex >= 0) {
rule.use[cssMiniExtractIndex] = {loader: 'style-loader'};
}
}
});
}
function getLibraryName(options: any) {
if (options && options.customWebpackConfig && options.customWebpackConfig.libraryName) {
return options.customWebpackConfig.libraryName;
}
// eslint-disable-next-line @typescript-eslint/no-use-before-define
const projectName = getProjectNameFromAngularJson();
if (projectName) return projectName;
console.warn(
'Warning: single-spa-angular could not determine a library name to use and has used a default value.',
);
console.info('This may cause issues if this app uses code-splitting or lazy loading.');
if (!options) {
console.info('You may also need to update extra-webpack.config.json.');
}
console.info(
'See <https://single-spa.js.org/docs/ecosystem-angular/#use-custom-webpack> for information on how to resolve this.',
);
return 'angular_single_spa_project';
}
function getProjectNameFromAngularJson(): string | null {
const angularJsonPath = findUp(['angular.json', '.angular.json'], process.cwd());
if (!angularJsonPath) return null;
const angularJson = JSON.parse(fs.readFileSync(angularJsonPath, 'utf8'));
if (!angularJson.projects) return null;
const projects = Object.keys(angularJson.projects);
// if there is exactly one project in the workspace, then that must be this one.
if (projects.length === 1) return projects[0];
// If we reach here there are multiple (or zero) projects in angular.json
// we cannot tell which one to use, so we will end up using the default.
return null;
}