diff options
author | 2021-03-23 13:47:54 -0400 | |
---|---|---|
committer | 2021-03-23 13:47:54 -0400 | |
commit | 854d0feb34f605c0fe3f5627a261e327164c449e (patch) | |
tree | c7d88676affbd271fd6304a73d98c149e265f042 /src/codegen/index.ts | |
parent | 3f16550765cccee0de8f2f6e5451bf41aec13601 (diff) | |
download | astro-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.ts | 50 |
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')}')`, |