liferay-npm-bundler-preset-reactjs
Version:
liferay npm bundler preset react
199 lines (155 loc) • 5.13 kB
text/typescript
/**
* SPDX-FileCopyrightText: © 2020 Liferay, Inc. <https://liferay.com>
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
import path from 'path';
import FilePath from './file-path';
import project from './project';
enum FileOrigin {
SOURCE_PROJECT,
SOURCE_DEPENDENCY,
BUILD_PROJECT,
BUILD_DEPENDENCY,
}
const fileOriginCache: {[index: string]: FileOrigin} = {};
const packageDirCache: {[index: string]: FilePath} = {};
/**
* Get the full path of the package.json file for a given JS module file.
*
* @remarks
* This method assumes that you are inside the Babel transform phase of the
* bundler. Otherwise, the return path may be incorrect.
*
* @param moduleFilePath the module file path
* @return the full path to the package.json file (with native path
* separators)
*/
export function getPackageJsonPath(moduleFilePath: string): string {
return path.join(getPackageDir(moduleFilePath), 'package.json');
}
/**
* Get the full path of the package directory for a given JS module file.
*
* @remarks
* This method assumes that the module file lives in a liferay-npm-bundler
* project. Otherwise, the return path may be incorrect.
*
* @param moduleFilePath the module file path
* @return the full path to the package directory (with native path
* separators)
*/
export function getPackageDir(moduleFilePath: string): string {
const absModuleFilePosixPath = new FilePath(moduleFilePath).resolve()
.asPosix;
let absPkgDir: FilePath = packageDirCache[absModuleFilePosixPath];
if (absPkgDir) {
return absPkgDir.asNative;
}
switch (getFileOrigin(moduleFilePath)) {
case FileOrigin.SOURCE_DEPENDENCY: {
const absModuleFilePosixPath = new FilePath(
moduleFilePath
).resolve().asPosix;
const absNodeModulesPosixPath = project.dir.join('node_modules')
.asPosix;
const relModuleFilePosixPath = absModuleFilePosixPath.substring(
absNodeModulesPosixPath.length + 1
);
const modulePathParts = relModuleFilePosixPath.split('/');
const pkgDir = relModuleFilePosixPath.startsWith('@')
? `${modulePathParts[0]}/${modulePathParts[1]}`
: modulePathParts[0];
absPkgDir = project.dir.join('node_modules', pkgDir);
break;
}
case FileOrigin.BUILD_DEPENDENCY: {
const absModuleFilePosixPath = new FilePath(
moduleFilePath
).resolve().asPosix;
const absBuildNodeModulesPosixPath = project.dir.join(
project.buildDir,
'node_modules'
).asPosix;
const relBuildNodeModulesPosixPath = absModuleFilePosixPath.substring(
absBuildNodeModulesPosixPath.length + 1
);
const modulePathParts = relBuildNodeModulesPosixPath.split('/');
const pkgDir = modulePathParts[0];
absPkgDir = project.dir.join(
project.buildDir,
'node_modules',
pkgDir
);
break;
}
case FileOrigin.SOURCE_PROJECT: {
absPkgDir = project.dir;
break;
}
case FileOrigin.BUILD_PROJECT: {
absPkgDir = project.dir.join(project.buildDir);
break;
}
default:
break;
}
packageDirCache[absModuleFilePosixPath] = absPkgDir;
return absPkgDir.asNative;
}
/**
* Get the name of a module given its file path.
*
* @remarks
* This method assumes that the module file lives in a liferay-npm-bundler
* project. Otherwise, the return path may be incorrect.
*
* @param moduleFilePath the module file path
* @return the name of the module
*/
export function getModuleName(moduleFilePath: string): string {
const absModuleFilePosixPath = new FilePath(moduleFilePath).resolve()
.asPosix;
const absPkgPosixPath = new FilePath(getPackageDir(moduleFilePath)).asPosix;
let moduleName: string = absModuleFilePosixPath.substring(
absPkgPosixPath.length + 1
);
moduleName = moduleName.replace(/\.js$/i, '');
if (getFileOrigin(moduleFilePath) === FileOrigin.SOURCE_PROJECT) {
for (const source of project.sources) {
const prefix = source.asPosix.substr(2);
if (moduleName.startsWith(prefix)) {
moduleName = moduleName.substring(prefix.length + 1);
break;
}
}
}
const pkgJson = require(getPackageJsonPath(moduleFilePath));
return `${pkgJson.name}@${pkgJson.version}/${moduleName}`;
}
function getFileOrigin(filePath: string): FileOrigin {
const absModuleFilePosixPath = new FilePath(filePath).resolve().asPosix;
let fileOrigin: FileOrigin = fileOriginCache[absModuleFilePosixPath];
if (fileOrigin) {
return fileOrigin;
}
const absBuildNodeModulesPosixPath = project.dir.join(
project.buildDir,
'node_modules'
).asPosix;
const absBuildPosixPath = project.dir.join(project.buildDir).asPosix;
const absNodeModulesPosixPath = project.dir.join('node_modules').asPosix;
if (absModuleFilePosixPath.startsWith(absBuildNodeModulesPosixPath)) {
fileOrigin = FileOrigin.BUILD_DEPENDENCY;
}
else if (absModuleFilePosixPath.startsWith(absBuildPosixPath)) {
fileOrigin = FileOrigin.BUILD_PROJECT;
}
else if (absModuleFilePosixPath.startsWith(absNodeModulesPosixPath)) {
fileOrigin = FileOrigin.SOURCE_DEPENDENCY;
}
else {
fileOrigin = FileOrigin.SOURCE_PROJECT;
}
fileOriginCache[absModuleFilePosixPath] = fileOrigin;
return fileOrigin;
}