/
modify-config-helper.ts
156 lines (142 loc) · 5.43 KB
/
modify-config-helper.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import { green } from 'colorette';
import fs from 'fs';
import path from 'path';
import yeoman from 'yeoman-environment';
import Generator from 'yeoman-generator';
import { runTransform } from './scaffold';
import { utils } from 'webpack-cli';
const { logger, getPackageManager } = utils;
export interface Config extends Object {
item?: {
name: string;
};
topScope?: string[];
configName?: string;
merge: string | string[];
webpackOptions: object;
}
export interface TransformConfig extends Object {
configPath?: string;
configFile?: string;
config?: Config;
}
export interface WebpackScaffoldObject extends Object {
config: {
configName?: string;
topScope?: string[];
webpackOptions?: object;
};
usingDefaults?: boolean;
}
const DEFAULT_WEBPACK_CONFIG_FILENAME = 'webpack.config.js';
/**
*
* Looks up the webpack.config in the user's path and runs a given
* generator scaffold followed up by a transform
*
* @param {String} action — action to be done (add, remove, update, init)
* @param {Class} generator - Yeoman generator class
* @param {String} configFile - Name of the existing/default webpack configuration file
* @param {Array} packages - List of packages to resolve
* @returns {Function} runTransform - Returns a transformation instance
*/
export function modifyHelperUtil(
action: string,
generator: Generator.GeneratorConstructor,
configFile: string = DEFAULT_WEBPACK_CONFIG_FILENAME,
packages?: string[],
autoSetDefaults = false,
generateConfig = false,
): void {
const configPath: string | null = null;
const env = yeoman.createEnv('webpack', null);
const generatorName = 'webpack-init-generator';
if (!generator) {
generator = class extends Generator {
public initializing(): void {
packages.forEach(
(pkgPath: string): Generator => {
return this.composeWith(require.resolve(pkgPath), {});
},
);
}
};
}
// this is the default name that the yeoman generator uses when writing
// to .yo-rc.json
// see: https://github.com/yeoman/generator/blob/v4.5.0/lib/index.js#L773
let packageName = '*';
try {
const packagePath = path.resolve(process.cwd(), 'package.json');
if (fs.existsSync(packagePath)) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const packageData = require(packagePath);
if (packageData && packageData.name) {
packageName = packageData.name;
}
}
} catch (err) {
logger.error('\nYour package.json was incorrectly formatted.\n');
Error.stackTraceLimit = 0;
process.exitCode = 2;
}
env.registerStub(generator, generatorName);
env.run(
generatorName,
{
configFile,
autoSetDefaults,
},
() => {
let configModule: object;
let finalConfig: WebpackScaffoldObject = {
config: {},
};
try {
const confPath = path.resolve(process.cwd(), '.yo-rc.json');
configModule = require(confPath);
} catch (err) {
logger.error('\nCould not find a yeoman configuration file (.yo-rc.json).\n');
logger.error(
"\nPlease make sure to use 'this.config.set('configuration', this.configuration);' at the end of the generator.\n",
);
Error.stackTraceLimit = 0;
process.exitCode = 2;
}
try {
// the configuration stored in .yo-rc.json should already be in the correct
// WebpackScaffoldObject format
// it is labeled with the name property from the user's package.json, meaning
// we should simply access that value, rather than iterating through all
// the configs that are stored in .yo-rc.json
if (configModule[packageName] && configModule[packageName].configuration) {
finalConfig = configModule[packageName].configuration;
}
} catch (err) {
logger.error(err);
logger.error(`${err.stack}\n`);
logger.error('Your yeoman configuration file (.yo-rc.json) was incorrectly formatted. Deleting it may fix the problem.\n');
Error.stackTraceLimit = 0;
process.exitCode = 2;
}
try {
const transformConfig = Object.assign(
{
configFile: !configPath ? null : fs.readFileSync(configPath, 'utf8'),
configPath,
},
finalConfig,
) as TransformConfig;
if (finalConfig.usingDefaults && finalConfig.usingDefaults === true) {
const runCommand = getPackageManager() === 'yarn' ? 'yarn build' : 'npm run build';
logger.log(`\nYou can now run ${green(runCommand)} to bundle your application!\n`);
}
// scaffold webpack config file from using .yo-rc.json
return runTransform(transformConfig, 'init', generateConfig);
} catch (err) {
logger.error(err);
process.exitCode = 2;
}
},
);
}