@teambit/preview 1.0.108 → 1.0.109
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/artifacts/__bit_junit.xml +6 -0
- package/artifacts/preview/teambit_preview_preview-preview.js +1 -0
- package/dist/{preview-1703647408454.js → preview-1703698405864.js} +2 -2
- package/package.json +21 -21
- package/artifact-file-middleware.ts +0 -66
- package/bundling-strategy.ts +0 -30
- package/component-preview.route.ts +0 -52
- package/component-preview.ts +0 -3
- package/env-preview-template.task.ts +0 -280
- package/env-template.route.ts +0 -72
- package/execution-ref.ts +0 -25
- package/generate-link.ts +0 -73
- package/index.ts +0 -18
- package/mk-temp-dir.ts +0 -7
- package/preview-artifact.ts +0 -24
- package/preview-assets.route.ts +0 -36
- package/preview-context.ts +0 -5
- package/preview-definition.ts +0 -41
- package/preview-env.ts +0 -46
- package/preview-type.ts +0 -36
- package/preview.aspect.ts +0 -12
- package/preview.graphql.ts +0 -48
- package/preview.route.ts +0 -58
- package/preview.task.ts +0 -85
- package/preview.ts +0 -13
- package/rendering-context.ts +0 -16
- package/size-event.ts +0 -14
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<testsuites>
|
|
3
|
+
<testsuite name="teambit.preview/preview@1.0.109" timestamp="2023-12-27T17:56:28.158Z" tests="1" failures="0" errors="0" skipped="0">
|
|
4
|
+
<testcase classname="create-peer-link.spec.js" name="should output snapshot" time="0.145"/>
|
|
5
|
+
</testsuite>
|
|
6
|
+
</testsuites>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["teambit.preview/preview-preview"]=t():e["teambit.preview/preview-preview"]=t()}(self,(()=>(()=>{"use strict";var e={47289:(e,t,n)=>{var o={id:"teambit.preview/preview@1.0.109",homepage:"https://bit.cloud/teambit/preview/preview",exported:!0};function r(){const e=i(n(87363));return r=function(){return e},e}function i(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0}),t.Logo=void 0,r.__bit_component=o,i.__bit_component=o;const a=()=>r().default.createElement("div",{style:{height:"100%",display:"flex",justifyContent:"center"}},r().default.createElement("img",{style:{width:70},src:"https://static.bit.dev/extensions-icons/preview.svg"}));a.__bit_component=o,t.Logo=a},77634:(e,t,n)=>{Object.defineProperty(t,"M",{enumerable:!0,get:function(){return o.default}});var o=r(n(26795));function r(e){return e&&e.__esModule?e:{default:e}}r.__bit_component={id:"teambit.preview/aspect-docs/preview@0.0.165",homepage:"https://bit.cloud/teambit/preview/aspect-docs/preview",exported:!0}},26795:(e,t,n)=>{var o={id:"teambit.preview/aspect-docs/preview@0.0.165",homepage:"https://bit.cloud/teambit/preview/aspect-docs/preview",exported:!0};Object.defineProperty(t,"__esModule",{value:!0}),t.default=m,a(n(87363));var r=n(40040),i=["components"];function a(e){return e&&e.__esModule?e:{default:e}}function s(){return s=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},s.apply(this,arguments)}function p(e,t){if(null==e)return{};var n,o,r=d(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o<i.length;o++)n=i[o],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function d(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o<i.length;o++)n=i[o],t.indexOf(n)>=0||(r[n]=e[n]);return r}a.__bit_component=o,s.__bit_component=o,p.__bit_component=o,d.__bit_component=o;var l={},c="wrapper";function m(e){var t=e.components,n=p(e,i);return(0,r.mdx)(c,s({},l,n,{components:t,mdxType:"MDXLayout"}),(0,r.mdx)("p",null,"The Preview aspect handles the bundling and rendering of component compositions and documentation, for the Workspace UI and Scope UI."),(0,r.mdx)("p",null,"Preview is used to display components in development (on ",(0,r.mdx)("inlineCode",{parentName:"p"},"bit start"),") as well as in their released versions (assets for the release version are generated as part of the build process)."),(0,r.mdx)("p",null,"The Preview aspect handles each component according to the configurations set by the environment that is used by that component. That means both the documentation and the component compositions will be bundled and displayed differently for different environments."),(0,r.mdx)("h2",null,"Rational"),(0,r.mdx)("p",null,"In a standard web application, UI components ",(0,r.mdx)("em",{parentName:"p"},"serving the same application")," are bundled together to produce the necessary assets to make them renderable by the browser."),(0,r.mdx)("p",null,"Components in a Bit workspace are not all in the service of the same application. Each component is authored, tagged and exported as an independent component.\nThat means a few things:"),(0,r.mdx)("ol",null,(0,r.mdx)("li",{parentName:"ol"},(0,r.mdx)("p",{parentName:"li"},"Components in a Bit workspace are not consumed ,directly or indirectly, by a single entry file (e.g, the app's ",(0,r.mdx)("inlineCode",{parentName:"p"},"index.js"),"). That makes it impossible for the bundler to follow the files needed to be bundled.")),(0,r.mdx)("li",{parentName:"ol"},(0,r.mdx)("p",{parentName:"li"},"Different components in a single workspace may be implemented using different technologies and bundled using different configurations or even different bundlers."))),(0,r.mdx)("p",null,"Preview solves the above challenges by creating a temporary entry file for each group of components using the same environment.\nIt then serves this file to the Bundler, to be bundled according to the environment and the purpose of bundling. That is, to display components in development or to display the components' release versions (for a \"production-level\" exhibition of the component's documentation and compositions)."),(0,r.mdx)("h2",null,"Usage"),(0,r.mdx)("h3",null,"Extending the Preview aspect"),(0,r.mdx)("p",null,"The preview aspect can be extended to generate other renderable artifacts , either when running Bit's development server or as part of the build pipeline (for a component's tagged version).\nThese artifacts can present additional information that assists in inspecting a component (for example, showing the results of accessibility tests)."))}m.__bit_component=o,m.isMDXComponent=!0},40040:e=>{e.exports=MdxJsReact},87363:e=>{e.exports=React}},t={};function n(o){var r=t[o];if(void 0!==r)return r.exports;var i=t[o]={exports:{}};return e[o](i,i.exports,n),i.exports}n.d=(e,t)=>{for(var o in t)n.o(t,o)&&!n.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var o={};return(()=>{n.r(o),n.d(o,{compositions:()=>m,compositions_metadata:()=>f,overview:()=>u});var e={};n.r(e),n.d(e,{default:()=>c});var t=n(47289),r=(n(87363),n(40040));const i=TeambitMdxUiMdxScopeContext;var a=n(77634),s=["components"];function p(){return p=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},p.apply(this,arguments)}var d={},l="wrapper";function c(e){var t=e.components,n=function(e,t){if(null==e)return{};var n,o,r=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o<i.length;o++)n=i[o],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o<i.length;o++)n=i[o],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}(e,s);return(0,r.mdx)(l,p({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.mdx)(i.MDXScopeProvider,{components:{Preview:a.M},mdxType:"MDXScopeProvider"},(0,r.mdx)(a.M,{mdxType:"Preview"})))}c.isMDXComponent=!0;const m=[t],u=[e],f={compositions:[{displayName:"Logo",identifier:"Logo"}]}})(),o})()));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as compositions_0 from '/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.preview_preview@1.0.
|
|
2
|
-
import * as overview_0 from '/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.preview_preview@1.0.
|
|
1
|
+
import * as compositions_0 from '/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.preview_preview@1.0.109/dist/preview.composition.js';
|
|
2
|
+
import * as overview_0 from '/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.preview_preview@1.0.109/dist/preview.docs.mdx';
|
|
3
3
|
|
|
4
4
|
export const compositions = [compositions_0];
|
|
5
5
|
export const overview = [overview_0];
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teambit/preview",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.109",
|
|
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.
|
|
9
|
+
"version": "1.0.109"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"mime": "2.5.2",
|
|
@@ -22,28 +22,28 @@
|
|
|
22
22
|
"@teambit/component-id": "1.2.0",
|
|
23
23
|
"@teambit/harmony": "0.4.6",
|
|
24
24
|
"@teambit/bit-error": "0.0.404",
|
|
25
|
-
"@teambit/express": "0.0.
|
|
26
|
-
"@teambit/logger": "0.0.
|
|
27
|
-
"@teambit/builder": "1.0.
|
|
28
|
-
"@teambit/bundler": "1.0.
|
|
29
|
-
"@teambit/component": "1.0.
|
|
25
|
+
"@teambit/express": "0.0.940",
|
|
26
|
+
"@teambit/logger": "0.0.934",
|
|
27
|
+
"@teambit/builder": "1.0.109",
|
|
28
|
+
"@teambit/bundler": "1.0.109",
|
|
29
|
+
"@teambit/component": "1.0.109",
|
|
30
30
|
"@teambit/preview.ui.component-preview": "1.0.3",
|
|
31
|
-
"@teambit/aspect-loader": "1.0.
|
|
32
|
-
"@teambit/cli": "0.0.
|
|
33
|
-
"@teambit/dependency-resolver": "1.0.
|
|
34
|
-
"@teambit/envs": "1.0.
|
|
31
|
+
"@teambit/aspect-loader": "1.0.109",
|
|
32
|
+
"@teambit/cli": "0.0.841",
|
|
33
|
+
"@teambit/dependency-resolver": "1.0.109",
|
|
34
|
+
"@teambit/envs": "1.0.109",
|
|
35
35
|
"@teambit/toolbox.path.to-windows-compatible-path": "0.0.494",
|
|
36
|
-
"@teambit/graphql": "1.0.
|
|
37
|
-
"@teambit/pkg": "1.0.
|
|
38
|
-
"@teambit/pubsub": "1.0.
|
|
39
|
-
"@teambit/scope": "1.0.
|
|
40
|
-
"@teambit/ui": "1.0.
|
|
41
|
-
"@teambit/watcher": "1.0.
|
|
42
|
-
"@teambit/workspace": "1.0.
|
|
43
|
-
"@teambit/compiler": "1.0.
|
|
36
|
+
"@teambit/graphql": "1.0.109",
|
|
37
|
+
"@teambit/pkg": "1.0.109",
|
|
38
|
+
"@teambit/pubsub": "1.0.109",
|
|
39
|
+
"@teambit/scope": "1.0.109",
|
|
40
|
+
"@teambit/ui": "1.0.109",
|
|
41
|
+
"@teambit/watcher": "1.0.109",
|
|
42
|
+
"@teambit/workspace": "1.0.109",
|
|
43
|
+
"@teambit/compiler": "1.0.109",
|
|
44
44
|
"@teambit/preview.cli.preview-server-status": "0.0.504",
|
|
45
45
|
"@teambit/preview.cli.webpack-events-listener": "0.0.172",
|
|
46
|
-
"@teambit/isolator": "1.0.
|
|
46
|
+
"@teambit/isolator": "1.0.109"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@types/mime": "2.0.3",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"@types/mocha": "9.1.0",
|
|
58
58
|
"@types/jest": "^29.2.2",
|
|
59
59
|
"@types/testing-library__jest-dom": "^5.9.5",
|
|
60
|
-
"@teambit/harmony.envs.core-aspect-env": "0.0.
|
|
60
|
+
"@teambit/harmony.envs.core-aspect-env": "0.0.14",
|
|
61
61
|
"@teambit/preview.aspect-docs.preview": "0.0.165"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import mime from 'mime';
|
|
2
|
-
import type { Request, Response } from '@teambit/express';
|
|
3
|
-
import { noPreview, serverError } from '@teambit/ui-foundation.ui.pages.static-error';
|
|
4
|
-
import type { Logger } from '@teambit/logger';
|
|
5
|
-
import type { PreviewArtifact } from './preview-artifact';
|
|
6
|
-
|
|
7
|
-
export type PreviewUrlParams = {
|
|
8
|
-
/**
|
|
9
|
-
* preview name like overview or composition
|
|
10
|
-
*/
|
|
11
|
-
previewName?: string;
|
|
12
|
-
/** `/preview/:filePath(*)` */
|
|
13
|
-
filePath?: string;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export type GetCacheControlFunc = (filePath: string, contents: string, mimeType?: string | null) => string | undefined;
|
|
17
|
-
|
|
18
|
-
export function getArtifactFileMiddleware(logger: Logger, getCacheControlFunc?: GetCacheControlFunc) {
|
|
19
|
-
return async (req: Request<PreviewUrlParams>, res: Response) => {
|
|
20
|
-
try {
|
|
21
|
-
// @ts-ignore
|
|
22
|
-
const artifact: PreviewArtifact = req.artifact;
|
|
23
|
-
// @ts-ignore
|
|
24
|
-
const isLegacyPath = req.isLegacyPath;
|
|
25
|
-
let file;
|
|
26
|
-
if (!isLegacyPath) {
|
|
27
|
-
file = getEnvTemplateFile(artifact, req.params.previewName, req.params.filePath);
|
|
28
|
-
} else {
|
|
29
|
-
file = getPreviewFile(artifact, req.params.previewName, req.params.filePath);
|
|
30
|
-
}
|
|
31
|
-
if (!file) return res.status(404).send(noPreview());
|
|
32
|
-
|
|
33
|
-
const contents = file.contents;
|
|
34
|
-
const str = `${file.cwd}/${file.path}`;
|
|
35
|
-
const contentType = mime.getType(str);
|
|
36
|
-
if (contentType) res.set('Content-Type', contentType);
|
|
37
|
-
if (getCacheControlFunc) {
|
|
38
|
-
const cacheControl = getCacheControlFunc(str, contents, contentType);
|
|
39
|
-
if (cacheControl) {
|
|
40
|
-
res.set('Cache-control', cacheControl);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return res.send(contents);
|
|
44
|
-
} catch (e: any) {
|
|
45
|
-
logger.error('failed getting preview', e);
|
|
46
|
-
return res.status(500).send(serverError());
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function getEnvTemplateFile(artifact: PreviewArtifact, previewName?: string, filePath?: string) {
|
|
52
|
-
const prevName = previewName || 'overview';
|
|
53
|
-
const finalFilePath = filePath || `${prevName}.html`;
|
|
54
|
-
const matchedFile = artifact?.getFileEndsWith(finalFilePath);
|
|
55
|
-
return matchedFile;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function getPreviewFile(artifact: PreviewArtifact, previewName?: string, filePath?: string) {
|
|
59
|
-
let finalFilePath = 'index.html';
|
|
60
|
-
if (previewName || filePath) {
|
|
61
|
-
const parts = [previewName, filePath].filter((x) => x);
|
|
62
|
-
finalFilePath = parts.join('/');
|
|
63
|
-
}
|
|
64
|
-
const matchedFile = artifact?.getFileEndsWith(finalFilePath);
|
|
65
|
-
return matchedFile;
|
|
66
|
-
}
|
package/bundling-strategy.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { BuildContext, BuiltTaskResult } from '@teambit/builder';
|
|
2
|
-
import { Target, BundlerResult, BundlerContext } from '@teambit/bundler';
|
|
3
|
-
import { PreviewDefinition } from './preview-definition';
|
|
4
|
-
import { PreviewTask } from './preview.task';
|
|
5
|
-
|
|
6
|
-
type ComputeTargetsExtraContextKeys = {
|
|
7
|
-
splitComponentBundle?: boolean;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export type ComputeTargetsContext = BuildContext & ComputeTargetsExtraContextKeys;
|
|
11
|
-
export interface BundlingStrategy {
|
|
12
|
-
/**
|
|
13
|
-
* name of the bundling strategy.
|
|
14
|
-
*/
|
|
15
|
-
name: string;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* compute bundling targets for the build context.
|
|
19
|
-
*/
|
|
20
|
-
computeTargets(
|
|
21
|
-
context: ComputeTargetsContext,
|
|
22
|
-
previewDefs: PreviewDefinition[],
|
|
23
|
-
previewTask: PreviewTask
|
|
24
|
-
): Promise<Target[]>;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* compute the results of the bundler.
|
|
28
|
-
*/
|
|
29
|
-
computeResults(context: BundlerContext, results: BundlerResult[], previewTask: PreviewTask): Promise<BuiltTaskResult>;
|
|
30
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import type { NextFunction, Request, Response, Route } from '@teambit/express';
|
|
2
|
-
import type { Component } from '@teambit/component';
|
|
3
|
-
import { noPreview, serverError } from '@teambit/ui-foundation.ui.pages.static-error';
|
|
4
|
-
import type { Logger } from '@teambit/logger';
|
|
5
|
-
|
|
6
|
-
import { PreviewMain } from './preview.main.runtime';
|
|
7
|
-
import type { PreviewArtifact } from './preview-artifact';
|
|
8
|
-
import type { PreviewUrlParams } from './artifact-file-middleware';
|
|
9
|
-
import { getArtifactFileMiddleware } from './artifact-file-middleware';
|
|
10
|
-
|
|
11
|
-
export class ComponentPreviewRoute implements Route {
|
|
12
|
-
constructor(
|
|
13
|
-
/**
|
|
14
|
-
* preview extension.
|
|
15
|
-
*/
|
|
16
|
-
private preview: PreviewMain,
|
|
17
|
-
private logger: Logger
|
|
18
|
-
) {}
|
|
19
|
-
|
|
20
|
-
route = `/component-preview/:filePath(*)`;
|
|
21
|
-
method = 'get';
|
|
22
|
-
|
|
23
|
-
middlewares = [
|
|
24
|
-
async (req: Request<PreviewUrlParams>, res: Response, next: NextFunction) => {
|
|
25
|
-
try {
|
|
26
|
-
let isLegacyPath = false;
|
|
27
|
-
// @ts-ignore TODO: @guy please fix.
|
|
28
|
-
const component = req.component as Component | undefined;
|
|
29
|
-
if (!component) return res.status(404).send(noPreview());
|
|
30
|
-
|
|
31
|
-
let artifact: PreviewArtifact | undefined;
|
|
32
|
-
// TODO - prevent error `getVinylsAndImportIfMissing is not a function` #4680
|
|
33
|
-
try {
|
|
34
|
-
isLegacyPath = true;
|
|
35
|
-
artifact = await this.preview.getPreview(component);
|
|
36
|
-
} catch (e: any) {
|
|
37
|
-
this.logger.error(`preview.getPreview has failed`, e);
|
|
38
|
-
return res.status(404).send(noPreview());
|
|
39
|
-
}
|
|
40
|
-
// @ts-ignore
|
|
41
|
-
req.artifact = artifact;
|
|
42
|
-
// @ts-ignore
|
|
43
|
-
req.isLegacyPath = isLegacyPath;
|
|
44
|
-
return next();
|
|
45
|
-
} catch (e: any) {
|
|
46
|
-
this.logger.error('failed getting preview', e);
|
|
47
|
-
return res.status(500).send(serverError());
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
getArtifactFileMiddleware(this.logger),
|
|
51
|
-
];
|
|
52
|
-
}
|
package/component-preview.ts
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BuildContext,
|
|
3
|
-
BuiltTaskResult,
|
|
4
|
-
BuildTask,
|
|
5
|
-
TaskLocation,
|
|
6
|
-
ComponentResult,
|
|
7
|
-
CAPSULE_ARTIFACTS_DIR,
|
|
8
|
-
} from '@teambit/builder';
|
|
9
|
-
import { MainRuntime } from '@teambit/cli';
|
|
10
|
-
import mapSeries from 'p-map-series';
|
|
11
|
-
import { Component, ComponentMap } from '@teambit/component';
|
|
12
|
-
import { AspectLoaderMain } from '@teambit/aspect-loader';
|
|
13
|
-
import { Bundler, BundlerContext, BundlerHtmlConfig, BundlerResult, Target } from '@teambit/bundler';
|
|
14
|
-
import type { EnvDefinition, Environment, EnvsMain } from '@teambit/envs';
|
|
15
|
-
import { join } from 'path';
|
|
16
|
-
import { compact, flatten, isEmpty } from 'lodash';
|
|
17
|
-
import { Logger } from '@teambit/logger';
|
|
18
|
-
import { DependencyResolverMain } from '@teambit/dependency-resolver';
|
|
19
|
-
import { existsSync, mkdirpSync } from 'fs-extra';
|
|
20
|
-
import type { PreviewMain } from './preview.main.runtime';
|
|
21
|
-
import { generateTemplateEntries } from './bundler/chunks';
|
|
22
|
-
import { generateHtmlConfig } from './bundler/html-plugin';
|
|
23
|
-
import { writePeerLink } from './bundler/create-peers-link';
|
|
24
|
-
|
|
25
|
-
export type ModuleExpose = {
|
|
26
|
-
name: string;
|
|
27
|
-
path: string;
|
|
28
|
-
include?: string[];
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
type TargetsGroup = {
|
|
32
|
-
env: Environment;
|
|
33
|
-
envToGetBundler: Environment;
|
|
34
|
-
targets: Target[];
|
|
35
|
-
};
|
|
36
|
-
type TargetsGroupMap = {
|
|
37
|
-
[envId: string]: TargetsGroup;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export const GENERATE_ENV_TEMPLATE_TASK_NAME = 'GenerateEnvTemplate';
|
|
41
|
-
|
|
42
|
-
export class EnvPreviewTemplateTask implements BuildTask {
|
|
43
|
-
aspectId = 'teambit.preview/preview';
|
|
44
|
-
name = GENERATE_ENV_TEMPLATE_TASK_NAME;
|
|
45
|
-
location: TaskLocation = 'end';
|
|
46
|
-
// readonly dependencies = [CompilerAspect.id];
|
|
47
|
-
|
|
48
|
-
constructor(
|
|
49
|
-
private preview: PreviewMain,
|
|
50
|
-
private envs: EnvsMain,
|
|
51
|
-
private aspectLoader: AspectLoaderMain,
|
|
52
|
-
private dependencyResolver: DependencyResolverMain,
|
|
53
|
-
private logger: Logger
|
|
54
|
-
) {}
|
|
55
|
-
|
|
56
|
-
async execute(context: BuildContext): Promise<BuiltTaskResult> {
|
|
57
|
-
const previewDefs = this.preview.getDefs();
|
|
58
|
-
const htmlConfig = previewDefs.map((previewModule) => generateHtmlConfig(previewModule, { dev: context.dev }));
|
|
59
|
-
const originalSeedersIds = context.capsuleNetwork.originalSeedersCapsules.map((c) => c.component.id.toString());
|
|
60
|
-
const grouped: TargetsGroupMap = {};
|
|
61
|
-
// avoid running them with `Promise.all` because getEnv methods do import/isolate which can't be in parallel.
|
|
62
|
-
await mapSeries(context.components, async (component) => {
|
|
63
|
-
// Do not run over other components in the graph. it make the process much longer with no need
|
|
64
|
-
if (originalSeedersIds && originalSeedersIds.length && !originalSeedersIds.includes(component.id.toString())) {
|
|
65
|
-
return undefined;
|
|
66
|
-
}
|
|
67
|
-
const envDef = this.envs.getEnvFromComponent(component);
|
|
68
|
-
if (!envDef) return undefined;
|
|
69
|
-
const env = envDef.env;
|
|
70
|
-
const bundlingStrategy = this.preview.getBundlingStrategy(envDef.env);
|
|
71
|
-
if (bundlingStrategy.name === 'env') {
|
|
72
|
-
return undefined;
|
|
73
|
-
}
|
|
74
|
-
const target = await this.getEnvTargetFromComponent(context, component, envDef, htmlConfig);
|
|
75
|
-
if (!target) return undefined;
|
|
76
|
-
const shouldUseDefaultBundler = this.shouldUseDefaultBundler(envDef);
|
|
77
|
-
let envToGetBundler = this.envs.getEnvsEnvDefinition().env;
|
|
78
|
-
let groupEnvId = 'default';
|
|
79
|
-
if (!shouldUseDefaultBundler) {
|
|
80
|
-
envToGetBundler = env;
|
|
81
|
-
groupEnvId = envDef.id;
|
|
82
|
-
}
|
|
83
|
-
if (!grouped[groupEnvId]) {
|
|
84
|
-
grouped[groupEnvId] = {
|
|
85
|
-
env,
|
|
86
|
-
envToGetBundler,
|
|
87
|
-
targets: [target],
|
|
88
|
-
};
|
|
89
|
-
} else {
|
|
90
|
-
grouped[groupEnvId].targets.push(target);
|
|
91
|
-
}
|
|
92
|
-
return undefined;
|
|
93
|
-
});
|
|
94
|
-
if (isEmpty(grouped)) {
|
|
95
|
-
return { componentsResults: [] };
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return this.runBundlerForGroups(context, grouped);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
private async runBundlerForGroups(context: BuildContext, groups: TargetsGroupMap): Promise<BuiltTaskResult> {
|
|
102
|
-
const bundlerContext: BundlerContext = Object.assign(context, {
|
|
103
|
-
targets: [],
|
|
104
|
-
entry: [],
|
|
105
|
-
development: context.dev,
|
|
106
|
-
metaData: {
|
|
107
|
-
initiator: `${GENERATE_ENV_TEMPLATE_TASK_NAME} task`,
|
|
108
|
-
envId: context.id,
|
|
109
|
-
isEnvTemplate: true,
|
|
110
|
-
},
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
const bundlerResults = await mapSeries(Object.entries(groups), async ([, targetsGroup]) => {
|
|
114
|
-
bundlerContext.targets = targetsGroup.targets;
|
|
115
|
-
const bundler: Bundler = await targetsGroup.envToGetBundler.getTemplateBundler(bundlerContext);
|
|
116
|
-
const bundlerResult = await bundler.run();
|
|
117
|
-
return bundlerResult;
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
const results = await this.computeResults(bundlerContext, flatten(bundlerResults));
|
|
121
|
-
return results;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
private shouldUseDefaultBundler(envDef: EnvDefinition): boolean {
|
|
125
|
-
if (this.aspectLoader.isCoreEnv(envDef.id) && envDef.id !== 'teambit.react/react-native') return true;
|
|
126
|
-
const env = envDef.env;
|
|
127
|
-
if (env.getTemplateBundler && typeof env.getTemplateBundler === 'function') return false;
|
|
128
|
-
return true;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
private async getEnvTargetFromComponent(
|
|
132
|
-
context: BuildContext,
|
|
133
|
-
envComponent: Component,
|
|
134
|
-
envDef: EnvDefinition,
|
|
135
|
-
htmlConfig: BundlerHtmlConfig[]
|
|
136
|
-
): Promise<Target | undefined> {
|
|
137
|
-
const envPreviewConfig = this.preview.getEnvPreviewConfig(envDef.env);
|
|
138
|
-
|
|
139
|
-
const peers = await this.dependencyResolver.getPreviewHostDependenciesFromEnv(envDef.env);
|
|
140
|
-
// const module = await this.getPreviewModule(envComponent);
|
|
141
|
-
// const entries = Object.keys(module).map((key) => module.exposes[key]);
|
|
142
|
-
const capsule = context.capsuleNetwork.graphCapsules.getCapsule(envComponent.id);
|
|
143
|
-
if (!capsule) throw new Error('no capsule found');
|
|
144
|
-
// Passing here the env itself to make sure it's preview runtime will be part of the preview root file
|
|
145
|
-
// that's needed to make sure the providers register there are running correctly
|
|
146
|
-
const previewRoot = await this.preview.writePreviewRuntime(context, [envComponent.id.toString()]);
|
|
147
|
-
const entries = await this.generateEntries({
|
|
148
|
-
envDef,
|
|
149
|
-
splitComponentBundle: envPreviewConfig.splitComponentBundle ?? false,
|
|
150
|
-
workDir: capsule.path,
|
|
151
|
-
peers,
|
|
152
|
-
previewRoot,
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
const outputPath = this.computeOutputPath(context, envComponent);
|
|
156
|
-
if (!existsSync(outputPath)) mkdirpSync(outputPath);
|
|
157
|
-
const resolvedEnvAspects = await this.preview.resolveAspects(MainRuntime.name, [envComponent.id], undefined, {
|
|
158
|
-
requestedOnly: true,
|
|
159
|
-
// required to support envs that are plguins (.bit-env files)
|
|
160
|
-
filterByRuntime: false,
|
|
161
|
-
});
|
|
162
|
-
const resolvedEnv = resolvedEnvAspects[0];
|
|
163
|
-
const hostRootDir = resolvedEnv?.aspectPath;
|
|
164
|
-
|
|
165
|
-
if (!hostRootDir) {
|
|
166
|
-
this.logger.warn(`env preview template task, hostRootDir is not defined, for env ${envComponent.id.toString()}`);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return {
|
|
170
|
-
peers,
|
|
171
|
-
html: htmlConfig,
|
|
172
|
-
entries,
|
|
173
|
-
chunking: { splitChunks: true },
|
|
174
|
-
components: [envComponent],
|
|
175
|
-
outputPath,
|
|
176
|
-
/* It's a path to the root of the host component. */
|
|
177
|
-
hostRootDir,
|
|
178
|
-
hostDependencies: peers,
|
|
179
|
-
aliasHostDependencies: true,
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
private async generateEntries({
|
|
184
|
-
previewRoot,
|
|
185
|
-
workDir,
|
|
186
|
-
peers,
|
|
187
|
-
envDef,
|
|
188
|
-
splitComponentBundle,
|
|
189
|
-
}: {
|
|
190
|
-
previewRoot: string;
|
|
191
|
-
workDir: string;
|
|
192
|
-
peers: string[];
|
|
193
|
-
envDef: EnvDefinition;
|
|
194
|
-
splitComponentBundle: boolean;
|
|
195
|
-
}) {
|
|
196
|
-
const previewModules = await this.getPreviewModules(envDef);
|
|
197
|
-
const previewEntries = previewModules.map(({ name, path, ...rest }) => {
|
|
198
|
-
const linkFile = this.preview.writeLink(
|
|
199
|
-
name,
|
|
200
|
-
ComponentMap.create([]),
|
|
201
|
-
{ default: path },
|
|
202
|
-
workDir,
|
|
203
|
-
splitComponentBundle
|
|
204
|
-
);
|
|
205
|
-
|
|
206
|
-
return { name, path, ...rest, entry: linkFile };
|
|
207
|
-
});
|
|
208
|
-
const peerLink = await writePeerLink(peers, workDir);
|
|
209
|
-
|
|
210
|
-
const entries = generateTemplateEntries({
|
|
211
|
-
peers: peerLink,
|
|
212
|
-
previewRootPath: previewRoot,
|
|
213
|
-
previewModules: previewEntries,
|
|
214
|
-
});
|
|
215
|
-
return entries;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
async computeResults(context: BundlerContext, results: BundlerResult[]) {
|
|
219
|
-
const allResults = results.map((result) => {
|
|
220
|
-
const componentsResults: ComponentResult[] = result.components.map((component) => {
|
|
221
|
-
return {
|
|
222
|
-
component,
|
|
223
|
-
errors: result.errors.map((err) => (typeof err === 'string' ? err : err.message)),
|
|
224
|
-
warning: result.warnings,
|
|
225
|
-
startTime: result.startTime,
|
|
226
|
-
endTime: result.endTime,
|
|
227
|
-
};
|
|
228
|
-
});
|
|
229
|
-
return componentsResults;
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
const componentsResults = flatten(allResults);
|
|
233
|
-
|
|
234
|
-
const artifacts = getArtifactDef();
|
|
235
|
-
|
|
236
|
-
return {
|
|
237
|
-
componentsResults,
|
|
238
|
-
artifacts,
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
private async getPreviewModules(envDef: EnvDefinition): Promise<ModuleExpose[]> {
|
|
243
|
-
const previewDefs = this.preview.getDefs();
|
|
244
|
-
|
|
245
|
-
const modules = compact(
|
|
246
|
-
await Promise.all(
|
|
247
|
-
previewDefs.map(async (def) => {
|
|
248
|
-
if (!def.renderTemplatePathByEnv) return undefined;
|
|
249
|
-
return {
|
|
250
|
-
name: def.prefix,
|
|
251
|
-
path: (await def.renderTemplatePathByEnv(envDef.env)) || '',
|
|
252
|
-
include: def.include,
|
|
253
|
-
};
|
|
254
|
-
})
|
|
255
|
-
)
|
|
256
|
-
);
|
|
257
|
-
|
|
258
|
-
return modules;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
private computeOutputPath(context: BuildContext, component: Component) {
|
|
262
|
-
const capsule = context.capsuleNetwork.graphCapsules.getCapsule(component.id);
|
|
263
|
-
if (!capsule) throw new Error('no capsule found');
|
|
264
|
-
return join(capsule.path, getArtifactDirectory());
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
export function getArtifactDirectory() {
|
|
269
|
-
return join(CAPSULE_ARTIFACTS_DIR, 'env-template');
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
export function getArtifactDef() {
|
|
273
|
-
return [
|
|
274
|
-
{
|
|
275
|
-
name: 'env-template',
|
|
276
|
-
globPatterns: ['**'],
|
|
277
|
-
rootDir: getArtifactDirectory(),
|
|
278
|
-
},
|
|
279
|
-
];
|
|
280
|
-
}
|
package/env-template.route.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import type { NextFunction, Request, Response } from '@teambit/express';
|
|
2
|
-
import type { ComponentUrlParams, RegisteredComponentRoute } from '@teambit/component';
|
|
3
|
-
import { noPreview, serverError } from '@teambit/ui-foundation.ui.pages.static-error';
|
|
4
|
-
import type { Logger } from '@teambit/logger';
|
|
5
|
-
|
|
6
|
-
import type { PreviewMain } from './preview.main.runtime';
|
|
7
|
-
import type { PreviewArtifact } from './preview-artifact';
|
|
8
|
-
import { getArtifactFileMiddleware, GetCacheControlFunc } from './artifact-file-middleware';
|
|
9
|
-
|
|
10
|
-
type UrlParams = ComponentUrlParams & {
|
|
11
|
-
filePath?: string;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
// Week for now
|
|
15
|
-
const CACHE_MAX_AGE = 60 * 60 * 24 * 7;
|
|
16
|
-
|
|
17
|
-
const getCacheControl: GetCacheControlFunc = (_filePath: string, _contents: string, mimeType?: string | null) => {
|
|
18
|
-
// Do not cache the html files
|
|
19
|
-
if (mimeType && mimeType === 'text/html') {
|
|
20
|
-
return undefined;
|
|
21
|
-
}
|
|
22
|
-
return `private, max-age=${CACHE_MAX_AGE}`;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export class EnvTemplateRoute implements RegisteredComponentRoute {
|
|
26
|
-
constructor(
|
|
27
|
-
/**
|
|
28
|
-
* preview extension.
|
|
29
|
-
*/
|
|
30
|
-
private preview: PreviewMain,
|
|
31
|
-
private logger: Logger
|
|
32
|
-
) {}
|
|
33
|
-
|
|
34
|
-
route = `/env-template/:previewName/:filePath(*)`;
|
|
35
|
-
method = 'get';
|
|
36
|
-
|
|
37
|
-
// Since we might give it a core env id
|
|
38
|
-
// Then in the component route when we do host.get(id) it will fail, as we don't have the core envs in the scope/workspace
|
|
39
|
-
resolveComponent = false;
|
|
40
|
-
|
|
41
|
-
// @ts-ignore
|
|
42
|
-
middlewares = [
|
|
43
|
-
async (req: Request<UrlParams>, res: Response, next: NextFunction) => {
|
|
44
|
-
try {
|
|
45
|
-
// @ts-ignore TODO: @guy please fix.
|
|
46
|
-
// const component = req.component as Component | undefined;
|
|
47
|
-
// if (!component) return res.status(404).send(noPreview());
|
|
48
|
-
|
|
49
|
-
let artifact: PreviewArtifact | undefined;
|
|
50
|
-
// TODO - prevent error `getVinylsAndImportIfMissing is not a function` #4680
|
|
51
|
-
try {
|
|
52
|
-
const { componentId: envId } = req.params;
|
|
53
|
-
artifact = await this.preview.getEnvTemplateByEnvId(envId);
|
|
54
|
-
} catch (e: any) {
|
|
55
|
-
this.logger.error(`getEnvTemplateByEnvId has failed`, e);
|
|
56
|
-
return res.status(404).send(noPreview());
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// @ts-ignore
|
|
60
|
-
req.artifact = artifact;
|
|
61
|
-
// @ts-ignore
|
|
62
|
-
req.isLegacyPath = false;
|
|
63
|
-
|
|
64
|
-
return next();
|
|
65
|
-
} catch (e: any) {
|
|
66
|
-
this.logger.error('failed getting preview', e);
|
|
67
|
-
return res.status(500).send(serverError());
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
getArtifactFileMiddleware(this.logger, getCacheControl),
|
|
71
|
-
];
|
|
72
|
-
}
|
package/execution-ref.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Component, ComponentID } from '@teambit/component';
|
|
2
|
-
import type { ExecutionContext } from '@teambit/envs';
|
|
3
|
-
|
|
4
|
-
// TODO - use workspace.list() instead of this
|
|
5
|
-
export class ExecutionRef {
|
|
6
|
-
constructor(public executionCtx: ExecutionContext) {
|
|
7
|
-
this.currentComponents = executionCtx.components;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
currentComponents: Component[];
|
|
11
|
-
|
|
12
|
-
add(added: Component) {
|
|
13
|
-
this.currentComponents = this.currentComponents.concat(added);
|
|
14
|
-
}
|
|
15
|
-
remove(removed: ComponentID) {
|
|
16
|
-
this.currentComponents = this.currentComponents.filter((c) => c.id.toString() !== removed.toString());
|
|
17
|
-
}
|
|
18
|
-
update(next: Component) {
|
|
19
|
-
this.currentComponents = this.currentComponents.map((c) => (c.equals(next) ? next : c));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
get(id: ComponentID) {
|
|
23
|
-
return this.currentComponents.find((x) => x.id.isEqual(id));
|
|
24
|
-
}
|
|
25
|
-
}
|
package/generate-link.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { toWindowsCompatiblePath } from '@teambit/toolbox.path.to-windows-compatible-path';
|
|
2
|
-
import camelcase from 'camelcase';
|
|
3
|
-
import type { ComponentMap } from '@teambit/component';
|
|
4
|
-
|
|
5
|
-
export type MainModulesMap = {
|
|
6
|
-
/**
|
|
7
|
-
* Path to default module in case there is no specific module for the current environment.
|
|
8
|
-
*/
|
|
9
|
-
default: string;
|
|
10
|
-
[envId: string]: string;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
// :TODO refactor to building an AST and generate source code based on it.
|
|
14
|
-
export function generateLink(
|
|
15
|
-
prefix: string,
|
|
16
|
-
componentMap: ComponentMap<string[]>,
|
|
17
|
-
mainModulesMap?: MainModulesMap,
|
|
18
|
-
isSplitComponentBundle = false
|
|
19
|
-
): string {
|
|
20
|
-
const links = componentMap.toArray().map(([component, modulePath], compIdx) => ({
|
|
21
|
-
componentIdentifier: component.id.fullName,
|
|
22
|
-
modules: modulePath.map((path, pathIdx) => ({
|
|
23
|
-
varName: moduleVarName(compIdx, pathIdx),
|
|
24
|
-
resolveFrom: toWindowsCompatiblePath(path),
|
|
25
|
-
})),
|
|
26
|
-
}));
|
|
27
|
-
|
|
28
|
-
let modulesLinks;
|
|
29
|
-
if (mainModulesMap) {
|
|
30
|
-
modulesLinks = Object.entries(mainModulesMap).map(([envId, path]) => {
|
|
31
|
-
const resolveFrom = toWindowsCompatiblePath(path);
|
|
32
|
-
const varName = getEnvVarName(envId);
|
|
33
|
-
return { envId, varName, resolveFrom };
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return `
|
|
38
|
-
import { linkModules } from '${toWindowsCompatiblePath(require.resolve('./preview.preview.runtime'))}';
|
|
39
|
-
|
|
40
|
-
${links
|
|
41
|
-
.map((link) => link.modules.map((module) => `import * as ${module.varName} from "${module.resolveFrom}";`).join('\n'))
|
|
42
|
-
.filter((line) => line !== '') // prevent empty lines
|
|
43
|
-
.join('\n')}
|
|
44
|
-
|
|
45
|
-
${modulesLinks.map((module) => `import * as ${module.varName} from "${module.resolveFrom}";`).join('\n')}
|
|
46
|
-
|
|
47
|
-
linkModules('${prefix}', {
|
|
48
|
-
modulesMap: {
|
|
49
|
-
${modulesLinks
|
|
50
|
-
// must include all components, including empty
|
|
51
|
-
.map((module) => `"${module.envId}": ${module.varName}`)
|
|
52
|
-
.join(',\n ')}
|
|
53
|
-
},
|
|
54
|
-
isSplitComponentBundle: ${isSplitComponentBundle},
|
|
55
|
-
componentMap: {
|
|
56
|
-
${links
|
|
57
|
-
// must include all components, including empty
|
|
58
|
-
.map((link) => ` "${link.componentIdentifier}": [${link.modules.map((module) => module.varName).join(', ')}]`)
|
|
59
|
-
.join(',\n')}
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
`;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function moduleVarName(componentIdx: number, fileIdx: number) {
|
|
66
|
-
return `file_${componentIdx}_${fileIdx}`;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function getEnvVarName(envId: string) {
|
|
70
|
-
const envNameFormatted = camelcase(envId.replace('@', '').replace('.', '-').replace(/\//g, '-'));
|
|
71
|
-
const varName = `${envNameFormatted}MainModule`;
|
|
72
|
-
return varName;
|
|
73
|
-
}
|
package/index.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export { PreviewAspect as default, PreviewAspect, PreviewRuntime } from './preview.aspect';
|
|
2
|
-
|
|
3
|
-
export * from './events';
|
|
4
|
-
export type { PreviewEnv, Preview } from './preview-env';
|
|
5
|
-
export type {
|
|
6
|
-
PreviewMain,
|
|
7
|
-
EnvPreviewConfig,
|
|
8
|
-
ComponentPreviewSize,
|
|
9
|
-
PreviewStrategyName,
|
|
10
|
-
PreviewFiles,
|
|
11
|
-
ComponentPreviewMetaData,
|
|
12
|
-
} from './preview.main.runtime';
|
|
13
|
-
export type { PreviewPreview, RenderingContextOptions, RenderingContextProvider } from './preview.preview.runtime';
|
|
14
|
-
export type { PreviewDefinition } from './preview-definition';
|
|
15
|
-
export type { PreviewModule, ModuleFile } from './types/preview-module';
|
|
16
|
-
export type { RenderingContext } from './rendering-context';
|
|
17
|
-
// Exporting directly from the inner file to prevent breaking the bundling process
|
|
18
|
-
export { ENV_PREVIEW_STRATEGY_NAME, COMPONENT_PREVIEW_STRATEGY_NAME } from './strategies/strategies-names';
|
package/mk-temp-dir.ts
DELETED
package/preview-artifact.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { AbstractVinyl } from '@teambit/legacy/dist/consumer/component/sources';
|
|
2
|
-
import { pathNormalizeToLinux } from '@teambit/legacy/dist/utils';
|
|
3
|
-
import { uniq } from 'lodash';
|
|
4
|
-
|
|
5
|
-
export class PreviewArtifact {
|
|
6
|
-
constructor(private artifacts: AbstractVinyl[]) {}
|
|
7
|
-
|
|
8
|
-
getPaths() {
|
|
9
|
-
// TODO: check why the artifacts stored twice, then remove this uniq here
|
|
10
|
-
return uniq(this.artifacts.map((artifact) => artifact.relative));
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
getFile(path: string) {
|
|
14
|
-
return this.artifacts.find((file) => {
|
|
15
|
-
return pathNormalizeToLinux(file.relative) === path;
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
getFileEndsWith(path: string) {
|
|
20
|
-
return this.artifacts.find((file) => {
|
|
21
|
-
return pathNormalizeToLinux(file.relative).endsWith(path);
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
}
|
package/preview-assets.route.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { Request, Response, Route } from '@teambit/express';
|
|
2
|
-
import type { Component } from '@teambit/component';
|
|
3
|
-
import { serverError } from '@teambit/ui-foundation.ui.pages.static-error';
|
|
4
|
-
import type { Logger } from '@teambit/logger';
|
|
5
|
-
|
|
6
|
-
import { PreviewMain } from './preview.main.runtime';
|
|
7
|
-
|
|
8
|
-
export class PreviewAssetsRoute implements Route {
|
|
9
|
-
constructor(
|
|
10
|
-
/**
|
|
11
|
-
* preview extension.
|
|
12
|
-
*/
|
|
13
|
-
private preview: PreviewMain,
|
|
14
|
-
private logger: Logger
|
|
15
|
-
) {}
|
|
16
|
-
|
|
17
|
-
route = '/preview-assets';
|
|
18
|
-
method = 'get';
|
|
19
|
-
|
|
20
|
-
middlewares = [
|
|
21
|
-
async (req: Request, res: Response) => {
|
|
22
|
-
try {
|
|
23
|
-
// @ts-ignore TODO: @guy please fix.
|
|
24
|
-
const component = req.component as Component | undefined;
|
|
25
|
-
// if (!component) return res.status(404).send(noPreview());
|
|
26
|
-
if (!component) return res.status(404).jsonp({ error: 'not found' });
|
|
27
|
-
const result = await this.preview.getPreviewFiles(component);
|
|
28
|
-
if (!result) return res.status(404).jsonp({ error: 'not found' });
|
|
29
|
-
return res.json(result);
|
|
30
|
-
} catch (e: any) {
|
|
31
|
-
this.logger.error('failed getting preview assets', e);
|
|
32
|
-
return res.status(500).send(serverError());
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
];
|
|
36
|
-
}
|
package/preview-context.ts
DELETED
package/preview-definition.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import type { Component, ComponentMap } from '@teambit/component';
|
|
2
|
-
import type { Environment, ExecutionContext } from '@teambit/envs';
|
|
3
|
-
import type { AbstractVinyl } from '@teambit/legacy/dist/consumer/component/sources';
|
|
4
|
-
|
|
5
|
-
export interface PreviewDefinition {
|
|
6
|
-
/**
|
|
7
|
-
* extension preview prefix
|
|
8
|
-
*/
|
|
9
|
-
prefix: string;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* which other extension modules to include in the preview context.
|
|
13
|
-
*/
|
|
14
|
-
include?: string[];
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* path of the default template to be executed.
|
|
18
|
-
*/
|
|
19
|
-
renderTemplatePath: (context: ExecutionContext) => Promise<string | undefined>;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* get the template by env.
|
|
23
|
-
* TODO: refactor `renderTemplatePath` to accept only an env and remove this method.
|
|
24
|
-
*/
|
|
25
|
-
renderTemplatePathByEnv: (env: Environment) => Promise<string | undefined>;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* get all files to require in the preview runtime.
|
|
29
|
-
*/
|
|
30
|
-
getModuleMap(components: Component[]): Promise<ComponentMap<AbstractVinyl[]>>;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Whether to include the peers chunk in the output html
|
|
34
|
-
*/
|
|
35
|
-
includePeers?: boolean;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Get metadata for the preview
|
|
39
|
-
*/
|
|
40
|
-
getMetadata?: (component: Component) => Promise<unknown>;
|
|
41
|
-
}
|
package/preview-env.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { Bundler, BundlerContext, DevServer, DevServerContext } from '@teambit/bundler';
|
|
2
|
-
import { AsyncEnvHandler, EnvHandler } from '@teambit/envs';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* interface for implementing component previews
|
|
6
|
-
* using bit's development environments.
|
|
7
|
-
*/
|
|
8
|
-
export interface PreviewEnv {
|
|
9
|
-
preview(): EnvHandler<Preview>;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export type Preview = {
|
|
13
|
-
/**
|
|
14
|
-
* return an instance of a mounter.
|
|
15
|
-
*/
|
|
16
|
-
getMounter: () => string;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* return a path to a docs template.
|
|
20
|
-
*/
|
|
21
|
-
getDocsTemplate: () => string;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* return a dev server instance to use for previews.
|
|
25
|
-
*/
|
|
26
|
-
getDevServer: (context: DevServerContext) => EnvHandler<DevServer> | AsyncEnvHandler<DevServer>;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* return an instance for a preview bundler.
|
|
30
|
-
*/
|
|
31
|
-
getBundler: (context: BundlerContext) => EnvHandler<Bundler> | AsyncEnvHandler<Bundler>;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* return the id of the dev server.
|
|
35
|
-
* used for deduplication of dev servers
|
|
36
|
-
*/
|
|
37
|
-
getDevEnvId: () => string;
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* dependencies that will bundled as part of the env template and will configured as externals for the component bundle
|
|
41
|
-
* these dependencies will be available in the preview on the window.
|
|
42
|
-
* these dependencies will have only one instance on the page.
|
|
43
|
-
* for dev server these dependencies will be aliased
|
|
44
|
-
*/
|
|
45
|
-
getHostDependencies: () => string[];
|
|
46
|
-
};
|
package/preview-type.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { ComponentID } from '@teambit/component-id';
|
|
2
|
-
import { RenderingContext } from './rendering-context';
|
|
3
|
-
import { PreviewModule } from './types/preview-module';
|
|
4
|
-
|
|
5
|
-
export interface PreviewType {
|
|
6
|
-
/**
|
|
7
|
-
* preview name to register.
|
|
8
|
-
*/
|
|
9
|
-
name: string;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* preview render method.
|
|
13
|
-
*/
|
|
14
|
-
render(
|
|
15
|
-
componentId: ComponentID,
|
|
16
|
-
envId: string,
|
|
17
|
-
linkedModules: PreviewModule<any>,
|
|
18
|
-
includedPreviews: string[],
|
|
19
|
-
renderingContext: RenderingContext
|
|
20
|
-
): void;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* determine if this will be the default preview to render.
|
|
24
|
-
*/
|
|
25
|
-
default?: boolean;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* which other extension modules to include in the preview context.
|
|
29
|
-
*/
|
|
30
|
-
include?: string[];
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* select relevant information to show in preview context
|
|
34
|
-
*/
|
|
35
|
-
selectPreviewModel?: (componentId: string, module: PreviewModule) => any;
|
|
36
|
-
}
|
package/preview.aspect.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Aspect, RuntimeDefinition } from '@teambit/harmony';
|
|
2
|
-
|
|
3
|
-
export const PreviewRuntime = new RuntimeDefinition('preview');
|
|
4
|
-
|
|
5
|
-
export const PreviewAspect = Aspect.create({
|
|
6
|
-
id: 'teambit.preview/preview',
|
|
7
|
-
dependencies: [],
|
|
8
|
-
defaultConfig: {},
|
|
9
|
-
declareRuntime: PreviewRuntime,
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
export default PreviewAspect;
|
package/preview.graphql.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { Component } from '@teambit/component';
|
|
2
|
-
import gql from 'graphql-tag';
|
|
3
|
-
|
|
4
|
-
import { PreviewMain } from './preview.main.runtime';
|
|
5
|
-
|
|
6
|
-
export function previewSchema(previewExtension: PreviewMain) {
|
|
7
|
-
return {
|
|
8
|
-
typeDefs: gql`
|
|
9
|
-
type Preview {
|
|
10
|
-
# url: String!
|
|
11
|
-
"""
|
|
12
|
-
Check if the component supports scaling
|
|
13
|
-
"""
|
|
14
|
-
isScaling: Boolean
|
|
15
|
-
includesEnvTemplate: Boolean
|
|
16
|
-
legacyHeader: Boolean
|
|
17
|
-
skipIncludes: Boolean
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
extend type Component {
|
|
21
|
-
preview: Preview
|
|
22
|
-
}
|
|
23
|
-
`,
|
|
24
|
-
resolvers: {
|
|
25
|
-
Component: {
|
|
26
|
-
preview: (component: Component) => {
|
|
27
|
-
// return previewExtension.getPreview(component);
|
|
28
|
-
return { component };
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
Preview: {
|
|
32
|
-
includesEnvTemplate: ({ component }) => {
|
|
33
|
-
return previewExtension.isBundledWithEnv(component);
|
|
34
|
-
},
|
|
35
|
-
isScaling: ({ component }) => {
|
|
36
|
-
return previewExtension.doesScaling(component);
|
|
37
|
-
},
|
|
38
|
-
legacyHeader: ({ component }) => {
|
|
39
|
-
return previewExtension.isLegacyHeader(component);
|
|
40
|
-
},
|
|
41
|
-
skipIncludes: ({ component }) => {
|
|
42
|
-
// return true;
|
|
43
|
-
return previewExtension.isSupportSkipIncludes(component);
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
}
|
package/preview.route.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import type { NextFunction, Request, Response, Route } from '@teambit/express';
|
|
2
|
-
import type { Component } from '@teambit/component';
|
|
3
|
-
import { noPreview, serverError } from '@teambit/ui-foundation.ui.pages.static-error';
|
|
4
|
-
import type { Logger } from '@teambit/logger';
|
|
5
|
-
|
|
6
|
-
import { PreviewMain } from './preview.main.runtime';
|
|
7
|
-
import { PreviewArtifact } from './preview-artifact';
|
|
8
|
-
import { getArtifactFileMiddleware } from './artifact-file-middleware';
|
|
9
|
-
import type { PreviewUrlParams } from './artifact-file-middleware';
|
|
10
|
-
|
|
11
|
-
export class PreviewRoute implements Route {
|
|
12
|
-
constructor(
|
|
13
|
-
/**
|
|
14
|
-
* preview extension.
|
|
15
|
-
*/
|
|
16
|
-
private preview: PreviewMain,
|
|
17
|
-
private logger: Logger
|
|
18
|
-
) {}
|
|
19
|
-
|
|
20
|
-
route = `/preview/:previewName?/:filePath(*)`;
|
|
21
|
-
method = 'get';
|
|
22
|
-
|
|
23
|
-
middlewares = [
|
|
24
|
-
async (req: Request<PreviewUrlParams>, res: Response, next: NextFunction) => {
|
|
25
|
-
try {
|
|
26
|
-
// @ts-ignore TODO: @guy please fix.
|
|
27
|
-
const component = req.component as Component | undefined;
|
|
28
|
-
if (!component) return res.status(404).send(noPreview());
|
|
29
|
-
const isLegacyPath = await this.preview.isBundledWithEnv(component);
|
|
30
|
-
|
|
31
|
-
let artifact: PreviewArtifact | undefined;
|
|
32
|
-
// TODO - prevent error `getVinylsAndImportIfMissing is not a function` #4680
|
|
33
|
-
try {
|
|
34
|
-
// Taking the env template (in this case we will take the component only bundle throw component-preview route)
|
|
35
|
-
// We use this route for the env template for backward compatibility - new scopes which contain components tagged with old versions of bit
|
|
36
|
-
if (!isLegacyPath) {
|
|
37
|
-
artifact = await this.preview.getEnvTemplateFromComponentEnv(component);
|
|
38
|
-
} else {
|
|
39
|
-
// If it's legacy (bundled together with the env template) take the preview bundle from the component directly
|
|
40
|
-
artifact = await this.preview.getPreview(component);
|
|
41
|
-
}
|
|
42
|
-
} catch (e: any) {
|
|
43
|
-
this.logger.error(`getEnvTemplateFromComponentEnv or getPreview has failed`, e);
|
|
44
|
-
return res.status(404).send(noPreview());
|
|
45
|
-
}
|
|
46
|
-
// @ts-ignore
|
|
47
|
-
req.artifact = artifact;
|
|
48
|
-
// @ts-ignore
|
|
49
|
-
req.isLegacyPath = isLegacyPath;
|
|
50
|
-
return next();
|
|
51
|
-
} catch (e: any) {
|
|
52
|
-
this.logger.error('failed getting preview', e);
|
|
53
|
-
return res.status(500).send(serverError());
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
getArtifactFileMiddleware(this.logger),
|
|
57
|
-
];
|
|
58
|
-
}
|
package/preview.task.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { resolve, join } from 'path';
|
|
2
|
-
import { ExecutionContext } from '@teambit/envs';
|
|
3
|
-
import { BuildContext, BuiltTaskResult, BuildTask, TaskLocation, CAPSULE_ARTIFACTS_DIR } from '@teambit/builder';
|
|
4
|
-
import { Bundler, BundlerContext, BundlerMain, Target } from '@teambit/bundler';
|
|
5
|
-
import { Compiler } from '@teambit/compiler';
|
|
6
|
-
import { ComponentMap } from '@teambit/component';
|
|
7
|
-
import { Capsule } from '@teambit/isolator';
|
|
8
|
-
import { AbstractVinyl } from '@teambit/legacy/dist/consumer/component/sources';
|
|
9
|
-
import { DependencyResolverMain } from '@teambit/dependency-resolver';
|
|
10
|
-
import { Logger } from '@teambit/logger';
|
|
11
|
-
import { PreviewMain } from './preview.main.runtime';
|
|
12
|
-
|
|
13
|
-
export const PREVIEW_TASK_NAME = 'GeneratePreview';
|
|
14
|
-
export class PreviewTask implements BuildTask {
|
|
15
|
-
constructor(
|
|
16
|
-
/**
|
|
17
|
-
* bundler extension.
|
|
18
|
-
*/
|
|
19
|
-
private bundler: BundlerMain,
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* preview extension.
|
|
23
|
-
*/
|
|
24
|
-
private preview: PreviewMain,
|
|
25
|
-
|
|
26
|
-
private dependencyResolver: DependencyResolverMain,
|
|
27
|
-
private logger: Logger
|
|
28
|
-
) {}
|
|
29
|
-
|
|
30
|
-
aspectId = 'teambit.preview/preview';
|
|
31
|
-
name = PREVIEW_TASK_NAME;
|
|
32
|
-
description = 'Bundling components for preview';
|
|
33
|
-
location: TaskLocation = 'end';
|
|
34
|
-
// readonly dependencies = [CompilerAspect.id];
|
|
35
|
-
|
|
36
|
-
async execute(context: BuildContext): Promise<BuiltTaskResult> {
|
|
37
|
-
const defs = this.preview.getDefs();
|
|
38
|
-
const url = `/preview/${context.envRuntime.id}`;
|
|
39
|
-
const bundlingStrategy = this.preview.getBundlingStrategy(context.env);
|
|
40
|
-
const envPreviewConfig = this.preview.getEnvPreviewConfig(context.env);
|
|
41
|
-
const splitComponentBundle = envPreviewConfig.splitComponentBundle ?? false;
|
|
42
|
-
const computeTargetsContext = Object.assign(context, { splitComponentBundle });
|
|
43
|
-
|
|
44
|
-
const targets: Target[] = await bundlingStrategy.computeTargets(computeTargetsContext, defs, this);
|
|
45
|
-
|
|
46
|
-
const bundlerContext: BundlerContext = Object.assign(context, {
|
|
47
|
-
targets,
|
|
48
|
-
compress: bundlingStrategy.name !== 'env' && splitComponentBundle,
|
|
49
|
-
entry: [],
|
|
50
|
-
publicPath: this.getPreviewDirectory(context),
|
|
51
|
-
rootPath: url,
|
|
52
|
-
development: context.dev,
|
|
53
|
-
metaData: {
|
|
54
|
-
initiator: `${PREVIEW_TASK_NAME} task`,
|
|
55
|
-
envId: context.id,
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
const bundler: Bundler = await context.env.getBundler(bundlerContext);
|
|
60
|
-
const bundlerResults = await bundler.run();
|
|
61
|
-
|
|
62
|
-
const results = bundlingStrategy.computeResults(bundlerContext, bundlerResults, this);
|
|
63
|
-
return results;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
getLinkFileDirectory() {
|
|
67
|
-
return join(CAPSULE_ARTIFACTS_DIR, 'preview-links');
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
getPreviewDirectory(context: ExecutionContext) {
|
|
71
|
-
const outputPath = resolve(`${context.id}/public`);
|
|
72
|
-
return outputPath;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
getPathsFromMap(
|
|
76
|
-
capsule: Capsule,
|
|
77
|
-
moduleMap: ComponentMap<AbstractVinyl[]>,
|
|
78
|
-
context: BuildContext
|
|
79
|
-
): ComponentMap<string[]> {
|
|
80
|
-
const compiler: Compiler = context.env.getCompiler(context);
|
|
81
|
-
return moduleMap.map((files) => {
|
|
82
|
-
return files.map((file) => join(capsule.path, compiler.getDistPathBySrcPath(file.relative)));
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
package/preview.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Bundler, BundlerContext, DevServer, DevServerContext } from '@teambit/bundler';
|
|
2
|
-
|
|
3
|
-
export interface Preview {
|
|
4
|
-
/**
|
|
5
|
-
* get a dev server instance of the.
|
|
6
|
-
*/
|
|
7
|
-
getDevServer(context: DevServerContext): DevServer;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* get bundler instance.
|
|
11
|
-
*/
|
|
12
|
-
getBundler(context: BundlerContext): Bundler;
|
|
13
|
-
}
|
package/rendering-context.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { RenderingContextSlot } from './preview.preview.runtime';
|
|
2
|
-
|
|
3
|
-
export type RenderingContextOptions = { aspectsFilter?: string[] };
|
|
4
|
-
export type RenderingContextProvider = (options: RenderingContextOptions) => { [key: string]: any };
|
|
5
|
-
|
|
6
|
-
export class RenderingContext {
|
|
7
|
-
constructor(private contexts: RenderingContextSlot, private options: RenderingContextOptions = {}) {}
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* obtain rendering context of a specific aspect.
|
|
11
|
-
*/
|
|
12
|
-
get(aspectId: string) {
|
|
13
|
-
const contextFactory = this.contexts.get(aspectId);
|
|
14
|
-
return contextFactory?.(this.options);
|
|
15
|
-
}
|
|
16
|
-
}
|
package/size-event.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { BitBaseEvent } from '@teambit/pubsub';
|
|
2
|
-
|
|
3
|
-
export type SizeEventType = {
|
|
4
|
-
height: number;
|
|
5
|
-
width: number;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export class SizeEvent extends BitBaseEvent<SizeEventType> {
|
|
9
|
-
static readonly TYPE = 'preview-size';
|
|
10
|
-
|
|
11
|
-
constructor(sizeEvent: SizeEventType) {
|
|
12
|
-
super(SizeEvent.TYPE, '0.0.1', new Date().getTime(), sizeEvent);
|
|
13
|
-
}
|
|
14
|
-
}
|