Skip to content

Commit

Permalink
Improve preview entries (#8691)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jinjiang committed May 15, 2024
1 parent da760a5 commit 90228d3
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 27 deletions.
87 changes: 64 additions & 23 deletions scopes/preview/preview/generate-link.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { toWindowsCompatiblePath } from '@teambit/toolbox.path.to-windows-compatible-path';
import camelcase from 'camelcase';
import type { ComponentMap } from '@teambit/component';
import { join } from 'path';
import { outputFileSync } from 'fs-extra';
import objectHash from 'object-hash';
import camelcase from 'camelcase';
import { toWindowsCompatiblePath } from '@teambit/toolbox.path.to-windows-compatible-path';
import { getPreviewDistDir } from './mk-temp-dir';

const previewDistDir = getPreviewDistDir();

export type MainModulesMap = {
/**
Expand All @@ -10,56 +16,71 @@ export type MainModulesMap = {
[envId: string]: string;
};

type ModuleLink = {
envId: string;
varName: string;
resolveFrom: string;
};

type ComponentLink = {
componentIdentifier: string;
modules: {
varName: string;
resolveFrom: string;
}[];
};

// :TODO refactor to building an AST and generate source code based on it.
export function generateLink(
prefix: string,
componentMap: ComponentMap<string[]>,
mainModulesMap?: MainModulesMap,
isSplitComponentBundle = false
isSplitComponentBundle = false,
tempPackageDir?: string
): string {
const links = componentMap.toArray().map(([component, modulePath], compIdx) => ({
const componentLinks: ComponentLink[] = componentMap.toArray().map(([component, modulePath], compIdx) => ({
componentIdentifier: component.id.fullName,
modules: modulePath.map((path, pathIdx) => ({
varName: moduleVarName(compIdx, pathIdx),
resolveFrom: toWindowsCompatiblePath(path),
})),
}));

let modulesLinks;
if (mainModulesMap) {
modulesLinks = Object.entries(mainModulesMap).map(([envId, path]) => {
const resolveFrom = toWindowsCompatiblePath(path);
const varName = getEnvVarName(envId);
return { envId, varName, resolveFrom };
});
}
const moduleLinks: ModuleLink[] = Object.entries(mainModulesMap || {}).map(([envId, path]) => {
const resolveFrom = toWindowsCompatiblePath(path);
const varName = getEnvVarName(envId);
return { envId, varName, resolveFrom };
});

return `
import { linkModules } from '@teambit/preview/dist/preview.preview.runtime.js';
const contents = `
import { linkModules } from '${previewDistDir}/preview.preview.runtime.js';
${links
.map((link) => link.modules.map((module) => `import * as ${module.varName} from "${module.resolveFrom}";`).join('\n'))
.filter((line) => line !== '') // prevent empty lines
.join('\n')}
${getModuleImports(moduleLinks, tempPackageDir)}
${modulesLinks.map((module) => `import * as ${module.varName} from "${module.resolveFrom}";`).join('\n')}
${getComponentImports(componentLinks)}
linkModules('${prefix}', {
modulesMap: {
${modulesLinks
${moduleLinks
// must include all components, including empty
.map((module) => `"${module.envId}": ${module.varName}`)
.map((moduleLink) => `"${moduleLink.envId}": ${moduleLink.varName}`)
.join(',\n ')}
},
isSplitComponentBundle: ${isSplitComponentBundle},
componentMap: {
${links
${componentLinks
// must include all components, including empty
.map((link) => ` "${link.componentIdentifier}": [${link.modules.map((module) => module.varName).join(', ')}]`)
.map(
(componentLink) =>
` "${componentLink.componentIdentifier}": [${componentLink.modules
.map((module) => module.varName)
.join(', ')}]`
)
.join(',\n')}
}
});
`;
return contents;
}

function moduleVarName(componentIdx: number, fileIdx: number) {
Expand All @@ -71,3 +92,23 @@ function getEnvVarName(envId: string) {
const varName = `${envNameFormatted}MainModule`;
return varName;
}

function getModuleImports(moduleLinks: ModuleLink[] = [], tempPackageDir?: string): string {
const hash = objectHash(moduleLinks);
const tempFileName = `preview-modules-${hash}.mjs`;
const tempFilePath = join(tempPackageDir || previewDistDir, tempFileName);
const tempFileContents = moduleLinks
.map((module) => `export * as ${module.varName} from "${module.resolveFrom}";`)
.join('\n');
outputFileSync(tempFilePath, tempFileContents);
return `import {${moduleLinks.map((moduleLink) => moduleLink.varName).join(', ')}} from "${tempFilePath}";`;
}

function getComponentImports(componentLinks: ComponentLink[] = []): string {
return componentLinks
.map((link) =>
link.modules.map((module) => `import * as ${module.varName} from "${module.resolveFrom}";`).join('\n')
)
.filter((line) => line !== '') // prevent empty lines
.join('\n');
}
11 changes: 10 additions & 1 deletion scopes/preview/preview/mk-temp-dir.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import { mkdtempSync } from 'fs-extra';
import { tmpdir } from 'os';
import { sep } from 'path';
import { sep, join } from 'path';
import { getAspectDirFromBvm } from '@teambit/aspect-loader';

export function makeTempDir(prefix = '') {
return mkdtempSync(`${tmpdir()}${sep}${prefix}`);
}

export function getPreviewDistDir(): string {
try {
return join(getAspectDirFromBvm('@teambit/preview'), 'dist');
} catch (err) {
return __dirname;
}
}
5 changes: 4 additions & 1 deletion scopes/preview/preview/pre-bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import { promisify } from 'util';
import { PreviewAspect } from './preview.aspect';
import { createWebpackConfig } from './webpack/webpack.config';
import { clearConsole } from './pre-bundle-utils';
import { getPreviewDistDir } from './mk-temp-dir';

const previewDistDir = getPreviewDistDir();

export const RUNTIME_NAME = 'preview';
export const PUBLIC_DIR = join('public', 'bit-preview');
Expand Down Expand Up @@ -131,7 +134,7 @@ export async function generateBundlePreviewEntry(rootAspectId: string, previewPr
config['teambit.harmony/bit'] = rootAspectId;

const contents = [imports, `run(${JSON.stringify(config, null, 2)});`].join('\n');
const previewRuntime = resolve(join(__dirname, `preview.entry.${sha1(contents)}.js`));
const previewRuntime = resolve(join(previewDistDir, `preview.entry.${sha1(contents)}.js`));

if (!existsSync(previewRuntime)) {
outputFileSync(previewRuntime, contents);
Expand Down
16 changes: 14 additions & 2 deletions scopes/preview/preview/preview.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { CACHE_ROOT } from '@teambit/legacy/dist/constants';
import { BitError } from '@teambit/bit-error';
import objectHash from 'object-hash';
import { uniq } from 'lodash';
import { writeFileSync, existsSync, mkdirSync } from 'fs-extra';
import { writeFileSync, existsSync, mkdirSync, ensureDirSync, writeJSONSync } from 'fs-extra';
import { join } from 'path';
import { PkgAspect, PkgMain } from '@teambit/pkg';
import { AspectLoaderAspect, getAspectDir, getAspectDirFromBvm } from '@teambit/aspect-loader';
Expand Down Expand Up @@ -639,6 +639,17 @@ export class PreviewMain {
private writeHash = new Map<string, string>();
private timestamp = Date.now();

private ensureTempPackage() {
const workspacePath = this.workspace?.path;
const tempPackageDir = workspacePath ? join(workspacePath, 'node_modules', '@teambit', '_local') : '';
if (tempPackageDir) {
ensureDirSync(tempPackageDir);
writeJSONSync(join(tempPackageDir, 'package.json'), { name: '@teambit/_local' });
writeFileSync(join(tempPackageDir, 'index.js'), 'module.exports = {};');
return tempPackageDir;
}
}

/**
* write a link to load custom modules dynamically.
* @param prefix write
Expand All @@ -653,7 +664,8 @@ export class PreviewMain {
dirName: string,
isSplitComponentBundle: boolean
) {
const contents = generateLink(prefix, moduleMap, mainModulesMap, isSplitComponentBundle);
const tempPackageDir = this.ensureTempPackage();
const contents = generateLink(prefix, moduleMap, mainModulesMap, isSplitComponentBundle, tempPackageDir);
return this.writeLinkContents(contents, dirName, prefix);
}

Expand Down

0 comments on commit 90228d3

Please sign in to comment.