liferay-npm-bundler-preset-reactjs
Version:
liferay npm bundler preset react
162 lines (161 loc) • 6.02 kB
JavaScript
;
/**
* SPDX-FileCopyrightText: © 2020 Liferay, Inc. <https://liferay.com>
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const clone_1 = __importDefault(require("clone"));
const path_1 = __importDefault(require("path"));
const file_path_1 = __importDefault(require("../file-path"));
const modules_1 = require("../modules");
/**
* Implements a restricted subset of webpack rules specification. The rules are
* specified as a top level field in `.npmbundlerrc`. Its supported structure
* is:
*
* rules := [<rule>]
* rule := {
* test: <test>,
* include: <include>,
* exclude: <exclude>,
* use: (<use> | [<use>])
* }
* test := (<regexp> | [<regexp>])
* include := (<regexp> | [<regexp>])
* exclude := (<regexp> | [<regexp>])
* regexp := STRING
* use := {STRING | <use_with_options>}
* use_with_options := {
* loader: STRING,
* options: OBJECT
* }
*
* See https://webpack.js.org/configuration/module/#modulerules for webpack's
* specification.
*/
class Rules {
constructor(project) {
this._project = project;
const { npmbundlerrc } = project;
this._config = npmbundlerrc['rules'] || [];
this._rules = clone_1.default(this._config);
this._normalizeRules();
this._versionsInfo = undefined;
}
/** Get raw rules config (useful for reports) */
get config() {
return this._config;
}
/**
* Get all available information about versions of loaders used for the
* build.
* @return a Map where keys are package names
*/
get versionsInfo() {
if (this._versionsInfo === undefined) {
const uses = this._rules.map((rule) => rule.use);
const descriptors = uses.reduce((array, use) => array.concat(use), []);
const resolvedModules = descriptors.map(({ resolvedModule }) => resolvedModule);
const { _project } = this;
this._versionsInfo = resolvedModules.reduce((map, resolvedModule) => {
const { modulePath, pkgName, scope } = modules_1.splitModuleName(resolvedModule);
const pkgJsonPath = _project.toolResolve(`${modules_1.joinModuleName(scope, pkgName, '')}/package.json`);
const pkgJson = require(pkgJsonPath);
map.set(resolvedModule, {
version: pkgJson.version,
path: path_1.default.relative(_project.dir.asNative, modulePath
? _project.toolResolve(resolvedModule)
: path_1.default.dirname(pkgJsonPath)),
});
return map;
}, new Map());
}
return this._versionsInfo;
}
/**
* Returns the associated rules for a given absolute file path.
* @param prjRelPath a native file path relative to `project.dir`
*/
loadersForFile(prjRelPath) {
const { _rules } = this;
const rules = _rules.filter((rule) => this._ruleApplies(rule, new file_path_1.default(prjRelPath)));
const loaders = rules.map((rule) => rule['use']);
// Flatten array
return [].concat(...loaders);
}
_instantiateLoader(use) {
const { _project } = this;
let moduleExports;
try {
use.resolvedModule = `liferay-npm-bundler-loader-${use.loader}`;
moduleExports = _project.toolRequire(use.resolvedModule);
}
catch (err) {
use.resolvedModule = use.loader;
moduleExports = _project.toolRequire(use.resolvedModule);
}
use.exec = moduleExports['default'] || moduleExports;
if (typeof use.exec !== 'function') {
throw new Error(`Loader '${use.resolvedModule}' is incorrect: ` +
`it does not export a function`);
}
use.metadata = moduleExports['metadata'] || {};
if (use.metadata.encoding === undefined) {
use.metadata.encoding = 'utf-8';
}
return use;
}
_normalizeRules() {
this._rules.forEach((rule) => {
this._normalizeArrayOfRegExp(rule, 'test', '.*');
this._normalizeArrayOfRegExp(rule, 'include', '.*');
this._normalizeArrayOfRegExp(rule, 'exclude', '(?!)');
if (!Array.isArray(rule['use'])) {
rule['use'] = [rule['use']];
}
rule['use'] = rule['use'].map((use) => {
if (typeof use === 'string') {
use = {
loader: use,
};
}
if (use.options === undefined) {
use.options = {};
}
use = this._instantiateLoader(use);
return use;
});
});
}
_normalizeArrayOfRegExp(rule, fieldName, defaultValue) {
if (rule[fieldName] === undefined) {
rule[fieldName] = [defaultValue];
}
else if (typeof rule[fieldName] === 'string') {
rule[fieldName] = [rule[fieldName]];
}
else if (!Array.isArray(rule[fieldName])) {
throw new Error(`Invalid rule ${fieldName}: ` + rule[fieldName]);
}
rule[fieldName] = rule[fieldName].map((test) => new RegExp(test));
}
_ruleApplies(rule, prjRelFile) {
const matched = rule.test.find((regexp) => regexp.test(prjRelFile.asPosix));
if (!matched) {
return false;
}
const included = rule.include.find((regexp) => regexp.test(prjRelFile.asPosix));
if (!included) {
return false;
}
const excluded = rule.exclude.find((regexp) => regexp.test(prjRelFile.asPosix));
if (excluded) {
return false;
}
return true;
}
}
exports.default = Rules;