Skip to content

Commit 31c856f

Browse files
committed
feat(interpret): use interpret
1 parent 215e233 commit 31c856f

File tree

7 files changed

+163
-124
lines changed

7 files changed

+163
-124
lines changed

lib/groups/config.js

Lines changed: 118 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,146 +1,171 @@
11
const { existsSync } = require('fs');
2-
const { resolve, extname, sep } = require('path');
2+
const { resolve, sep, dirname } = require('path');
3+
const { extensions } = require('interpret');
34

45
const GroupHelper = require('../utils/group-helper');
56

6-
const VALID_EXTENSIONS = ['.mjs', '.js', '.json', '.babel.js', '.ts'];
77
const DEFAULT_CONFIG_LOC = ['.webpack/webpack.config', '.webpack/webpack.config.dev', '.webpack/webpack.config.prod', '.webpack/webpackfile', 'webpack.config'];
88

99
const getDefaultConfigFiles = () => {
10-
return DEFAULT_CONFIG_LOC.map(filename =>
11-
VALID_EXTENSIONS.map(ext => ({
12-
path: resolve(filename + ext),
10+
return DEFAULT_CONFIG_LOC.map(filename => {
11+
return Object.keys(extensions).map(ext => {
12+
return {
13+
path: resolve(filename + ext),
14+
ext: ext,
15+
module: extensions[ext]
16+
}
17+
})
18+
}).reduce((a, i) => a.concat(i), []);
19+
}
20+
21+
const getConfigInfoFromFileName = (filename) => {
22+
const originalExt = filename.split('.').pop();
23+
return Object.keys(extensions).filter(ext => {
24+
return '.'.concat(originalExt) === ext;
25+
}).
26+
map(ext => {
27+
return {
28+
path: resolve(filename),
1329
ext: ext,
14-
})),
15-
).reduce((a, i) => a.concat(i), []);
30+
module: extensions[ext]
31+
}
32+
}).filter(e => existsSync(e.path));
1633
}
1734

