summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Matthew Phillips <matthew@skypack.dev> 2022-09-15 09:50:48 -0400
committerGravatar GitHub <noreply@github.com> 2022-09-15 09:50:48 -0400
commitfc885eaea1f08429599c0ab4697ab6382f3d7fa4 (patch)
treeb52766a3a1e5f06be95ab0fa96ae96670640ae8e
parent0398efa39f14f40e77dc8e87f08e9f100a0fef34 (diff)
downloadastro-fc885eaea1f08429599c0ab4697ab6382f3d7fa4.tar.gz
astro-fc885eaea1f08429599c0ab4697ab6382f3d7fa4.tar.zst
astro-fc885eaea1f08429599c0ab4697ab6382f3d7fa4.zip
Read jsxImportSource from tsconfig (#4759)
* Read jsxImportSource from tsconfig * Only read from tsconfig if not found earlier
-rw-r--r--.changeset/tricky-cats-drop.md5
-rw-r--r--packages/astro/src/@types/astro.ts3
-rw-r--r--packages/astro/src/core/config.ts16
-rw-r--r--packages/astro/src/vite-plugin-config-alias/index.ts24
-rw-r--r--packages/astro/src/vite-plugin-jsx/index.ts11
-rw-r--r--packages/astro/test/fixtures/react-and-solid/astro.config.mjs7
-rw-r--r--packages/astro/test/fixtures/react-and-solid/package.json8
-rw-r--r--packages/astro/test/fixtures/react-and-solid/src/components/ExampleReact.tsx6
-rw-r--r--packages/astro/test/fixtures/react-and-solid/src/components/ExampleSolid.tsx5
-rw-r--r--packages/astro/test/fixtures/react-and-solid/src/pages/index.astro13
-rw-r--r--packages/astro/test/fixtures/react-and-solid/tsconfig.json7
-rw-r--r--packages/astro/test/react-and-solid.test.js20
-rw-r--r--pnpm-lock.yaml10
13 files changed, 118 insertions, 17 deletions
diff --git a/.changeset/tricky-cats-drop.md b/.changeset/tricky-cats-drop.md
new file mode 100644
index 000000000..53ea749bf
--- /dev/null
+++ b/.changeset/tricky-cats-drop.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Read jsxImportSource from tsconfig
diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts
index c358d63e7..817467a30 100644
--- a/packages/astro/src/@types/astro.ts
+++ b/packages/astro/src/@types/astro.ts
@@ -9,6 +9,7 @@ import type {
} from '@astrojs/markdown-remark';
import type * as babel from '@babel/core';
import type { AddressInfo } from 'net';
+import type { TsConfigJson } from 'tsconfig-resolver';
import type * as vite from 'vite';
import { z } from 'zod';
import type { SerializedSSRManifest } from '../core/app/types';
@@ -876,6 +877,8 @@ export interface AstroConfig extends z.output<typeof AstroConfigSchema> {
// that is different from the user-exposed configuration.
// TODO: Create an AstroConfig class to manage this, long-term.
_ctx: {
+ tsConfig: TsConfigJson | undefined;
+ tsConfigPath: string | undefined;
pageExtensions: string[];
injectedRoutes: InjectedRoute[];
adapter: AstroAdapter | undefined;
diff --git a/packages/astro/src/core/config.ts b/packages/astro/src/core/config.ts
index 611584b76..3aa820835 100644
--- a/packages/astro/src/core/config.ts
+++ b/packages/astro/src/core/config.ts
@@ -11,6 +11,7 @@ import * as colors from 'kleur/colors';
import path from 'path';
import postcssrc from 'postcss-load-config';
import { BUNDLED_THEMES } from 'shiki';
+import * as tsr from 'tsconfig-resolver';
import { fileURLToPath, pathToFileURL } from 'url';
import * as vite from 'vite';
import { mergeConfig as mergeViteConfig } from 'vite';
@@ -345,11 +346,14 @@ export async function validateConfig(
.optional()
.default({}),
});
+ const tsconfig = loadTSConfig(root);
// First-Pass Validation
const result = {
...(await AstroConfigRelativeSchema.parseAsync(userConfig)),
_ctx: {
pageExtensions: ['.astro', '.md', '.html'],
+ tsConfig: tsconfig?.config,
+ tsConfigPath: tsconfig?.path,
scripts: [],
renderers: [jsxRenderer],
injectedRoutes: [],
@@ -550,6 +554,18 @@ async function tryLoadConfig(
}
}
+function loadTSConfig(
+ cwd: string | undefined
+): tsr.TsConfigResult | undefined {
+ for(const searchName of ['tsconfig.json', 'jsconfig.json']) {
+ const config = tsr.tsconfigResolverSync({ cwd, searchName });
+ if(config.exists) {
+ return config;
+ }
+ }
+ return undefined
+}
+
/**
* Attempt to load an `astro.config.mjs` file
* @deprecated
diff --git a/packages/astro/src/vite-plugin-config-alias/index.ts b/packages/astro/src/vite-plugin-config-alias/index.ts
index 782cacc41..62f5abd98 100644
--- a/packages/astro/src/vite-plugin-config-alias/index.ts
+++ b/packages/astro/src/vite-plugin-config-alias/index.ts
@@ -1,6 +1,4 @@
import * as path from 'path';
-import * as tsr from 'tsconfig-resolver';
-import * as url from 'url';
import type { AstroConfig } from '../@types/astro';
import type * as vite from 'vite';
@@ -14,33 +12,25 @@ export declare interface Alias {
/** Returns a path with its slashes replaced with posix slashes. */
const normalize = (pathname: string) => String(pathname).split(path.sep).join(path.posix.sep);
-/** Returns the results of a config file if it exists, otherwise null. */
-const getExistingConfig = (
- searchName: string,
- cwd: string | undefined
-): tsr.TsConfigResultSuccess | null => {
- const config = tsr.tsconfigResolverSync({ cwd, searchName });
-
- return config.exists ? config : null;
-};
/** Returns a list of compiled aliases. */
-const getConfigAlias = (cwd: string | undefined): Alias[] | null => {
+const getConfigAlias = (astroConfig: AstroConfig): Alias[] | null => {
/** Closest tsconfig.json or jsconfig.json */
- const config = getExistingConfig('tsconfig.json', cwd) || getExistingConfig('jsconfig.json', cwd);
+ const config = astroConfig._ctx.tsConfig;
+ const configPath = astroConfig._ctx.tsConfigPath;
// if no config was found, return null
- if (!config) return null;
+ if (!config || !configPath) return null;
/** Compiler options from tsconfig.json or jsconfig.json. */
- const compilerOptions = Object(config.config.compilerOptions);
+ const compilerOptions = Object(config.compilerOptions);
// if no compilerOptions.baseUrl was defined, return null
if (!compilerOptions.baseUrl) return null;
// resolve the base url from the configuration file directory
const baseUrl = path.posix.resolve(
- path.posix.dirname(normalize(config.path).replace(/^\/?/, '/')),
+ path.posix.dirname(normalize(configPath).replace(/^\/?/, '/')),
normalize(compilerOptions.baseUrl)
);
@@ -93,7 +83,7 @@ export default function configAliasVitePlugin({
config: AstroConfig;
}): vite.PluginOption {
/** Aliases from the tsconfig.json or jsconfig.json configuration. */
- const configAlias = getConfigAlias(astroConfig.root && url.fileURLToPath(astroConfig.root));
+ const configAlias = getConfigAlias(astroConfig);
// if no config alias was found, bypass this plugin
if (!configAlias) return {} as vite.PluginOption;
diff --git a/packages/astro/src/vite-plugin-jsx/index.ts b/packages/astro/src/vite-plugin-jsx/index.ts
index 3c166bf98..9f42b0fa9 100644
--- a/packages/astro/src/vite-plugin-jsx/index.ts
+++ b/packages/astro/src/vite-plugin-jsx/index.ts
@@ -1,4 +1,5 @@
import type { TransformResult } from 'rollup';
+import type { TsConfigJson } from 'tsconfig-resolver';
import type { Plugin, ResolvedConfig } from 'vite';
import type { AstroConfig, AstroRenderer } from '../@types/astro';
import type { LogOptions } from '../core/logger/core.js';
@@ -13,6 +14,10 @@ import { error } from '../core/logger/core.js';
import { parseNpmName } from '../core/util.js';
import tagExportsPlugin from './tag.js';
+type FixedCompilerOptions = TsConfigJson.CompilerOptions & {
+ jsxImportSource?: string;
+}
+
const JSX_EXTENSIONS = new Set(['.jsx', '.tsx', '.mdx']);
const IMPORT_STATEMENTS: Record<string, string> = {
react: "import React from 'react'",
@@ -223,6 +228,12 @@ export default function jsx({ config, logging }: AstroPluginJSXOptions): Plugin
importSource = await detectImportSourceFromImports(code, id, jsxRenderers);
}
+ // Check the tsconfig
+ if(!importSource) {
+ const compilerOptions = config._ctx.tsConfig?.compilerOptions;
+ importSource = (compilerOptions as FixedCompilerOptions | undefined)?.jsxImportSource;
+ }
+
// if we still can’t tell the import source, now is the time to throw an error.
if (!importSource && defaultJSXRendererEntry) {
const [defaultRendererName] = defaultJSXRendererEntry;
diff --git a/packages/astro/test/fixtures/react-and-solid/astro.config.mjs b/packages/astro/test/fixtures/react-and-solid/astro.config.mjs
new file mode 100644
index 000000000..f7e79331e
--- /dev/null
+++ b/packages/astro/test/fixtures/react-and-solid/astro.config.mjs
@@ -0,0 +1,7 @@
+import { defineConfig } from 'astro/config';
+import react from '@astrojs/react';
+import solid from '@astrojs/solid-js';
+
+export default defineConfig({
+ integrations: [react(), solid()]
+});
diff --git a/packages/astro/test/fixtures/react-and-solid/package.json b/packages/astro/test/fixtures/react-and-solid/package.json
new file mode 100644
index 000000000..0ec8ac57e
--- /dev/null
+++ b/packages/astro/test/fixtures/react-and-solid/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@test/react-and-solid",
+ "dependencies": {
+ "astro": "workspace:*",
+ "@astrojs/react": "workspace:*",
+ "@astrojs/solid-js": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/react-and-solid/src/components/ExampleReact.tsx b/packages/astro/test/fixtures/react-and-solid/src/components/ExampleReact.tsx
new file mode 100644
index 000000000..f4b8cfd55
--- /dev/null
+++ b/packages/astro/test/fixtures/react-and-solid/src/components/ExampleReact.tsx
@@ -0,0 +1,6 @@
+/** @jsxImportSource react */
+import { FC } from 'react';
+
+export const ExampleReact: FC = () => {
+ return <div id="example-react">example react component</div>;
+};
diff --git a/packages/astro/test/fixtures/react-and-solid/src/components/ExampleSolid.tsx b/packages/astro/test/fixtures/react-and-solid/src/components/ExampleSolid.tsx
new file mode 100644
index 000000000..c0e6336fc
--- /dev/null
+++ b/packages/astro/test/fixtures/react-and-solid/src/components/ExampleSolid.tsx
@@ -0,0 +1,5 @@
+import { VoidComponent } from 'solid-js';
+
+export const ExampleSolid: VoidComponent = () => {
+ return <div id="example-solid">example solidjs component</div>;
+};
diff --git a/packages/astro/test/fixtures/react-and-solid/src/pages/index.astro b/packages/astro/test/fixtures/react-and-solid/src/pages/index.astro
new file mode 100644
index 000000000..99f781534
--- /dev/null
+++ b/packages/astro/test/fixtures/react-and-solid/src/pages/index.astro
@@ -0,0 +1,13 @@
+---
+import { ExampleReact } from '../components/ExampleReact';
+import { ExampleSolid } from '../components/ExampleSolid';
+---
+<html>
+ <head>
+ <title>title</title>
+ </head>
+ <body>
+ <ExampleReact />
+ <ExampleSolid />
+ </body>
+</html>
diff --git a/packages/astro/test/fixtures/react-and-solid/tsconfig.json b/packages/astro/test/fixtures/react-and-solid/tsconfig.json
new file mode 100644
index 000000000..0b4b89bbc
--- /dev/null
+++ b/packages/astro/test/fixtures/react-and-solid/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "compilerOptions": {
+ "strict": true,
+ "jsxImportSource": "solid-js",
+ "types": ["astro/client"]
+ }
+}
diff --git a/packages/astro/test/react-and-solid.test.js b/packages/astro/test/react-and-solid.test.js
new file mode 100644
index 000000000..e15e6e7fa
--- /dev/null
+++ b/packages/astro/test/react-and-solid.test.js
@@ -0,0 +1,20 @@
+import { expect } from 'chai';
+import * as cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
+
+describe('Solid app with some React components', () => {
+ /** @type {import('./test-utils').Fixture} */
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({ root: './fixtures/react-and-solid/' });
+ await fixture.build();
+ });
+
+ it('Reads jsxImportSource from tsconfig', async () => {
+ let html = await fixture.readFile('/index.html');
+ let $ = cheerio.load(html);
+ expect($('#example-solid').text()).to.equal('example solidjs component');
+ expect($('#example-react').text()).to.equal('example react component');
+ });
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 649da20d0..f011242cb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1748,6 +1748,16 @@ importers:
dependencies:
astro: link:../../..
+ packages/astro/test/fixtures/react-and-solid:
+ specifiers:
+ '@astrojs/react': workspace:*
+ '@astrojs/solid-js': workspace:*
+ astro: workspace:*
+ dependencies:
+ '@astrojs/react': link:../../../../integrations/react
+ '@astrojs/solid-js': link:../../../../integrations/solid
+ astro: link:../../..
+
packages/astro/test/fixtures/react-component:
specifiers:
'@astrojs/react': workspace:*