1 | import path from 'path';
|
2 | import { dashToPascalCase, normalizePath, readPackageJson, relativeImport, sortBy } from './utils';
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | export async function reactProxyOutput(config, compilerCtx, outputTarget, components) {
|
11 | const filteredComponents = getFilteredComponents(outputTarget.excludeComponents, components);
|
12 | const rootDir = config.rootDir;
|
13 | const pkgData = await readPackageJson(rootDir);
|
14 | const finalText = generateProxies(config, filteredComponents, pkgData, outputTarget, rootDir);
|
15 | await compilerCtx.fs.writeFile(outputTarget.proxiesFile, finalText);
|
16 | await copyResources(config, outputTarget);
|
17 | }
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | function getFilteredComponents(excludeComponents = [], cmps) {
|
25 | return sortBy(cmps, (cmp) => cmp.tagName).filter((c) => !excludeComponents.includes(c.tagName) && !c.internal);
|
26 | }
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 | export function generateProxies(config, components, pkgData, outputTarget, rootDir) {
|
37 | const distTypesDir = path.dirname(pkgData.types);
|
38 | const dtsFilePath = path.join(rootDir, distTypesDir, GENERATED_DTS);
|
39 | const componentsTypeFile = relativeImport(outputTarget.proxiesFile, dtsFilePath, '.d.ts');
|
40 | const pathToCorePackageLoader = getPathToCorePackageLoader(config, outputTarget);
|
41 | const imports = `/* eslint-disable */
|
42 | /* tslint:disable */
|
43 | /* auto-generated react proxies */
|
44 | import { createReactComponent } from './react-component-lib';\n`;
|
45 | |
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 | const generateTypeImports = () => {
|
52 | if (outputTarget.componentCorePackage !== undefined) {
|
53 | const dirPath = outputTarget.includeImportCustomElements ? `/${outputTarget.customElementsDir || 'components'}` : '';
|
54 | return `import type { ${IMPORT_TYPES} } from '${normalizePath(outputTarget.componentCorePackage)}${dirPath}';\n`;
|
55 | }
|
56 | return `import type { ${IMPORT_TYPES} } from '${normalizePath(componentsTypeFile)}';\n`;
|
57 | };
|
58 | const typeImports = generateTypeImports();
|
59 | let sourceImports = '';
|
60 | let registerCustomElements = '';
|
61 | |
62 |
|
63 |
|
64 |
|
65 |
|
66 | if (outputTarget.includeImportCustomElements && outputTarget.componentCorePackage !== undefined) {
|
67 | const cmpImports = components.map(component => {
|
68 | const pascalImport = dashToPascalCase(component.tagName);
|
69 | return `import { defineCustomElement as define${pascalImport} } from '${normalizePath(outputTarget.componentCorePackage)}/${outputTarget.customElementsDir ||
|
70 | 'components'}/${component.tagName}.js';`;
|
71 | });
|
72 | sourceImports = cmpImports.join('\n');
|
73 | }
|
74 | else if (outputTarget.includePolyfills && outputTarget.includeDefineCustomElements) {
|
75 | sourceImports = `import { ${APPLY_POLYFILLS}, ${REGISTER_CUSTOM_ELEMENTS} } from '${pathToCorePackageLoader}';\n`;
|
76 | registerCustomElements = `${APPLY_POLYFILLS}().then(() => ${REGISTER_CUSTOM_ELEMENTS}());`;
|
77 | }
|
78 | else if (!outputTarget.includePolyfills && outputTarget.includeDefineCustomElements) {
|
79 | sourceImports = `import { ${REGISTER_CUSTOM_ELEMENTS} } from '${pathToCorePackageLoader}';\n`;
|
80 | registerCustomElements = `${REGISTER_CUSTOM_ELEMENTS}();`;
|
81 | }
|
82 | const final = [
|
83 | imports,
|
84 | typeImports,
|
85 | sourceImports,
|
86 | registerCustomElements,
|
87 | components.map(cmpMeta => createComponentDefinition(cmpMeta, outputTarget.includeImportCustomElements)).join('\n'),
|
88 | ];
|
89 | return final.join('\n') + '\n';
|
90 | }
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 | export function createComponentDefinition(cmpMeta, includeCustomElement = false) {
|
99 | const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
|
100 | let template = `export const ${tagNameAsPascal} = /*@__PURE__*/createReactComponent<${IMPORT_TYPES}.${tagNameAsPascal}, HTML${tagNameAsPascal}Element>('${cmpMeta.tagName}'`;
|
101 | if (includeCustomElement) {
|
102 | template += `, undefined, undefined, define${tagNameAsPascal}`;
|
103 | }
|
104 | template += `);`;
|
105 | return [
|
106 | template
|
107 | ];
|
108 | }
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 |
|
116 | async function copyResources(config, outputTarget) {
|
117 | if (!config.sys || !config.sys.copy || !config.sys.glob) {
|
118 | throw new Error('stencil is not properly initialized at this step. Notify the developer');
|
119 | }
|
120 | const srcDirectory = path.join(__dirname, '..', 'react-component-lib');
|
121 | const destDirectory = path.join(path.dirname(outputTarget.proxiesFile), 'react-component-lib');
|
122 | return config.sys.copy([
|
123 | {
|
124 | src: srcDirectory,
|
125 | dest: destDirectory,
|
126 | keepDirStructure: false,
|
127 | warn: false,
|
128 | },
|
129 | ], srcDirectory);
|
130 | }
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 | export function getPathToCorePackageLoader(config, outputTarget) {
|
138 | var _a;
|
139 | const basePkg = outputTarget.componentCorePackage || '';
|
140 | const distOutputTarget = (_a = config.outputTargets) === null || _a === void 0 ? void 0 : _a.find((o) => o.type === 'dist');
|
141 | const distAbsEsmLoaderPath = (distOutputTarget === null || distOutputTarget === void 0 ? void 0 : distOutputTarget.esmLoaderPath) && path.isAbsolute(distOutputTarget.esmLoaderPath)
|
142 | ? distOutputTarget.esmLoaderPath
|
143 | : null;
|
144 | const distRelEsmLoaderPath = config.rootDir && distAbsEsmLoaderPath
|
145 | ? path.relative(config.rootDir, distAbsEsmLoaderPath)
|
146 | : null;
|
147 | const loaderDir = outputTarget.loaderDir || distRelEsmLoaderPath || DEFAULT_LOADER_DIR;
|
148 | return normalizePath(path.join(basePkg, loaderDir));
|
149 | }
|
150 | export const GENERATED_DTS = 'components.d.ts';
|
151 | const IMPORT_TYPES = 'JSX';
|
152 | const REGISTER_CUSTOM_ELEMENTS = 'defineCustomElements';
|
153 | const APPLY_POLYFILLS = 'applyPolyfills';
|
154 | const DEFAULT_LOADER_DIR = '/dist/loader';
|