bit-bin
Version:
<a href="https://opensource.org/licenses/Apache-2.0"><img alt="apache" src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"></a> <a href="https://github.com/teambit/bit/blob/master/CONTRIBUTING.md"><img alt="prs" src="https://img.shields.io/b
467 lines (364 loc) • 17.5 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _bluebird() {
const data = require("bluebird");
_bluebird = function () {
return data;
};
return data;
}
function _defineProperty2() {
const data = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
_defineProperty2 = function () {
return data;
};
return data;
}
function path() {
const data = _interopRequireWildcard(require("path"));
path = function () {
return data;
};
return data;
}
function _constants() {
const data = require("../../../constants");
_constants = function () {
return data;
};
return data;
}
function _logger() {
const data = _interopRequireDefault(require("../../../logger/logger"));
_logger = function () {
return data;
};
return data;
}
function _links() {
const data = require("../../../links");
_links = function () {
return data;
};
return data;
}
function _utils() {
const data = require("../../../utils");
_utils = function () {
return data;
};
return data;
}
function _path2() {
const data = require("../../../utils/path");
_path2 = function () {
return data;
};
return data;
}
function _source() {
const data = _interopRequireDefault(require("../../../scope/models/source"));
_source = function () {
return data;
};
return data;
}
function _dataToPersist() {
const data = _interopRequireDefault(require("./data-to-persist"));
_dataToPersist = function () {
return data;
};
return data;
}
function _manipulateDir() {
const data = require("../../component-ops/manipulate-dir");
_manipulateDir = function () {
return data;
};
return data;
}
/**
* Dist paths are by default saved into the component's root-dir/dist. However, when dist is set in bit.json, the paths
* are in the consumer-root/dist.target dir. If dist.entry is set, the dist.entry part is stripped from the dists paths.
* (according to some additional conditions. See shouldDistEntryBeStripped()).
* If there is originallySharedDir and the component is IMPORTED, it is stripped as well.
*
* These modifications of the paths are taken care in different stages depends on the scenario.
* 1) using 'bit build'.
* First, the sharedOriginallyDir is stripped (happens in consumer-component.build()). There are two scenarios here:
* a) the component wasn't change since the last build. It loads the dists from the model and strip the
* sharedOriginallyDir. (see the !needToRebuild case of build()).
* b) the component was changed. It re-builds it. The dists path are cloned from the files, since the files are
* sharedOriginallyDir stripped (because they loaded from the filesystem), so will be the dists files.
* Next, the dist.entry is stripped. This is done when the dists are written into the file-system, (see writeDists()).
*
* 2) using 'bit import'.
* When converting the component from model to consumer-component, the sharedOriginallyDir is stripped. (see
* stripOriginallySharedDir() ).
* Then, Before writing the dists to the file-system, the dist-entry is taken care of. (see writeDists() ).
*
* 3) using 'bit link'.
* When linking authored components, we generate an index file from node_modules/component-name to the main dist file.
* It might happen during the import, when updateDistsPerWorkspaceConfig() was running already, and it might happen
* during the 'bit link' command. Therefore, before linking, the updateDistsPerWorkspaceConfig() is running while making
* sure it doesn't run twice.
* (see node-modules-linker.linkToMainFile() and calculateMainDistFileForAuthored()).
*
* The opposite action is taken when a component is tagged. We load the component from the file-system while the dist
* paths might be stripped from consumer dist.entry and originallySharedDir.
* Then, before writing them to the model, we first add the originallySharedDir and then the dist.entry. We make sure
* there were stripped before adding them. (See this.toDistFilesModel() function and the comment there)
*/
class Dists {
// changed only when importing a component
// populated only after getDistDirForConsumer() is called
constructor(dists, mainDistFile) {
(0, _defineProperty2().default)(this, "dists", void 0);
(0, _defineProperty2().default)(this, "writeDistsFiles", true);
(0, _defineProperty2().default)(this, "areDistsInsideComponentDir", true);
(0, _defineProperty2().default)(this, "distEntryShouldBeStripped", false);
(0, _defineProperty2().default)(this, "_mainDistFile", void 0);
(0, _defineProperty2().default)(this, "distsRootDir", void 0);
this._mainDistFile = mainDistFile;
this.dists = dists || []; // cover also case of null (when it comes from the model)
}
isEmpty() {
return !this.dists.length;
}
get() {
return this.dists;
}
getAsReadable() {
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
return this.dists.map(file => file.toReadableString());
}
getMainDistFile() {
return this._mainDistFile;
}
/**
* When dists are written by a consumer (as opposed to isolated-environment for example), the dist-entry and
* dist-target are taken into account for calculating the path.
* By default, the dists path is inside the component. If dist attribute is populated in bit.json, the path is
* relative to consumer root.
*/
getDistDirForConsumer(consumer, componentRootDir) {
if (consumer.shouldDistsBeInsideTheComponent()) {
this.distsRootDir = path().join(componentRootDir, _constants().DEFAULT_DIST_DIRNAME);
} else {
this.areDistsInsideComponentDir = false;
this.distsRootDir = Dists.getDistDirWhenDistIsOutsideCompDir(consumer.config, componentRootDir);
}
return this.distsRootDir;
}
hasFileParallelToSrcFile(srcFile) {
const distFile = (0, _utils().searchFilesIgnoreExt)(this.dists, path().normalize(srcFile));
return Boolean(distFile);
}
static getDistDirWhenDistIsOutsideCompDir(workspaceConfig, componentRootDir) {
if (workspaceConfig._distEntry) componentRootDir = componentRootDir.replace(workspaceConfig._distEntry, '');
const distTarget = workspaceConfig._distTarget || _constants().DEFAULT_DIST_DIRNAME;
return path().join(distTarget, componentRootDir);
}
getDistDir(consumer, componentRootDir) {
if (consumer) return this.getDistDirForConsumer(consumer, componentRootDir);
this.distsRootDir = path().join(componentRootDir, _constants().DEFAULT_DIST_DIRNAME);
return this.distsRootDir;
}
updateDistsPerWorkspaceConfig(id, consumer, componentMap) {
if (this.isEmpty()) return;
const newDistBase = this.getDistDir(consumer, componentMap.getRootDir());
this.dists.forEach(dist => dist.updatePaths({
newBase: newDistBase
}));
if (consumer) this.stripDistEntryIfNeeded(id, consumer, componentMap);
}
stripDistEntryIfNeeded(id, consumer, componentMap) {
const distEntry = consumer.config._distEntry;
if (!distEntry) return;
const shouldDistEntryBeStripped = () => {
if (this.distEntryShouldBeStripped) return false; // it has been already stripped, don't strip twice!
if (!distEntry || componentMap.origin === _constants().COMPONENT_ORIGINS.NESTED) return false;
const areAllDistsStartWithDistEntry = () => {
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
return this.dists.map(dist => dist.relative.startsWith(distEntry)).every(x => x);
};
if (componentMap.origin === _constants().COMPONENT_ORIGINS.AUTHORED) {
return areAllDistsStartWithDistEntry();
} // it's IMPORTED. We first check that rootDir starts with dist.entry, it happens mostly when a user imports into
// a specific directory (e.g. bit import --path src/). Then, we make sure all dists files start with that
// dist.entry. In a case when originallySharedDir is the same as dist.entry, this second check returns false.
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
return componentMap.rootDir.startsWith(distEntry) && areAllDistsStartWithDistEntry();
};
const distEntryShouldBeStripped = shouldDistEntryBeStripped();
if (!distEntryShouldBeStripped) return;
_logger().default.debug(`stripping dist.entry "${distEntry}" from ${id.toString()}`);
this.distEntryShouldBeStripped = true; // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
this.dists.forEach(dist => dist.updatePaths({
newRelative: dist.relative.replace(distEntry, '')
}));
if (this._mainDistFile) {
this._mainDistFile.replace(distEntry, '');
}
}
stripOriginallySharedDir(originallySharedDir) {
this.dists.forEach(distFile => {
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
const newRelative = (0, _manipulateDir().stripSharedDirFromPath)(distFile.relative, originallySharedDir);
distFile.updatePaths({
newRelative
});
});
this._mainDistFile = this._mainDistFile ? (0, _manipulateDir().stripSharedDirFromPath)(this._mainDistFile, originallySharedDir) : this._mainDistFile;
}
/**
* write dists files to the filesystem
*/
writeDists(component, consumer, // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
writeLinks = true) {
var _this = this;
return (0, _bluebird().coroutine)(function* () {
const dataToPersist = yield _this.getDistsToWrite(component, consumer.bitMap, consumer, writeLinks);
if (!dataToPersist) return null;
if (consumer) dataToPersist.addBasePath(consumer.getPath());
yield dataToPersist.persistAllToFS(); // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
return _this.dists.map(distFile => distFile.path);
})();
}
/**
* write dist link files to the filesystem
*/
writeDistsLinks(component, consumer) {
var _this2 = this;
return (0, _bluebird().coroutine)(function* () {
if (_this2.isEmpty() || !_this2.writeDistsFiles) return;
const componentMap = consumer ? consumer.bitMap.getComponent(component.id, {
ignoreVersion: true
}) : component.componentMap;
if (!componentMap) throw new Error('writeDistsLinks expect componentMap to be defined');
if (componentMap.origin === _constants().COMPONENT_ORIGINS.NESTED) return;
const dataToPersist = yield (0, _links().getLinksInDistToWrite)(component, componentMap, consumer, consumer.bitMap);
dataToPersist.addBasePath(consumer.getPath());
yield dataToPersist.persistAllToFS();
})();
}
/**
* In case there is a consumer and dist.entry should be stripped, it will be done before writing the files.
* The originallySharedDir should be already stripped before accessing this method.
*/
getDistsToWrite(component, bitMap, consumer, // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
writeLinks = true, componentWithDependencies) {
var _this3 = this;
return (0, _bluebird().coroutine)(function* () {
if (_this3.isEmpty() || !_this3.writeDistsFiles) return null;
const dataToPersist = new (_dataToPersist().default)();
const componentMap = consumer ? consumer.bitMap.getComponent(component.id, {
ignoreVersion: true
}) : component.componentMap;
if (!componentMap) throw new Error('getDistsToWrite expect componentMap to be defined');
_this3.updateDistsPerWorkspaceConfig(component.id, consumer, componentMap);
dataToPersist.addManyFiles(_this3.dists);
if (writeLinks && componentMap && componentMap.origin === _constants().COMPONENT_ORIGINS.IMPORTED) {
const linksInDist = yield (0, _links().getLinksInDistToWrite)(component, componentMap, consumer, bitMap, componentWithDependencies);
dataToPersist.merge(linksInDist);
}
return dataToPersist;
})();
} // In case there are dist files, we want to point the index to the main dist file, not to source.
// This important since when you require a module without specify file, it will give you the file specified under this key
// (or index.js if key not exists)
calculateMainDistFile(mainSourceFile) {
if (this.writeDistsFiles && this.areDistsInsideComponentDir) {
const getMainFile = () => {
if (this._mainDistFile) return this._mainDistFile; // Take the only dist file if there is only one or search for one with the same name as the main source file
if (this.dists && this.dists.length === 1) return this.dists[0].relative; // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
return (0, _utils().searchFilesIgnoreExt)(this.dists, mainSourceFile, 'relative');
};
const mainFile = getMainFile();
if (mainFile) return path().join(_constants().DEFAULT_DIST_DIRNAME, mainFile);
}
return this._mainDistFile || mainSourceFile;
}
/**
* authored components have the dists outside the components dir and they don't have rootDir.
* it returns the file or dist file relative to consumer-root.
*/
calculateDistFileForAuthored(componentFile, consumer, isMain) {
if (this.isEmpty()) return componentFile;
const getFileToSearch = () => {
if (!consumer.config._distEntry) return componentFile;
const distEntryNormalized = path().normalize(consumer.config._distEntry);
return componentFile.replace(`${distEntryNormalized}${path().sep}`, '');
};
const fileToSearch = getFileToSearch(); // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
const distFile = isMain && this._mainDistFile ? this._mainDistFile : (0, _utils().searchFilesIgnoreExt)(this.dists, fileToSearch, 'relative');
if (!distFile) return componentFile;
const distTarget = consumer.config._distTarget || _constants().DEFAULT_DIST_DIRNAME;
return path().join(distTarget, distFile);
}
toDistFilesModel(consumer, originallySharedDir, isCompileSet) {
// when a component is written to the filesystem, the originallySharedDir may be stripped, if it was, the
// originallySharedDir is written in bit.map, and then set in consumerComponent.originallySharedDir when loaded.
// similarly, when the dists are written to the filesystem, the dist.entry may be stripped, if it was, the
// consumerComponent.dists.distEntryShouldBeStripped is set to true.
// because the model always has the paths of the original author, in case part of the path was stripped, add it
// back before saving to the model. this way, when the author updates the components, the paths will be correct.
const addSharedDirAndDistEntry = pathStr => {
const withSharedDir = originallySharedDir ? path().join(originallySharedDir, pathStr) : pathStr;
const withDistEntry = this.distEntryShouldBeStripped ? path().join(consumer.config._distEntry, withSharedDir) : withSharedDir;
return (0, _path2().pathNormalizeToLinux)(withDistEntry);
};
if (this.isEmpty() || !isCompileSet) return {};
const dists = this.get().map(dist => {
return {
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
name: dist.basename,
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
relativePath: addSharedDirAndDistEntry(dist.relative),
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
file: _source().default.from(dist.contents),
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
test: dist.test
};
});
const mainDistFile = this._mainDistFile ? addSharedDirAndDistEntry(this._mainDistFile) : this._mainDistFile; // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
return {
dists,
mainDistFile
};
}
/**
* the formula is distTarget + (customModuleDir - distEntry).
* e.g. distTarget = 'dist', customDir = 'src', distEntry = 'src'.
* node_path will be 'dist' + 'src' - 'src' = 'dist'.
* another example, distTarget = 'dist', customDir = 'src/custom', distEntry = 'src'. result: "dist/custom"
*/
static getNodePathDir(consumer) {
const resolveModules = consumer.config._resolveModules;
if (!resolveModules || !resolveModules.modulesDirectories || !resolveModules.modulesDirectories.length) return undefined;
const distTarget = consumer.config._distTarget || _constants().DEFAULT_DIST_DIRNAME;
const distEntry = consumer.config._distEntry;
const nodePaths = resolveModules.modulesDirectories.map(moduleDir => {
const isRelative = str => str.startsWith('./') || str.startsWith('../');
if (!distEntry) return path().join(distTarget, moduleDir);
const distEntryRelativeToModuleDir = (0, _utils().pathRelativeLinux)(distEntry, moduleDir);
if (isRelative(distEntryRelativeToModuleDir)) {
// moduleDir is outside the distEntry, ignore the distEntry
return path().join(distTarget, moduleDir);
}
return path().join(distTarget, distEntryRelativeToModuleDir);
});
return nodePaths.map(nodePath => consumer.toAbsolutePath(nodePath)).map(_path2().pathNormalizeToLinux).join(_constants().NODE_PATH_SEPARATOR);
}
clone() {
const clone = Object.assign(Object.create(Object.getPrototypeOf(this)), this);
clone.dists = this.dists.map(d => d.clone());
return clone;
}
}
exports.default = Dists;