Skip to content

Commit

Permalink
improvement(init) - generate package.json with type:module on bit init (
Browse files Browse the repository at this point in the history
  • Loading branch information
GiladShoham authored Feb 26, 2024
1 parent f94de83 commit d4cc879
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 21 deletions.
4 changes: 2 additions & 2 deletions e2e/commands/init.e2e.1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ describe('run bit init', function () {
});
describe('bit init', () => {
before(() => {
helper.scopeHelper.initWorkspace();
helper.scopeHelper.initWorkspace(undefined, { 'no-package-json': true });
});
it('should not change BitMap file', () => {
const currentBitMap = helper.bitMap.read();
Expand All @@ -175,7 +175,7 @@ describe('run bit init', function () {
describe('bit init --reset', () => {
before(() => {
helper.scopeHelper.getClonedLocalScope(localScope);
helper.command.runCmd('bit init --reset');
helper.command.runCmd('bit init --reset --no-package-json');
});
it('should not change BitMap file', () => {
const currentBitMap = helper.bitMap.read();
Expand Down
2 changes: 1 addition & 1 deletion scopes/generator/generator/workspace-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export class WorkspaceGenerator {
try {
process.chdir(this.workspacePath);
await this.initGit();
await init(this.workspacePath, this.options.skipGit, false, false, false, false, false, false, {});
await init(this.workspacePath, this.options.skipGit, false, false, false, false, false, false, false, {});
await this.writeWorkspaceFiles();
await this.reloadBitInWorkspaceDir();
// Setting the workspace to be in install context to prevent errors during the workspace generation
Expand Down
5 changes: 3 additions & 2 deletions src/api/consumer/lib/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import ObjectsWithoutConsumer from './exceptions/objects-without-consumer';
export default async function init(
absPath: string = process.cwd(),
noGit = false,
noPackageJson = false,
reset = false,
resetNew = false,
resetLaneNew = false,
Expand All @@ -23,7 +24,7 @@ export default async function init(
}
let consumer: Consumer | undefined;
try {
consumer = await Consumer.create(absPath, noGit, workspaceConfigProps);
consumer = await Consumer.create(absPath, noGit, noPackageJson, workspaceConfigProps);
} catch (err) {
// it's possible that at this stage the consumer fails to load due to scope issues.
// still we want to load it to include its instance of "scope.json", so then later when "consumer.write()", we
Expand All @@ -34,7 +35,7 @@ export default async function init(
if (!scopePath) throw new Error(`fatal: scope not found in the path: ${process.cwd()}`);
await Scope.reset(scopePath, true);
}
if (!consumer) consumer = await Consumer.create(absPath, noGit, workspaceConfigProps);
if (!consumer) consumer = await Consumer.create(absPath, noGit, noPackageJson, workspaceConfigProps);
if (!force && !resetScope) {
await throwForOutOfSyncScope(consumer);
}
Expand Down
4 changes: 3 additions & 1 deletion src/cli/commands/public-cmds/init-cmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export default class Init implements LegacyCommand {
'standalone',
'do not nest component store within .git directory and do not write config data inside package.json',
],
['', 'no-package-json', 'do not generate package.json'],
['r', 'reset', 'write missing or damaged Bit files'],
['', 'reset-new', 'reset .bitmap file as if the components were newly added and remove all model data (objects)'],
[
Expand All @@ -59,7 +60,6 @@ export default class Init implements LegacyCommand {
['', 'default-scope <default-scope>', 'set the default scope for components in the workspace'],
['p', 'package-manager <package-manager>', 'set the package manager (npm or yarn) to be used in the workspace'],
['f', 'force', 'force workspace initialization without clearing local objects'],
['', 'harmony', 'DEPRECATED. no need for this flag. Harmony is the default now'],
['I', 'interactive', 'EXPERIMENTAL. start an interactive process'],
] as CommandOptions;

Expand All @@ -72,6 +72,7 @@ export default class Init implements LegacyCommand {
bare,
shared,
standalone,
noPackageJson,
reset,
resetNew,
resetLaneNew,
Expand Down Expand Up @@ -105,6 +106,7 @@ export default class Init implements LegacyCommand {
return init(
path,
standalone,
noPackageJson,
reset,
resetNew,
resetLaneNew,
Expand Down
22 changes: 20 additions & 2 deletions src/consumer/component/package-json-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ export default class PackageJsonFile {
* load from the given dir, if not exist, don't throw an error, just set packageJsonObject as an
* empty object
*/
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
static async load(workspaceDir: PathOsBasedAbsolute, componentDir?: PathRelative = '.'): Promise<PackageJsonFile> {
static async load(workspaceDir: PathOsBasedAbsolute, componentDir: PathRelative = '.'): Promise<PackageJsonFile> {
const filePath = composePath(componentDir);
const filePathAbsolute = path.join(workspaceDir, filePath);
const packageJsonStr = await PackageJsonFile.getPackageJsonStrIfExist(filePathAbsolute);
Expand All @@ -75,6 +74,25 @@ export default class PackageJsonFile {
return new PackageJsonFile({ filePath, packageJsonObject, fileExist: true, workspaceDir, indent, newline });
}

static create(
workspaceDir: PathOsBasedAbsolute,
componentDir: PathRelative = '.',
content: Record<string, any>,
indent = ' ',
newline = '\n'
): PackageJsonFile {
const filePath = composePath(componentDir);

return new PackageJsonFile({
filePath,
packageJsonObject: content,
fileExist: false,
workspaceDir,
indent,
newline,
});
}

static async reset(workspaceDir: PathOsBasedAbsolute) {
const pkgJsonFile = await PackageJsonFile.load(workspaceDir);
if (pkgJsonFile.fileExist) {
Expand Down
51 changes: 44 additions & 7 deletions src/consumer/consumer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fs from 'fs-extra';
import * as path from 'path';
import R from 'ramda';
import { compact } from 'lodash';
import { compact, isEmpty } from 'lodash';
import { ComponentID, ComponentIdList } from '@teambit/component-id';
import { DEFAULT_LANE, LaneId } from '@teambit/lane-id';
import { BitIdStr } from '@teambit/legacy-bit-id';
Expand Down Expand Up @@ -73,7 +73,7 @@ export default class Consumer {
_componentsStatusCache: Record<string, any> = {}; // cache loaded components
packageManagerArgs: string[] = []; // args entered by the user in the command line after '--'
componentLoader: ComponentLoader;
packageJson: any;
packageJson: PackageJsonFile;
public onCacheClear: Array<() => void | Promise<void>> = [];
constructor({
projectPath,
Expand All @@ -98,6 +98,10 @@ export default class Consumer {
this.bitMap = await BitMap.load(this);
}

setPackageJson(packageJson: PackageJsonFile) {
this.packageJson = packageJson;
}

// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
get dirStructure(): DirStructure {
if (!this._dirStructure) {
Expand Down Expand Up @@ -183,6 +187,7 @@ export default class Consumer {
await Promise.all([this.config.write({ workspaceDir: this.projectPath }), this.scope.ensureDir()]);
this.bitMap.markAsChanged();
await this.writeBitMap();
await this.writePackageJson();
return this;
}

Expand Down Expand Up @@ -424,9 +429,10 @@ export default class Consumer {
static create(
projectPath: PathOsBasedAbsolute,
noGit = false,
noPackageJson = false,
workspaceConfigProps?: WorkspaceConfigProps
): Promise<Consumer> {
return this.ensure(projectPath, noGit, workspaceConfigProps);
return this.ensure(projectPath, noGit, noPackageJson, workspaceConfigProps);
}

static _getScopePath(projectPath: PathOsBasedAbsolute, noGit: boolean): PathOsBasedAbsolute {
Expand All @@ -441,6 +447,7 @@ export default class Consumer {
static async ensure(
projectPath: PathOsBasedAbsolute,
standAlone = false,
noPackageJson = false,
workspaceConfigProps?: WorkspaceConfigProps
): Promise<Consumer> {
const resolvedScopePath = Consumer._getScopePath(projectPath, standAlone);
Expand All @@ -458,16 +465,40 @@ export default class Consumer {
existingGitHooks,
});
await consumer.setBitMap();
// understands why tests break with gilad and david.
// await Consumer.ensurePackageJson(projectPath);
if (!noPackageJson) {
consumer.setPackageJsonWithTypeModule();
}
return consumer;
}

private setPackageJsonWithTypeModule() {
const exists = this.packageJson && this.packageJson.fileExist;
if (exists) {
const content = this.packageJson.packageJsonObject;
if (content.type === 'module') return;
logger.console(
'\nEnable ESM by adding "type":"module" to the package.json file (https://nodejs.org/api/esm.html#enabling). If you are looking to use CJS. Use the Bit CJS environments.'
);
return;
}
const jsonContent = { type: 'module' };
const packageJson = PackageJsonFile.create(this.projectPath, undefined, jsonContent);
this.setPackageJson(packageJson);
}

static async ensurePackageJson(projectPath: string) {
const packageJsonPath = path.join(projectPath, 'package.json');
const exists = fs.existsSync(packageJsonPath);
if (exists) return;
fs.writeFileSync(packageJsonPath, `{\n "type": "module" \n}`);
if (exists) {
const content = await fs.readJson(packageJsonPath);
if (content.type === 'module') return;
logger.console(
'\nEnable ESM by adding "type":"module" to the package.json file (https://nodejs.org/api/esm.html#enabling). If you are looking to use CJS. Use the Bit CJS environments.'
);
return;
}
const jsonContent = { type: 'module' };
fs.writeJSONSync(packageJsonPath, jsonContent, { spaces: 2 });
}

/**
Expand Down Expand Up @@ -605,6 +636,12 @@ export default class Consumer {
await this.bitMap.write();
}

async writePackageJson() {
if (!isEmpty(this.packageJson.packageJsonObject)) {
await this.packageJson.write();
}
}

getBitmapHistoryDir(): PathOsBasedAbsolute {
return path.join(this.scope.path, BITMAP_HISTORY_DIR_NAME);
}
Expand Down
14 changes: 9 additions & 5 deletions src/e2e-helper/e2e-scope-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type SetupWorkspaceOpts = {
disableMissingManuallyConfiguredPackagesIssue?: boolean; // default to true. otherwise, it'll always show missing babel/jest from react-env
registry?: string;
initGit?: boolean;
generatePackageJson?: boolean;
yarnRCConfig?: any;
npmrcConfig?: any;
};
Expand Down Expand Up @@ -84,7 +85,8 @@ export default class ScopeHelper {
reInitLocalScope(opts?: SetupWorkspaceOpts) {
this.cleanLocalScope();
if (opts?.initGit) this.command.runCmd('git init');
this.initWorkspace();
const initWsOpts = opts?.generatePackageJson ? undefined : { 'no-package-json': true };
this.initWorkspace(undefined, initWsOpts);

if (opts?.addRemoteScopeAsDefaultScope ?? true) this.workspaceJsonc.addDefaultScope();
if (opts?.disablePreview ?? true) this.workspaceJsonc.disablePreview();
Expand Down Expand Up @@ -122,8 +124,9 @@ export default class ScopeHelper {
this.command.new(templateName, flags, this.scopes.local, this.scopes.e2eDir);
}

initWorkspace(workspacePath?: string) {
return this.command.runCmd(`bit init`, workspacePath);
initWorkspace(workspacePath?: string, options?: Record<string, any>) {
const opts = this.command.parseOptions(options);
return this.command.runCmd(`bit init ${opts}`, workspacePath);
}

async initInteractive(inputs: InteractiveInputs) {
Expand All @@ -143,13 +146,14 @@ export default class ScopeHelper {
this.addRemoteScope();
}

initNewLocalScope(deleteCurrentScope = true) {
initNewLocalScope(deleteCurrentScope = true, generatePackageJson = false) {
if (deleteCurrentScope) {
fs.removeSync(this.scopes.localPath);
}
this.scopes.setLocalScope();
fs.ensureDirSync(this.scopes.localPath);
return this.initWorkspace();
const initWsOpts = generatePackageJson ? undefined : { 'no-package-json': true };
return this.initWorkspace(undefined, initWsOpts);
}
addRemoteScope(
remoteScopePath: string = this.scopes.remotePath,
Expand Down
2 changes: 1 addition & 1 deletion src/interactive/commands/init-interactive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export default (async function initInteractive() {
actualCompiler = undefined;
}
answers.compiler = actualCompiler;
return init(undefined, false, false, false, false, false, false, false, answers).then(
return init(undefined, false, false, false, false, false, false, false, false, answers).then(
({ created, addedGitHooks, existingGitHooks }) => {
return {
created,
Expand Down

0 comments on commit d4cc879

Please sign in to comment.