diff options
16 files changed, 238 insertions, 21 deletions
diff --git a/.changeset/dry-garlics-push.md b/.changeset/dry-garlics-push.md new file mode 100644 index 000000000..b350e8f41 --- /dev/null +++ b/.changeset/dry-garlics-push.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Remove 'paths' requirement for tsconfig path aliasing diff --git a/packages/astro/src/vite-plugin-config-alias/index.ts b/packages/astro/src/vite-plugin-config-alias/index.ts index b3698c834..d124dd687 100644 --- a/packages/astro/src/vite-plugin-config-alias/index.ts +++ b/packages/astro/src/vite-plugin-config-alias/index.ts @@ -13,7 +13,7 @@ const getConfigAlias = (settings: AstroSettings): Alias[] | null => { if (!tsConfig || !tsConfigPath || !tsConfig.compilerOptions) return null; const { baseUrl, paths } = tsConfig.compilerOptions; - if (!baseUrl || !paths) return null; + if (!baseUrl) return null; // resolve the base url from the configuration file directory const resolvedBaseUrl = path.resolve(path.dirname(tsConfigPath), baseUrl); @@ -21,26 +21,28 @@ const getConfigAlias = (settings: AstroSettings): Alias[] | null => { const aliases: Alias[] = []; // compile any alias expressions and push them to the list - for (const [alias, values] of Object.entries(paths)) { - /** Regular Expression used to match a given path. */ - const find = new RegExp( - `^${[...alias] - .map((segment) => - segment === '*' ? '(.+)' : segment.replace(/[\\^$*+?.()|[\]{}]/, '\\$&') - ) - .join('')}$` - ); - - /** Internal index used to calculate the matching id in a replacement. */ - let matchId = 0; - - for (const value of values) { - /** String used to replace a matched path. */ - const replacement = [...normalizePath(path.resolve(resolvedBaseUrl, value))] - .map((segment) => (segment === '*' ? `$${++matchId}` : segment === '$' ? '$$' : segment)) - .join(''); - - aliases.push({ find, replacement }); + if (paths) { + for (const [alias, values] of Object.entries(paths)) { + /** Regular Expression used to match a given path. */ + const find = new RegExp( + `^${[...alias] + .map((segment) => + segment === '*' ? '(.+)' : segment.replace(/[\\^$*+?.()|[\]{}]/, '\\$&') + ) + .join('')}$` + ); + + /** Internal index used to calculate the matching id in a replacement. */ + let matchId = 0; + + for (const value of values) { + /** String used to replace a matched path. */ + const replacement = [...normalizePath(path.resolve(resolvedBaseUrl, value))] + .map((segment) => (segment === '*' ? `$${++matchId}` : segment === '$' ? '$$' : segment)) + .join(''); + + aliases.push({ find, replacement }); + } } } diff --git a/packages/astro/test/alias-tsconfig-baseurl-only.test.js b/packages/astro/test/alias-tsconfig-baseurl-only.test.js new file mode 100644 index 000000000..55b7ecc37 --- /dev/null +++ b/packages/astro/test/alias-tsconfig-baseurl-only.test.js @@ -0,0 +1,123 @@ +import { expect } from 'chai'; +import * as cheerio from 'cheerio'; +import { loadFixture } from './test-utils.js'; + +describe('Aliases with tsconfig.json - baseUrl only', () => { + let fixture; + + /** + * @param {string} html + * @returns {string[]} + */ + function getLinks(html) { + let $ = cheerio.load(html); + let out = []; + $('link[rel=stylesheet]').each((i, el) => { + out.push($(el).attr('href')); + }); + return out; + } + + /** + * @param {string} href + * @returns {Promise<{ href: string; css: string; }>} + */ + async function getLinkContent(href, f = fixture) { + const css = await f.readFile(href); + return { href, css }; + } + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/alias-tsconfig-baseurl-only/', + }); + }); + + describe('dev', () => { + let devServer; + + before(async () => { + devServer = await fixture.startDevServer(); + }); + + after(async () => { + await devServer.stop(); + }); + + it('can load client components', async () => { + const html = await fixture.fetch('/').then((res) => res.text()); + const $ = cheerio.load(html); + + // Should render aliased element + expect($('#client').text()).to.equal('test'); + + const scripts = $('script').toArray(); + expect(scripts.length).to.be.greaterThan(0); + }); + + it('can load via baseUrl', async () => { + const html = await fixture.fetch('/').then((res) => res.text()); + const $ = cheerio.load(html); + + expect($('#foo').text()).to.equal('foo'); + expect($('#constants-foo').text()).to.equal('foo'); + expect($('#constants-index').text()).to.equal('index'); + }); + + it('works in css @import', async () => { + const html = await fixture.fetch('/').then((res) => res.text()); + // imported css should be bundled + expect(html).to.include('#style-red'); + expect(html).to.include('#style-blue'); + }); + + it('works in components', async () => { + const html = await fixture.fetch('/').then((res) => res.text()); + const $ = cheerio.load(html); + + expect($('#alias').text()).to.equal('foo'); + }); + }); + + describe('build', () => { + before(async () => { + await fixture.build(); + }); + + it('can load client components', async () => { + const html = await fixture.readFile('/index.html'); + const $ = cheerio.load(html); + + // Should render aliased element + expect($('#client').text()).to.equal('test'); + + const scripts = $('script').toArray(); + expect(scripts.length).to.be.greaterThan(0); + }); + + it('can load via baseUrl', async () => { + const html = await fixture.readFile('/index.html'); + const $ = cheerio.load(html); + + expect($('#foo').text()).to.equal('foo'); + expect($('#constants-foo').text()).to.equal('foo'); + expect($('#constants-index').text()).to.equal('index'); + }); + + it('works in css @import', async () => { + const html = await fixture.readFile('/index.html'); + const content = await Promise.all(getLinks(html).map((href) => getLinkContent(href))); + const [{ css }] = content; + // imported css should be bundled + expect(css).to.include('#style-red'); + expect(css).to.include('#style-blue'); + }); + + it('works in components', async () => { + const html = await fixture.readFile('/index.html'); + const $ = cheerio.load(html); + + expect($('#alias').text()).to.equal('foo'); + }); + }); +}); diff --git a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/astro.config.mjs b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/astro.config.mjs new file mode 100644 index 000000000..77fdcd1b9 --- /dev/null +++ b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/astro.config.mjs @@ -0,0 +1,7 @@ +import { defineConfig } from 'astro/config'; +import svelte from '@astrojs/svelte'; + +// https://astro.build/config +export default defineConfig({ + integrations: [svelte()], +}); diff --git a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/package.json b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/package.json new file mode 100644 index 000000000..6fcb9106c --- /dev/null +++ b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/package.json @@ -0,0 +1,10 @@ +{ + "name": "@test/aliases-tsconfig-baseurl-only", + "version": "0.0.0", + "private": true, + "dependencies": { + "@astrojs/svelte": "workspace:*", + "astro": "workspace:*", + "svelte": "^3.48.0" + } +} diff --git a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/components/Alias.svelte b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/components/Alias.svelte new file mode 100644 index 000000000..e0208ecf8 --- /dev/null +++ b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/components/Alias.svelte @@ -0,0 +1,4 @@ +<script> + import { foo } from 'utils/constants'; +</script> +<div id="alias">{foo}</div> diff --git a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/components/Client.svelte b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/components/Client.svelte new file mode 100644 index 000000000..2450d326a --- /dev/null +++ b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/components/Client.svelte @@ -0,0 +1,2 @@ +<script></script> +<div id="client">test</div> diff --git a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/components/Foo.astro b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/components/Foo.astro new file mode 100644 index 000000000..85bd9347e --- /dev/null +++ b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/components/Foo.astro @@ -0,0 +1 @@ +<p id="foo">foo</p> diff --git a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/components/Style.astro b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/components/Style.astro new file mode 100644 index 000000000..0d8e06ae3 --- /dev/null +++ b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/components/Style.astro @@ -0,0 +1,2 @@ +<p id="style-blue">i am blue</p> +<p id="style-red">i am red</p> diff --git a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/pages/index.astro b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/pages/index.astro new file mode 100644 index 000000000..e200a9567 --- /dev/null +++ b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/pages/index.astro @@ -0,0 +1,27 @@ +--- +import Client from 'components/Client.svelte' +import Foo from 'components/Foo.astro'; +import StyleComp from 'components/Style.astro'; +import Alias from 'components/Alias.svelte'; +import { foo, index } from 'utils/constants'; +import 'styles/main.css'; +--- +<html lang="en"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width" /> + <title>Aliases using tsconfig</title> + </head> + <body> + <main> + <Client client:load /> + <Foo /> + <StyleComp /> + <Alias client:load /> + <p id="constants-foo">{foo}</p> + <p id="constants-index">{index}</p> + <p id="style-red">style-red</p> + <p id="style-blue">style-blue</p> + </main> + </body> +</html> diff --git a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/styles/extra.css b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/styles/extra.css new file mode 100644 index 000000000..0b41276e8 --- /dev/null +++ b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/styles/extra.css @@ -0,0 +1,3 @@ +#style-red { + color: red; +}
\ No newline at end of file diff --git a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/styles/main.css b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/styles/main.css new file mode 100644 index 000000000..44b3310db --- /dev/null +++ b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/styles/main.css @@ -0,0 +1,5 @@ +@import "styles/extra.css"; + +#style-blue { + color: blue; +} diff --git a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/utils/constants.js b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/utils/constants.js new file mode 100644 index 000000000..28e8a5c17 --- /dev/null +++ b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/utils/constants.js @@ -0,0 +1,3 @@ +export * from '.' + +export const foo = 'foo' diff --git a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/utils/index.js b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/utils/index.js new file mode 100644 index 000000000..96896d711 --- /dev/null +++ b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/src/utils/index.js @@ -0,0 +1 @@ +export const index = 'index' diff --git a/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/tsconfig.json b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/tsconfig.json new file mode 100644 index 000000000..738e8a465 --- /dev/null +++ b/packages/astro/test/fixtures/alias-tsconfig-baseurl-only/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "baseUrl": "./src" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 94cb491ba..71fba1de2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1672,6 +1672,18 @@ importers: specifier: ^3.48.0 version: 3.58.0 + packages/astro/test/fixtures/alias-tsconfig-baseurl-only: + dependencies: + '@astrojs/svelte': + specifier: workspace:* + version: link:../../../../integrations/svelte + astro: + specifier: workspace:* + version: link:../../.. + svelte: + specifier: ^3.48.0 + version: 3.54.0 + packages/astro/test/fixtures/alias-tsconfig/deps/namespace-package: {} packages/astro/test/fixtures/api-routes: @@ -16520,6 +16532,11 @@ packages: typescript: 5.0.2 dev: false + /svelte@3.54.0: + resolution: {integrity: sha512-tdrgeJU0hob0ZWAMoKXkhcxXA7dpTg6lZGxUeko5YqvPdJBiyRspGsCwV27kIrbrqPP2WUoSV9ca0gnLlw8YzQ==} + engines: {node: '>= 8'} + dev: false + /svelte@3.58.0: resolution: {integrity: sha512-brIBNNB76mXFmU/Kerm4wFnkskBbluBDCjx/8TcpYRb298Yh2dztS2kQ6bhtjMcvUhd5ynClfwpz5h2gnzdQ1A==} engines: {node: '>= 8'} |