1835
class ConfigGroup extends GroupHelper {
1936
constructor(options) {
2037
super(options);
2138
}
2239

23-
getConfigExtension(configPath) {
24-
for (let i = VALID_EXTENSIONS.length - 1; i >= 0; i--) {
25-
const tmpExt = VALID_EXTENSIONS[i];
26-
if (configPath.includes(tmpExt, configPath.length - tmpExt.length)) {
27-
return tmpExt;
28-
}
29-
}
30-
return extname(configPath);
31-
}
32-
mapConfigArg(config) {
33-
const { path } = config;
34-
const ext = this.getConfigExtension(path);
35-
return {
36-
path,
37-
ext,
38-
};
39-
}
40-
4140
require(path) {
4241
const result = require(path);
4342
if (result && result.__esModule && result.default) {
4443
return result.default;
4544
}
46-
return result;
45+
return {
46+
path: path,
47+
content: result
48+
};
4749
}
4850

49-
requireConfig(configPath) {
50-
const { register } = this.args;
51+
requireConfig(configModule) {
5152
return (() => {
52-
if (register && register.length) {
53-
module.paths.unshift(resolve(process.cwd(), 'node_modules'));
54-
register.forEach(dep => {
55-
const isRelative = ['./', '../', '.\\', '..\\'].some(start => dep.startsWith(start));
56-
if (isRelative) {
57-
require(resolve(process.cwd(), dep));
58-
} else {
59-
require(dep);
60-
}
61-
});
53+
try {
54+
if(!configModule.module) {
55+
return this.require(configModule.path);
56+
}
57+
} catch(err) {
58+
console.log(err);
6259
}
63-
return this.require(configPath);
6460
})();
6561
}
6662

67-
async resolveConfigFiles() {
68-
const { config, mode } = this.args;
69-
const path = require('path');
70-
71-
let configFiles;
72-
if (config) {
73-
//TODO: check for existence, give user feedback otherwise
74-
const configPath = path.resolve(process.cwd(), config);
75-
const ext = this.getConfigExtension(configPath);
76-
configFiles = {
77-
path: configPath,
78-
ext,
79-
};
80-
}
81-
if (!configFiles) {
82-
const defaultConfigFiles = getDefaultConfigFiles();
83-
const tmpConfigFiles = defaultConfigFiles
84-
.filter(file => {
85-
return existsSync(file.path);
86-
})
87-
.map(this.mapConfigArg.bind(this));
88-
if (tmpConfigFiles.length) {
89-
if (!config) {
90-
const defaultConfig = tmpConfigFiles.find(p => p.path.includes(mode));
91-
configFiles = defaultConfig || tmpConfigFiles[0];
92-
}
93-
}
94-
}
63+
async finalize(moduleObj) {
64+
let newOptionsObject = {
65+
outputOptions: {},
66+
options: {}
67+
};
9568

96-
let configOptions = [];
97-
if (configFiles) {
98-
// TODO: support mjs etc..
99-
const resolvedConfigurationFiles = this.requireConfig(configFiles.path);
100-
configOptions = resolvedConfigurationFiles;
101-
if (configOptions && configFiles.path.includes('.webpack')) {
102-
const currentPath = configFiles.path;
103-
const parentContext = path.dirname(currentPath).split(sep).slice(0, -1).join('/');
104-
if(Array.isArray(configOptions)) {
105-
configOptions.forEach(config => {
106-
config.context = config.context || parentContext;
107-
})
108-
} else {
109-
configOptions.context = configOptions.context || parentContext;
110-
}
111-
}
69+
if(!moduleObj) {
70+
return newOptionsObject;
11271
}
72+
const configPath = moduleObj.path;
73+
const configOptions = moduleObj.content;
11374
if (configOptions.length > 0) {
114-
this.opts['options'] = configOptions;
75+
newOptionsObject['options'] = configOptions;
11576
}
11677
else if (typeof configOptions === 'function') {
11778
const newOptions = await configOptions();
118-
this.opts['options'] = newOptions;
79+
newOptionsObject['options'] = newOptions;
11980
}
12081
else {
12182
if (Array.isArray(configOptions) && !configOptions.length) {
122-
this.opts['options'] = {};
83+
newOptionsObject['options'] = {};
84+
return newOptionsObject;
85+
}
86+
newOptionsObject['options'] = configOptions;
87+
}
88+
89+
if (configOptions && configPath.includes('.webpack')) {
90+
const currentPath = configPath;
91+
const parentContext = dirname(currentPath).split(sep).slice(0, -1).join('/');
92+
if(Array.isArray(configOptions)) {
93+
configOptions.forEach(config => {
94+
config.context = config.context || parentContext;
95+
})
96+
} else {
97+
configOptions.context = configOptions.context || parentContext;
98+
}
99+
newOptionsObject['options'] = configOptions;
100+
}
101+
return newOptionsObject;
102+
}
103+
104+
async resolveConfigFiles() {
105+
const { config, mode } = this.args;
106+
107+
if (config) {
108+
const configPath = resolve(process.cwd(), config);
109+
const configFiles = getConfigInfoFromFileName(configPath);
110+
if(!configFiles.length) {
111+
this.opts.processingMessageBuffer.push({
112+
lvl: 'warn',
113+
msg: `Configuration ${config} not found in ${configPath}`
114+
});
115+
return;
116+
}
117+
const foundConfig = configFiles[0];
118+
const resolvedConfig = this.requireConfig(foundConfig);
119+
this.opts = this.finalize(resolvedConfig);
120+
return;
121+
}
122+
123+
const defaultConfigFiles = getDefaultConfigFiles();
124+
const tmpConfigFiles = defaultConfigFiles
125+
.filter(file => {
126+
return existsSync(file.path);
127+
});
128+
129+
const configFiles = tmpConfigFiles.map(this.requireConfig.bind(this));
130+
if (configFiles.length) {
131+
const defaultConfig = configFiles.find(p => p.path.includes(mode));
132+
if(defaultConfig) {
133+
const envConfig = defaultConfig.map(c => c.content);
134+
this.opts = this.finalize(envConfig);
123135
return;
124136
}
125-
this.opts['options'] = configOptions;
137+
const foundConfig = configFiles.pop();
138+
this.opts = this.finalize(foundConfig);
139+
return;
126140
}
127141
}
128142

129-
resolveConfigMerging() {
143+
async resolveConfigMerging() {
130144
if (this.args.hasOwnProperty('merge')) {
131145
const { merge } = this.args;
132146

133147
const newConfigPath = this.resolveFilePath(merge, 'webpack.base.js');
134-
const newConfig = newConfigPath ? this.require(newConfigPath) : null;
135-
136-
const webpackMerge = require('webpack-merge');
137-
this.opts['options'] = webpackMerge(this.opts['options'], newConfig);
148+
if(newConfigPath) {
149+
const configFiles = getConfigInfoFromFileName(newConfigPath);
150+
if(!configFiles.length) {
151+
this.opts.processingMessageBuffer.push({
152+
lvl: 'warn',
153+
msg: 'Could not find file to merge configuration with...'
154+
})
155+
return;
156+
}
157+
const foundConfig = configFiles[0];
158+
const resolvedConfig = this.requireConfig(foundConfig);
159+
const newConfigurationsObject = await this.finalize(resolvedConfig);
160+
const webpackMerge = require('webpack-merge');
161+
this.opts['options'] = webpackMerge(this.opts['options'], newConfigurationsObject.options);
162+
}
138163
}
139164
}
140165

141166
async run() {
142167
await this.resolveConfigFiles();
143-
this.resolveConfigMerging();
168+
await this.resolveConfigMerging();
144169
return this.opts;
145170
}
146171
}

lib/utils/compiler.js

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -64,22 +64,22 @@ function showEmojiConditionally() {
6464
return (process.stdout.isTTY && process.platform === 'darwin')
6565
}
6666

67-
function generateOutput(outputOptions, stats, statsErrors) {
67+
function generateOutput(outputOptions, stats, statsErrors, processingMessageBuffer) {
6868
const statsObj = stats.toJson(outputOptions);
6969
if (statsObj.children && statsObj.children.length) {
7070
statsObj.children.forEach(child => {
71-
generateOutputForSingleCompilation(child, statsErrors);
71+
generateOutputForSingleCompilation(child, statsErrors, processingMessageBuffer);
7272
});
7373
return;
7474
}
75-
generateOutputForSingleCompilation(statsObj, statsErrors);
75+
generateOutputForSingleCompilation(statsObj, statsErrors, processingMessageBuffer);
7676
process.stdout.write('\n');
7777
if (outputOptions.watch) {
7878
process.cliLogger.info('watching files for updates...');
7979
}
8080
}
8181

82-
function generateOutputForSingleCompilation(statsObj, statsErrors) {
82+
function generateOutputForSingleCompilation(statsObj, statsErrors, processingMessageBuffer) {
8383
const { assets, entrypoints, time, builtAt, warnings, outputPath } = statsObj;
8484

8585
const visibleEmojies = showEmojiConditionally() ? ['✅', '🌏', '⚒️ ', '⏱ ', '📂'] : new Array(5).fill('');
@@ -118,8 +118,18 @@ function generateOutputForSingleCompilation(statsObj, statsErrors) {
118118
process.stdout.write(table.toString());
119119
}
120120

121+
if (processingMessageBuffer.length > 0) {
122+
processingMessageBuffer.forEach(buff => {
123+
if(buff.lvl === 'warn') {
124+
warnings.push(buff.msg);
125+
} else {
126+
statsErrors.push(buff.msg);
127+
}
128+
})
129+
}
130+
121131
warnings.forEach(warning => {
122-
process.stdout.write('\n');
132+
process.stdout.write('\n\n');
123133
process.cliLogger.warn(warning);
124134
});
125135

@@ -134,21 +144,21 @@ function generateOutputForSingleCompilation(statsObj, statsErrors) {
134144
}
135145
return statsObj;
136146
}
137-
async function invokeCompilerInstance(compiler, lastHash, options, outputOptions) {
147+
async function invokeCompilerInstance(compiler, lastHash, options, outputOptions, processingMessageBuffer) {
138148
return new Promise(async (resolve, reject) => {
139149
await compiler.run(function (err, stats) {
140-
const content = compilerCallback(compiler, err, stats, lastHash, options, outputOptions);
150+
const content = compilerCallback(compiler, err, stats, lastHash, options, outputOptions, processingMessageBuffer);
141151
resolve(content);
142152
});
143153
});
144154
}
145155

146-
async function invokeWatchInstance(compiler, lastHash, options, outputOptions, watchOptions) {
156+
async function invokeWatchInstance(compiler, lastHash, options, outputOptions, watchOptions, processingMessageBuffer) {
147157
return compiler.watch(watchOptions, function (err, stats) {
148-
return compilerCallback(compiler, err, stats, lastHash, options, outputOptions);
158+
return compilerCallback(compiler, err, stats, lastHash, options, outputOptions, processingMessageBuffer);
149159
});
150160
}
151-
function compilerCallback(compiler, err, stats, lastHash, options, outputOptions) {
161+
function compilerCallback(compiler, err, stats, lastHash, options, outputOptions, processingMessageBuffer) {
152162
let statsErrors = [];
153163
const stdout = options.silent
154164
? {
@@ -175,7 +185,7 @@ function compilerCallback(compiler, err, stats, lastHash, options, outputOptions
175185
statsErrors.push({ name: statErr.message, loc: errLoc });
176186
});
177187
}
178-
return generateOutput(outputOptions, stats, statsErrors);
188+
return generateOutput(outputOptions, stats, statsErrors, processingMessageBuffer);
179189
}
180190
if (!outputOptions.watch && stats.hasErrors()) {
181191
process.exitCode = 2;
@@ -187,11 +197,7 @@ function getCompiler(options) {
187197
}
188198

189199
async function webpackInstance(opts) {
190-
const { outputOptions, processingErrors, options } = opts;
191-
192-
if (processingErrors.length > 0) {
193-
throw new Error(processingErrors);
194-
}
200+
const { outputOptions, processingMessageBuffer, options } = opts;
195201

196202
const compiler = getCompiler(options);
197203
let lastHash = null;
@@ -203,7 +209,7 @@ async function webpackInstance(opts) {
203209

204210
if (outputOptions.interactive) {
205211
const interactive = require('./interactive');
206-
return interactive(options, outputOptions, processingErrors);
212+
return interactive(options, outputOptions, processingMessageBuffer);
207213
}
208214

209215
if (compiler.compilers) {
@@ -222,9 +228,9 @@ async function webpackInstance(opts) {
222228
});
223229
process.stdin.resume();
224230
}
225-
await invokeWatchInstance(compiler, lastHash, options, outputOptions, watchOptions);
231+
await invokeWatchInstance(compiler, lastHash, options, outputOptions, watchOptions, processingMessageBuffer);
226232
} else {
227-
return await invokeCompilerInstance(compiler, lastHash, options, outputOptions);
233+
return await invokeCompilerInstance(compiler, lastHash, options, outputOptions, processingMessageBuffer);
228234
}
229235
};
230236

lib/utils/group-helper.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class GroupHelper {
77
this.opts = {
88
outputOptions: {},
99
options: {},
10-
processingErrors: [],
10+
processingMessageBuffer: [],
1111
};
1212
}
1313

0 commit comments

Comments
 (0)