feat: dynamic imports

This commit is contained in:
Eduardo Speroni
2021-11-20 18:25:27 -03:00
parent eb219b1ee8
commit 9b4e4c0e7d
3 changed files with 55 additions and 20 deletions

View File

@@ -8,6 +8,7 @@ import path from 'path';
import fs from 'fs';
import { parseEnvFlags } from '../cli/parseEnvFlags';
import { tryRequireThenImport } from '../helpers/dynamicImports';
const defaultConfig = path.resolve(
__dirname,
@@ -47,7 +48,7 @@ program
.option('--config [path]', 'config path')
.option('--watch', 'watch for changes')
.allowUnknownOption()
.action((options, command) => {
.action(async (options, command) => {
const env = parseEnvFlags(command.args);
// add --env <val> into the env object
// for example if we use --env prod
@@ -75,7 +76,7 @@ program
// todo: guard against invalid config
let configuration: webpack.Configuration;
try {
configuration = require(configPath)(env);
configuration = await (await tryRequireThenImport(configPath))(env);
} catch (err) {
console.log(err);
}

View File

@@ -0,0 +1,36 @@
export function dynamicImportLoaderFactory() {
let importESM;
try {
importESM = new Function('id', 'return import(id);');
} catch (e) {
importESM = null;
}
return importESM;
}
export async function tryRequireThenImport(module: string) {
let result;
try {
result = require(module);
} catch (error) {
const dynamicImportLoader = dynamicImportLoaderFactory();
if (error.code === 'ERR_REQUIRE_ESM' && dynamicImportLoader) {
result = await dynamicImportLoader(module);
result = result.default;
return result;
}
throw error;
}
// For babel/typescript
if (result && typeof result === 'object' && 'default' in result) {
result = result.default || {};
}
return result || {};
}

View File

@@ -170,28 +170,26 @@ export async function resolveChainableConfig(): Promise<Config> {
// todo: allow opt-out
await applyExternalConfigs();
webpackChains
.splice(0)
.sort((a, b) => {
return a.order - b.order;
})
.forEach(({ chainFn, plugin }) => {
try {
chainFn(config, env);
} catch (err) {
if (plugin) {
// catch and print errors from plugins
return error(`
for (const { chainFn, plugin } of webpackChains.splice(0).sort((a, b) => {
return a.order - b.order;
})) {
try {
await chainFn(config, env);
} catch (err) {
if (plugin) {
// catch and print errors from plugins
error(`
Unable to apply chain function from: ${plugin}.
Error is: ${err}
`);
}
// otherwise throw - as the error is likely from the user config
// or missing env flags (eg. missing platform)
throw err;
continue;
}
});
// otherwise throw - as the error is likely from the user config
// or missing env flags (eg. missing platform)
throw err;
}
}
if (env.verbose) {
info('Resolved chainable config (before merges):');