@teambit/preview 1.0.465 → 1.0.467

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@teambit/preview",
3
- "version": "1.0.465",
3
+ "version": "1.0.467",
4
4
  "homepage": "https://bit.cloud/teambit/preview/preview",
5
5
  "main": "dist/index.js",
6
6
  "componentId": {
7
7
  "scope": "teambit.preview",
8
8
  "name": "preview",
9
- "version": "1.0.465"
9
+ "version": "1.0.467"
10
10
  },
11
11
  "dependencies": {
12
12
  "mime": "2.5.2",
@@ -16,9 +16,11 @@
16
16
  "camelcase": "6.2.0",
17
17
  "normalize-path": "3.0.0",
18
18
  "object-hash": "2.1.1",
19
+ "chalk": "2.4.2",
20
+ "pad-right": "0.2.2",
19
21
  "webpack": "5.84.1",
20
22
  "graphql-tag": "2.12.1",
21
- "chalk": "2.4.2",
23
+ "filenamify": "4.2.0",
22
24
  "lodash.compact": "3.0.1",
23
25
  "graphql-request": "6.1.0",
24
26
  "webpack-manifest-plugin": "5.0.0",
@@ -29,35 +31,35 @@
29
31
  "@teambit/bit-error": "0.0.404",
30
32
  "@teambit/preview.cli.dev-server-events-listener": "0.0.1",
31
33
  "@teambit/react.webpack.react-webpack": "1.0.37",
32
- "@teambit/express": "0.0.1141",
33
- "@teambit/logger": "0.0.1135",
34
+ "@teambit/express": "0.0.1143",
35
+ "@teambit/logger": "0.0.1137",
34
36
  "@teambit/ui-foundation.ui.pages.static-error": "0.0.105",
35
- "@teambit/builder": "1.0.465",
36
- "@teambit/bundler": "1.0.465",
37
- "@teambit/component": "1.0.465",
37
+ "@teambit/builder": "1.0.467",
38
+ "@teambit/bundler": "1.0.467",
39
+ "@teambit/component": "1.0.467",
38
40
  "@teambit/preview.ui.component-preview": "1.0.16",
39
- "@teambit/aspect-loader": "1.0.465",
40
- "@teambit/cli": "0.0.1042",
41
- "@teambit/dependency-resolver": "1.0.465",
42
- "@teambit/envs": "1.0.465",
41
+ "@teambit/aspect-loader": "1.0.467",
42
+ "@teambit/cli": "0.0.1044",
43
+ "@teambit/dependency-resolver": "1.0.467",
44
+ "@teambit/envs": "1.0.467",
43
45
  "@teambit/toolbox.path.to-windows-compatible-path": "0.0.496",
44
46
  "@teambit/toolbox.crypto.sha1": "0.0.2",
45
- "@teambit/ui": "1.0.465",
46
- "@teambit/isolator": "1.0.465",
47
+ "@teambit/ui": "1.0.467",
48
+ "@teambit/isolator": "1.0.467",
47
49
  "@teambit/harmony.modules.harmony-root-generator": "0.0.7",
48
50
  "@teambit/component.sources": "0.0.44",
49
51
  "@teambit/toolbox.path.path": "0.0.4",
50
- "@teambit/cache": "0.0.1135",
51
- "@teambit/graphql": "1.0.465",
52
+ "@teambit/cache": "0.0.1137",
53
+ "@teambit/graphql": "1.0.467",
52
54
  "@teambit/harmony.modules.feature-toggle": "0.0.6",
53
- "@teambit/pkg": "1.0.465",
54
- "@teambit/pubsub": "1.0.465",
55
- "@teambit/scope": "1.0.465",
56
- "@teambit/watcher": "1.0.465",
57
- "@teambit/workspace": "1.0.465",
58
- "@teambit/compiler": "1.0.465",
55
+ "@teambit/pkg": "1.0.467",
56
+ "@teambit/pubsub": "1.0.467",
57
+ "@teambit/scope": "1.0.467",
58
+ "@teambit/watcher": "1.0.467",
59
+ "@teambit/workspace": "1.0.467",
60
+ "@teambit/compiler": "1.0.467",
59
61
  "@teambit/preview.cli.webpack-events-listener": "0.0.175",
60
- "@teambit/webpack": "1.0.465"
62
+ "@teambit/webpack": "1.0.467"
61
63
  },
