'use strict'; const path = require('path'); const assign = require('object-assign'); const fs = require('fs'); /** * @class * @param {Object} options * @param {String} options.path Path to theme folder, required param * @param {RegExp} [options.rule=/^@theme/] * @param {String} [options.env='THEME'] * @param {String} [options.defaultTheme='default'] * @param {String} [options.theme] * @constructor */ function WpjResolverPlugin(options) { this.options = assign( {}, { rule: /^@theme/, paths: {}, scss: false }, options ); this.options.moduleRule = new RegExp(this.options.rule.source + '\\[(.*)\\]'); } WpjResolverPlugin.prototype.apply = function(compiler) { const options = this.options; var target = compiler.ensureHook('internal-resolve'); var root = fs.realpathSync('.'); const resolve = (file, request, resolveContext, finalCallback) => { const obj = assign({}, request, { request: './' + file, path: root, relativePath: '.', }); // console.log('Resolving', request.request, file); compiler.doResolve(target, obj, `found file: ${file}`, resolveContext, function(...args) { return finalCallback(...args); }); }; const resolveFiles = (files, request, resolveContext, finalCallback) => { let resolved = false; files.some(file => { if ( (fs.existsSync(file) && fs.lstatSync(file).isFile()) || (fs.existsSync(file + '.scss') && fs.lstatSync(file + '.scss').isFile()) || (fs.existsSync(file + '.tsx') && fs.lstatSync(file + '.tsx').isFile()) || (fs.existsSync(file + '.ts') && fs.lstatSync(file + '.ts').isFile()) ) { resolved = true; resolve(file, request, resolveContext, finalCallback); return true; } }); if (!resolved) { return finalCallback(); } }; compiler.getHook('raw-resolve').tapAsync('WpjResolverPlugin', function(request, resolveContext, finalCallback) { if (!options.rule.test(request.request)) { return finalCallback(); } let attempts = assign({}, options.paths); let moduleMatch = request.request.match(options.moduleRule); if (moduleMatch) { attempts = {}; attempts[moduleMatch[1]] = options.paths[moduleMatch[1]]; } let files = []; Object.keys(attempts).forEach(name => { let prefix = attempts[name]; files.push(request.request.replace(moduleMatch ? options.moduleRule : options.rule, prefix)); if (options.scss) { let parts = path.parse(request.request); files.push( path.join(parts.dir.replace(moduleMatch ? options.moduleRule : options.rule, prefix), '_' + parts.base) ); } }); return resolveFiles(files, request, resolveContext, finalCallback); }); }; module.exports = WpjResolverPlugin;