summaryrefslogtreecommitdiff
path: root/src/codegen/index.ts
diff options
context:
space:
mode:
authorGravatar Matthew Phillips <matthew@matthewphillips.info> 2021-03-23 13:47:54 -0400
committerGravatar GitHub <noreply@github.com> 2021-03-23 13:47:54 -0400
commit854d0feb34f605c0fe3f5627a261e327164c449e (patch)
treec7d88676affbd271fd6304a73d98c149e265f042 /src/codegen/index.ts
parent3f16550765cccee0de8f2f6e5451bf41aec13601 (diff)
downloadastro-854d0feb34f605c0fe3f5627a261e327164c449e.tar.gz
astro-854d0feb34f605c0fe3f5627a261e327164c449e.tar.zst
astro-854d0feb34f605c0fe3f5627a261e327164c449e.zip
Add support for React components. (#18)
* Add support for React components. This adds support for react components via a new `extensions` config in astro.config.mjs. In the future we can extend this to do things like look at the import statements, as Snowpack does. * Fix the tests
Diffstat (limited to 'src/codegen/index.ts')
-rw-r--r--src/codegen/index.ts50
1 files changed, 44 insertions, 6 deletions
diff --git a/src/codegen/index.ts b/src/codegen/index.ts
index 725546f51..a9fc433f4 100644
--- a/src/codegen/index.ts
+++ b/src/codegen/index.ts
@@ -1,4 +1,5 @@
import type { CompileOptions } from '../@types/compiler';
+import type { ValidExtensionPlugins } from '../@types/astro';
import type { Ast, TemplateNode } from '../compiler/interfaces';
import type { JsxItem, TransformResult } from '../@types/astro';
@@ -89,10 +90,34 @@ function generateAttributes(attrs: Record<string, string>): string {
return result + '}';
}
-function getComponentWrapper(_name: string, { type, url }: { type: string; url: string }, { resolve }: CompileOptions) {
+interface ComponentInfo {
+ type: string;
+ url: string;
+}
+
+const defaultExtensions: Readonly<Record<string, ValidExtensionPlugins>> = {
+ '.hmx': 'hmx',
+ '.jsx': 'react',
+ '.vue': 'vue',
+ '.svelte': 'svelte'
+};
+
+function getComponentWrapper(_name: string, { type, url }: ComponentInfo, compileOptions: CompileOptions) {
+ const {
+ resolve,
+ extensions = defaultExtensions
+ } = compileOptions;
+
const [name, kind] = _name.split(':');
- switch (type) {
- case '.hmx': {
+
+ const plugin = extensions[type] || defaultExtensions[type];
+
+ if(!plugin) {
+ throw new Error(`No supported plugin found for extension ${type}`);
+ }
+
+ switch (plugin) {
+ case 'hmx': {
if (kind) {
throw new Error(`HMX does not support :${kind}`);
}
@@ -101,7 +126,7 @@ function getComponentWrapper(_name: string, { type, url }: { type: string; url:
wrapperImport: ``,
};
}
- case '.jsx': {
+ case 'preact': {
if (kind === 'dynamic') {
return {
wrapper: `__preact_dynamic(${name}, new URL(${JSON.stringify(url.replace(/\.[^.]+$/, '.js'))}, \`http://TEST\${import.meta.url}\`).pathname, '${resolve('preact')}')`,
@@ -114,7 +139,20 @@ function getComponentWrapper(_name: string, { type, url }: { type: string; url:
};
}
}
- case '.svelte': {
+ case 'react': {
+ if (kind === 'dynamic') {
+ return {
+ wrapper: `__react_dynamic(${name}, new URL(${JSON.stringify(url.replace(/\.[^.]+$/, '.js'))}, \`http://TEST\${import.meta.url}\`).pathname, '${resolve('react')}', '${resolve('react-dom')}')`,
+ wrapperImport: `import {__react_dynamic} from '${internalImport('render/react.js')}';`,
+ };
+ } else {
+ return {
+ wrapper: `__react_static(${name})`,
+ wrapperImport: `import {__react_static} from '${internalImport('render/react.js')}';`,
+ };
+ }
+ }
+ case 'svelte': {
if (kind === 'dynamic') {
return {
wrapper: `__svelte_dynamic(${name}, new URL(${JSON.stringify(url.replace(/\.[^.]+$/, '.svelte.js'))}, \`http://TEST\${import.meta.url}\`).pathname)`,
@@ -127,7 +165,7 @@ function getComponentWrapper(_name: string, { type, url }: { type: string; url:
};
}
}
- case '.vue': {
+ case 'vue': {
if (kind === 'dynamic') {
return {
wrapper: `__vue_dynamic(${name}, new URL(${JSON.stringify(url.replace(/\.[^.]+$/, '.vue.js'))}, \`http://TEST\${import.meta.url}\`).pathname, '${resolve('vue')}')`,