62
64
  "devDependencies": {
63
65
  "@types/mime": "2.0.3",
@@ -1,5 +1,15 @@
1
- import { EnvService, Env, EnvContext, ServiceTransformationMap } from '@teambit/envs';
2
- import { EnvPreviewConfig } from './preview.main.runtime';
1
+ import filenamify from 'filenamify';
2
+ import { EnvService, ExecutionContext, Env, EnvContext, ServiceTransformationMap } from '@teambit/envs';
3
+ import { EnvPreviewConfig, PreviewMain } from './preview.main.runtime';
4
+ import { BitError } from '@teambit/bit-error';
5
+ import { DependencyResolverMain } from '@teambit/dependency-resolver';
6
+ import { Logger } from '@teambit/logger';
7
+ import { Bundler, BundlerContext, BundlerHtmlConfig, Target } from '@teambit/bundler';
8
+ import { Component, ComponentID } from '@teambit/component';
9
+ import { join, resolve } from 'path';
10
+ import { outputFileSync, pathExists, readJsonSync } from 'fs-extra';
11
+ import { ScopeMain } from '@teambit/scope';
12
+ import { html } from './bundler/html-template';
3
13
 
4
14
  type PreviewTransformationMap = ServiceTransformationMap & {
5
15
  /**
@@ -27,9 +37,18 @@ type PreviewTransformationMap = ServiceTransformationMap & {
27
37
  getPreviewConfig?: () => EnvPreviewConfig;
28
38
  };
29
39
 
40
+ const LOCAL_PREVIEW_DIR = 'local-preview';
41
+
30
42
  export class PreviewService implements EnvService<any> {
31
43
  name = 'preview';
32
44
 
45
+ constructor(
46
+ private preview: PreviewMain,
47
+ private logger: Logger,
48
+ private dependencyResolver: DependencyResolverMain,
49
+ private scope: ScopeMain
50
+ ) {}
51
+
33
52
  transform(env: Env, envContext: EnvContext): PreviewTransformationMap | undefined {
34
53
  // Old env
35
54
  if (!env?.preview) return undefined;
@@ -48,4 +67,171 @@ export class PreviewService implements EnvService<any> {
48
67
 
49
68
  return transformMap;
50
69
  }
70
+
71
+ async run(context: ExecutionContext, options: { name: string }): Promise<any> {
72
+ const defs = this.preview.getDefs();
73
+ const onlyCompositionDef = defs.filter((def) => def.prefix === 'compositions');
74
+ if (!onlyCompositionDef || onlyCompositionDef.length === 0) {
75
+ throw new BitError('unable to find composition definition');
76
+ }
77
+ const components = context.components;
78
+ const componentIds = components.map((c) => c.id);
79
+ const envDirName = this.getEnvDirName(context.id);
80
+ const outputPath = this.getEnvLocalPreviewDir(options.name, envDirName);
81
+ const linkFiles = await this.preview.updateLinkFiles(onlyCompositionDef, context.components, context);
82
+ const dirPath = join(this.preview.tempFolder, context.id);
83
+ await this.addComponentsToLocalMapping(options.name, envDirName, componentIds);
84
+ const previewRootEntry = this.generateLocalPreviewRoot(dirPath);
85
+
86
+ const entries = [...linkFiles, previewRootEntry];
87
+ const peers = await this.dependencyResolver.getPreviewHostDependenciesFromEnv(context.envDefinition.env);
88
+ const hostRootDir = context.envRuntime.envAspectDefinition?.aspectPath;
89
+ const targets = this.getTargets({ entries, components, outputPath, peers, hostRootDir });
90
+ const url = `/preview/${context.envRuntime.id}`;
91
+ const htmlConfig = this.generateHtmlConfig();
92
+ // @ts-ignore we don't really need the full bundler type here, we should
93
+ // change the original type to only have the relevant fields
94
+ const bundlerContext: BundlerContext = Object.assign(context, {
95
+ targets,
96
+ compress: false,
97
+ html: [htmlConfig],
98
+ components,
99
+ entry: [],
100
+ publicPath: '/',
101
+ hostRootDir,
102
+ hostDependencies: peers,
103
+ aliasHostDependencies: true,
104
+ rootPath: url,
105
+ development: true,
106
+ metaData: {
107
+ initiator: `Generate local preview`,
108
+ envId: context.id,
109
+ },
110
+ });
111
+
112
+ const bundler: Bundler = await context.env.getBundler(bundlerContext);
113
+ await bundler.run();
114
+ const res = componentIds.reduce((acc, id) => {
115
+ return { ...acc, [id.fullName]: outputPath };
116
+ }, {});
117
+ return res;
118
+ }
119
+
120
+ getEnvDirName(envId: string): string {
121
+ return filenamify(envId, { replacement: '_' });
122
+ }
123
+
124
+ getLocalPreviewDir(name: string) {
125
+ const dirPath = this.scope.legacyScope.tmp.composePath(`${LOCAL_PREVIEW_DIR}/${name}`);
126
+ return dirPath;
127
+ }
128
+
129
+ getEnvLocalPreviewDir(name: string, envDirName: string) {
130
+ const localPreviewDir = this.getLocalPreviewDir(name);
131
+ return join(localPreviewDir, envDirName);
132
+ }
133
+
134
+ getComponentsPreviewPath(name: string) {
135
+ const dirPath = this.getLocalPreviewDir(name);
136
+ const filePath = join(dirPath, 'components-preview.json');
137
+ return filePath;
138
+ }
139
+
140
+ async readComponentsPreview(name: string) {
141
+ const filePath = this.getComponentsPreviewPath(name);
142
+ return readJsonSync(filePath);
143
+ }
144
+
145
+ async addComponentsToLocalMapping(name: string, envDirPath: string, compIds: ComponentID[]) {
146
+ const filePath = this.getComponentsPreviewPath(name);
147
+ // const idsString = compIds.map((id) => id.toString());
148
+ const idsString = compIds.map((id) => id.fullName);
149
+ const exists = await pathExists(filePath);
150
+ // let newFile = { [envDirPath]: idsString };
151
+ let newFile = idsString.reduce((acc, id) => {
152
+ return { ...acc, [id]: envDirPath };
153
+ }, {});
154
+ if (exists) {
155
+ const existingFile = readJsonSync(filePath);
156
+ newFile = { ...existingFile, ...newFile };
157
+ }
158
+ outputFileSync(filePath, JSON.stringify(newFile, null, 2));
159
+ return newFile;
160
+ }
161
+
162
+ generateLocalPreviewRoot(dir: string) {
163
+ const contents = `const previewModules = window.__bit_preview_modules;
164
+ const queryString = window.location.search;
165
+ const urlParams = new URLSearchParams(queryString);
166
+ const location = window.location.pathname;
167
+ const splitLocation = location.split('/').filter((x) => x);
168
+ // Remove message part
169
+ splitLocation.shift();
170
+ // const comp = urlParams.get('comp');
171
+ const comp = splitLocation.join('/');
172
+ const compositions = previewModules.get("compositions");
173
+ const mounter = compositions.modulesMap.default;
174
+ const componentMap = compositions.componentMap;
175
+ const foundComponent = componentMap[comp];
176
+ if (!foundComponent) {
177
+ throw new Error('component not found');
178
+ }
179
+ let compositionName = urlParams.get('name');
180
+ if (!compositionName) {
181
+ const allCompositions = Object.keys(foundComponent[0]);
182
+ compositionName = allCompositions[0];
183
+ }
184
+ const composition = foundComponent[0][compositionName];
185
+ if (!composition) {
186
+ throw new Error('composition not found');
187
+ }
188
+ let func = mounter.default;
189
+ if (typeof func !== 'function') {
190
+ func = func.default;
191
+ }
192
+ func(composition);
193
+ `;
194
+ const previewRootPath = resolve(join(dir, `preview.entry.js`));
195
+
196
+ // if (!existsSync(previewRootPath)) {
197
+ outputFileSync(previewRootPath, contents);
198
+ // }
199
+ return previewRootPath;
200
+ }
201
+
202
+ generateHtmlConfig() {
203
+ const config: BundlerHtmlConfig = {
204
+ title: 'Preview',
205
+ templateContent: html('Preview'),
206
+ minify: false,
207
+ filename: 'index.html',
208
+ };
209
+ return config;
210
+ }
211
+
212
+ private getTargets({
213
+ entries,
214
+ components,
215
+ outputPath,
216
+ peers,
217
+ hostRootDir,
218
+ }: {
219
+ entries: string[];
220
+ components: Component[];
221
+ outputPath: string;
222
+ peers?: string[];
223
+ hostRootDir: string;
224
+ }): Target[] {
225
+ return [
226
+ {
227
+ entries,
228
+ components,
229
+ outputPath,
230
+ hostRootDir,
231
+ hostDependencies: peers,
232
+ externalizeHostDependencies: false,
233
+ aliasHostDependencies: true,
234
+ },
235
+ ];
236
+ }
51
237
  }
@@ -0,0 +1,21 @@
1
+ import { Command, CommandOptions } from '@teambit/cli';
2
+ import type { PreviewMain } from './preview.main.runtime';
3
+
4
+ export class ServePreviewCmd implements Command {
5
+ name = 'serve-preview';
6
+ description = 'serve local preview bundle for components';
7
+ group = 'development';
8
+ options = [['p', 'port [port]', 'port to run the server on']] as CommandOptions;
9
+ private = true;
10
+
11
+ constructor(
12
+ /**
13
+ * access to the extension instance.
14
+ */
15
+ private preview: PreviewMain
16
+ ) {}
17
+
18
+ async wait(args, options: { port: number }) {
19
+ await this.preview.serveLocalPreview(options);
20
+ }
21
+ }
@@ -7,7 +7,6 @@ import { Compiler } from '@teambit/compiler';
7
7
  import type { AbstractVinyl } from '@teambit/component.sources';
8
8
  import type { Capsule } from '@teambit/isolator';
9
9
  import { CAPSULE_ARTIFACTS_DIR, ComponentResult } from '@teambit/builder';
10
- import type { PkgMain } from '@teambit/pkg';
11
10
  import { BitError } from '@teambit/bit-error';
12
11
  import type { DependencyResolverMain } from '@teambit/dependency-resolver';
13
12
  import { Logger } from '@teambit/logger';
@@ -39,7 +38,6 @@ export class ComponentBundlingStrategy implements BundlingStrategy {
39
38
 
40
39
  constructor(
41
40
  private preview: PreviewMain,
42
- private pkg: PkgMain,
43
41
  private dependencyResolver: DependencyResolverMain,
44
42
  private logger: Logger
45
43
  ) {}