/**
* @file exports/resolve.js
* @copyright @spmhome @_2025
* @author Scott Meesseman @spmeesseman
*
* @see {@link https://webpack.js.org/configuration/resolve webpack.js.org/resolve}
*
*//** */
// const { ProvidePlugin } = require("webpack");
const WpwWebpackExport = require("./base");
/**
* @augments WpwWebpackExport
*/
class WpwResolveExport extends WpwWebpackExport
{
/**
* @private
*/
static polyfills = {
buffer: "buffer", console: "console-browserify", constants: "constants-browserify", crypto: "crypto-browserify",
events: "events", http: "http-browserify", https: "https-browserify", os: "os-browserify", path: "path-browserify",
querystring: "querystring", stream: "stream-browserify", tty: "tty-browserify", url: "url-browserify", util: "util",
vm: "vm-browserify", zlib: "zlib-browserify"
};
/**
* @param {WpwExportOptions} options Plugin options to be applied
*/
constructor(options)
{
super(options);
this.buildOptions = /** @type {WpwBuildOptionsExportConfig<"resolve">} */(this.buildOptions);
}
/**
* @override
* @param {WpwBuild} b
*/
static create = (b) => WpwResolveExport.wrap.call(this, b, b.isAnyAppOrLib || b.isTypes || b.isResource || b.isTests);
/**
* @override
* @param {WpwBuild} build
*/
app(build)
{
this.applyPolyfills(build);
build.wpc.resolve.mainFields = build.isModule ? [ "exports", "module", "main" ] : [ "exports", "main", "module" ];
if (!build.isWeb) {
// if (build.pkgJson.exports) {
// build.wpc.resolveLoader.conditionNames = [ "node", "types", "require", "import", "default" ];
// }
// build.wpc.resolveLoader.exportsFields = [ "exports" ];
// build.wpc.resolve.importsFields = [ ".", "node", "nodejs", "import", "require", "types", "default" ];
}
else {
// if (build.pkgJson.exports) {
// build.wpc.resolve.conditionNames = [ "browser", "web" ];
// }
/// build.wpc.resolveLoader.exportsFields = [ "browser", "types", "require", "import", "default" ];
// build.wpc.resolve.mainFields = build.isModule ? [ "browser", "module", "main" ] : [ "browser", "main", "module" ]
build.wpc.resolve.mainFields.unshift("browser");
}
}
/**
* @param {WpwBuild} build
*/
applyPolyfills(build)
{
const poly = Object.entries(this.buildOptions.polyfill || {});
build.wpc.resolve.fallback = build.isWeb ? { fs: false } : (poly.length > 0 ? {} : undefined);
if (poly.length > 0)
{ poly.filter(([ _, p ]) => this._types_.isString(p, true))
.map(([ m, p ]) => ([ m, build.getBasePath({ path: p }) ]))
.filter(([ _, p ]) => this._fs_.existsSync(p))
.forEach(([ m, p ]) => { build.wpc.resolve.fallback[m] = p; });
poly.filter(([ m, b ]) => this._types_.isBoolean(b) && WpwResolveExport.polyfills[m])
.forEach(([ m ]) => { build.wpc.resolve.fallback[m] = WpwResolveExport.polyfills[m]; });
// this._obj_.apply(build.wpc.resolve.fallback,
// { fs: !web,
// util: cfgPoly.util === true ? require.resolve("util") : false,
// vm: cfgPoly.vm === true ? require.resolve("vm-browserify") : false,
// tty: cfgPoly.tty === true ? require.resolve("tty-browserify") : false,
// url: cfgPoly.url === true ? require.resolve("url-browserify") : false,
// path: cfgPoly.path === true ? require.resolve("path-browserify") : false,
// http: cfgPoly.http === true ? require.resolve("http-browserify") : false,
// zlib: cfgPoly.zlib === true ? require.resolve("zlib-browserify") : false,
// os: cfgPoly.os === true ? require.resolve("os-browserify") : false,
// events: cfgPoly.events === true ? require.resolve("events") : false,
// https: cfgPoly.https === true ? require.resolve("https-browserify") : false,s
// crypto: cfgPoly.crypto === true ? require.resolve("crypto-browserify") : false,
// stream: cfgPoly.stream === true ? require.resolve("stream-browserify") : false,
// console: cfgPoly.console === true ? require.resolve("console-browserify") : false,
// querystring: cfgPoly.querystring === true ? require.resolve("querystring") : false,
// constants: cfgPoly.constants === true ? require.resolve("constants-browserify") : false,
// buffer: cfgPoly.buffer === true || cfgPoly.crypto === true ? require.resolve("buffer") : false
// // vm: cfgPoly.vm === true || cfgPoly.buffer === true ? require.resolve("vm-browserify") : false,
// });
Object.entries(build.wpc.resolve.fallback).forEach(([ p, r ]) => { build.wpc.resolve.alias[p] = r; });
if (this._types_.isObjectEmpty(build.wpc.resolve.fallback)) {
this._obj_.cleanPrototype(build.wpc.resolve, "fallback");
}
// build.wpc.plugins.push(new ProvidePlugin({ process: "process/browser", Buffer: [ "buffer", "Buffer" ] }));s
}
}
/**
* @override
* @param {WpwBuild} build
*/
base(build)
{
const joinPath = this._path_.joinPath,
modules = [ "node_modules", ...build.nodeModulesPaths.all ];
build.logger.write("initialize webpack 'resolve' configuration", 1);
build.logger.value(" node_modules path", build.nodeModulesPaths.base, 1);
build.logger.value(" context node_modules path", build.nodeModulesPaths.ctx, 2);
build.logger.value(" global node_modules path", build.nodeModulesPaths.global, 2);
build.logger.value(" wpw node_modules path", build.nodeModulesPaths.wpw, 2);
this._obj_.apply(this.build.wpc, /** @type {Partial<WpwWebpackConfig>} */(
{ resolve:
{ modules: [ ...modules, this._path_.resolvePath(build.nodeModulesPaths.wpw, "..") ],
extensions: [ ".js", ".cjs", ".mjs" ],
cache: !!((build.options.cache?.type === "filesystem") && (build.options.cache?.resolver))
},
resolveLoader:
{ modules: [
!this.global.isDevExec ? joinPath(build.wpwPath, "loaders") : joinPath(build.wpwPath, "src", "loaders"),
...modules, this._path_.resolvePath(build.nodeModulesPaths.wpw, "..")
]
}
}));
if (build.isTranspiled)
{ const compilerOptions = build.tsc.compilerOptions;
if (build.isTs || build.isTsJs || build.isJsTs)
{ build.wpc.resolve.extensions.unshift(".ts", ".tsx");
build.wpc.resolve.extensionAlias = {
".js": [ ".js", ".ts" ], ".cjs": [ ".cjs",".cts" ], ".mjs": [ ".mjs",".mts" ]
};
}
build.wpc.resolve.alias = this.resolveAliasPaths(build, build.nodeModulesPaths.base);
if (compilerOptions.jsx) {
this._arr_.pushUniq2(build.wpc.resolve.extensions, this.global.isWin32, ".jsx");
}
if (compilerOptions.resolveJsonModule) {
this._arr_.pushUniq2(build.wpc.resolve.extensions, this.global.isWin32, ".json");
}
}
}
/**
* @override
*/
doxygen() {}
/**
* @override
*/
extjsdoc() {}
/**
* @override
* @param {WpwBuild} _build
*/
jsdoc(_build) {}
/**
* @override
* @param {WpwBuild} build
*/
lib(build) { this.app(build); }
/**
* @override
* @param {WpwBuild} build
*/
plugin(build) { this.app(build); }
/**
* @private
* @param {WpwBuild} build
* @param {string} modulesPath
* @returns {WpwWebpackAliasConfig}
*/
resolveAliasPaths(build, modulesPath)
{
const tsConfig = build.tsconfig,
existsSync = this._fs_.existsSync,
tscfgSrcDir = build.source.info.dir,
resolvePath = this._path_.resolvePath,
tscfgPaths = tsConfig.compilerOptions.paths;
/** @type {WpwWebpackAliasConfig} */
const alias = {
"append-transform": resolvePath(modulesPath, "append-transform/index.js"),
// "fsevents": resolvePath(this.nodeModulesPath, "fsevents/index.js")
"./module-types": resolvePath("../../@babel/core/lib/config/files/module-types.js")
// "@babel/preset-env": resolvePath(build.nodeModulesPaths.wpw, "@babel/preset-env/lib/index.js/"),
// "@babel/preset-module": resolvePath(build.nodeModulesPaths.wpw, "@babel/preset-module/lib/index.js/"),
// "@babel/preset-typescript": resolvePath(build.nodeModulesPaths.wpw, "@babel/preset-typescript/lib/index.js/")
};
if (tscfgSrcDir && tscfgPaths)
{
Object.entries(tscfgPaths).filter(([ _, p ]) => this._types_.isArray(p)).forEach(([ key, p ]) =>
{ alias[key.replace(/[/\\]\*+$/, "")] = p.map(
(p) => resolvePath(tscfgSrcDir, p).replace(/[/\\]\*+$/, "")).filter((p) => existsSync(p)
);
});
}
return alias;
}
/**
* @override
* @param {WpwBuild} _build
*/
schema(_build) {}
/**
* @override
* @param {WpwBuild} _build
*/
script(_build) {}
/**
* @override
* @param {WpwBuild} build
*/
resource(build) { this._arr_.pushUniq(/** @type {string[]} */(build.wpc.resolve.extensions), ".json"); }
/**
* @override
* @param {WpwBuild} build
*/
tests(build)
{
const spmTestUtilsPath = this._path_.resolvePath(build.getBasePath(), "node_modules/@spmhome/test-utils/node_modules");
this.applyPolyfills(build);
if (this._fs_.existsSync(spmTestUtilsPath)) {
build.wpc.resolve.modules.unshift(spmTestUtilsPath);
}
}
/**
* @override
* @param {WpwBuild} build
*/
types(build)
{
this.applyPolyfills(build);
this._arr_.pushUniq2(build.wpc.resolve.extensions, this.global.isWin32, ".d.ts", ".ts");
}
/**
* @override
* @param {WpwBuild} build
*/
webapp(build)
{
this.applyPolyfills(build);
this._arr_.pushUniq2(build.wpc.resolve.extensions, this.global.isWin32, ".scss", ".woff", ".woff2");
}
};
module.exports = WpwResolveExport.create;