mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
Use acorn to postprocess Astro globs (#5652)
This commit is contained in:
parent
7a575d78c2
commit
0b50987584
7 changed files with 52 additions and 57 deletions
5
.changeset/five-cups-battle.md
Normal file
5
.changeset/five-cups-battle.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Use acorn to postprocess Astro globs
|
|
@ -3,9 +3,7 @@ import { useState } from 'react';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
obj: BigNestedObject;
|
obj: BigNestedObject;
|
||||||
// TODO: support BigInt in `astro:postprocess`
|
num: bigint;
|
||||||
// num: bigint;
|
|
||||||
num: number;
|
|
||||||
arr: any[];
|
arr: any[];
|
||||||
map: Map<string, string>;
|
map: Map<string, string>;
|
||||||
set: Set<string>;
|
set: Set<string>;
|
||||||
|
|
|
@ -30,8 +30,7 @@ set.add('test2');
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<!-- TODO: support BigInt in `astro:postprocess` -->
|
<Component client:load obj={obj} num={11n} arr={[0, "foo"]} map={map} set={set} />
|
||||||
<Component client:load obj={obj} num={11} arr={[0, "foo"]} map={map} set={set} />
|
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -32,8 +32,7 @@ test.describe('Passing JS into client components', () => {
|
||||||
await expect(regExpValue).toHaveText('ok');
|
await expect(regExpValue).toHaveText('ok');
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: support BigInt in `astro:postprocess`
|
test('BigInts', async ({ page }) => {
|
||||||
test.skip('BigInts', async ({ page }) => {
|
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
|
|
||||||
const bigIntType = await page.locator('#bigint-type');
|
const bigIntType = await page.locator('#bigint-type');
|
||||||
|
|
|
@ -124,6 +124,7 @@
|
||||||
"@types/babel__core": "^7.1.19",
|
"@types/babel__core": "^7.1.19",
|
||||||
"@types/html-escaper": "^3.0.0",
|
"@types/html-escaper": "^3.0.0",
|
||||||
"@types/yargs-parser": "^21.0.0",
|
"@types/yargs-parser": "^21.0.0",
|
||||||
|
"acorn": "^8.8.1",
|
||||||
"boxen": "^6.2.1",
|
"boxen": "^6.2.1",
|
||||||
"ci-info": "^3.3.1",
|
"ci-info": "^3.3.1",
|
||||||
"common-ancestor-path": "^1.0.1",
|
"common-ancestor-path": "^1.0.1",
|
||||||
|
@ -133,6 +134,7 @@
|
||||||
"devalue": "^4.2.0",
|
"devalue": "^4.2.0",
|
||||||
"diff": "^5.1.0",
|
"diff": "^5.1.0",
|
||||||
"es-module-lexer": "^1.1.0",
|
"es-module-lexer": "^1.1.0",
|
||||||
|
"estree-walker": "^3.0.1",
|
||||||
"execa": "^6.1.0",
|
"execa": "^6.1.0",
|
||||||
"fast-glob": "^3.2.11",
|
"fast-glob": "^3.2.11",
|
||||||
"github-slugger": "^1.4.0",
|
"github-slugger": "^1.4.0",
|
||||||
|
@ -192,7 +194,6 @@
|
||||||
"@types/rimraf": "^3.0.2",
|
"@types/rimraf": "^3.0.2",
|
||||||
"@types/send": "^0.17.1",
|
"@types/send": "^0.17.1",
|
||||||
"@types/unist": "^2.0.6",
|
"@types/unist": "^2.0.6",
|
||||||
"ast-types": "^0.14.2",
|
|
||||||
"astro-scripts": "workspace:*",
|
"astro-scripts": "workspace:*",
|
||||||
"chai": "^4.3.6",
|
"chai": "^4.3.6",
|
||||||
"cheerio": "^1.0.0-rc.11",
|
"cheerio": "^1.0.0-rc.11",
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { parse as babelParser } from '@babel/parser';
|
import { parse } from 'acorn';
|
||||||
import type { ArrowFunctionExpressionKind, CallExpressionKind } from 'ast-types/gen/kinds';
|
import { walk } from 'estree-walker';
|
||||||
import type { NodePath } from 'ast-types/lib/node-path';
|
import MagicString from 'magic-string';
|
||||||
import { parse, print, types, visit } from 'recast';
|
|
||||||
import type { Plugin } from 'vite';
|
import type { Plugin } from 'vite';
|
||||||
import type { AstroSettings } from '../@types/astro';
|
import type { AstroSettings } from '../@types/astro';
|
||||||
import { isMarkdownFile } from '../core/util.js';
|
import { isMarkdownFile } from '../core/util.js';
|
||||||
|
@ -28,57 +27,48 @@ export default function astro(_opts: AstroPluginOptions): Plugin {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let s: MagicString | undefined;
|
||||||
const ast = parse(code, {
|
const ast = parse(code, {
|
||||||
// We need to use the babel parser because `import.meta.hot` is not
|
ecmaVersion: 'latest',
|
||||||
// supported by esprima (default parser). In the future, we should
|
sourceType: 'module',
|
||||||
// experiment with other parsers if Babel is too slow or heavy.
|
|
||||||
parser: { parse: babelParser },
|
|
||||||
});
|
});
|
||||||
|
walk(ast, {
|
||||||
visit(ast, {
|
enter(node: any) {
|
||||||
visitCallExpression: function (path) {
|
// Transform `Astro.glob("./pages/*.astro")` to `Astro.glob(import.meta.glob("./pages/*.astro"), () => "./pages/*.astro")`
|
||||||
// Filter out anything that isn't `Astro.glob()` or `Astro2.glob()`
|
// Also handle for `Astro2.glob()`
|
||||||
if (
|
if (
|
||||||
!types.namedTypes.MemberExpression.check(path.node.callee) ||
|
node.type === 'CallExpression' &&
|
||||||
!types.namedTypes.Identifier.check(path.node.callee.property) ||
|
node.callee.type === 'MemberExpression' &&
|
||||||
!(path.node.callee.property.name === 'glob') ||
|
node.callee.property.name === 'glob' &&
|
||||||
!types.namedTypes.Identifier.check(path.node.callee.object) ||
|
(node.callee.object.name === 'Astro' || node.callee.object.name === 'Astro2') &&
|
||||||
!(path.node.callee.object.name === 'Astro' || path.node.callee.object.name === 'Astro2')
|
node.arguments.length
|
||||||
) {
|
) {
|
||||||
this.traverse(path);
|
const firstArgStart = node.arguments[0].start;
|
||||||
return;
|
const firstArgEnd = node.arguments[0].end;
|
||||||
|
const lastArgEnd = node.arguments[node.arguments.length - 1].end;
|
||||||
|
let firstArg = code.slice(firstArgStart, firstArgEnd);
|
||||||
|
// If argument is template literal, try convert to a normal string.
|
||||||
|
// This is needed for compat with previous recast strategy.
|
||||||
|
// TODO: Remove in Astro 2.0
|
||||||
|
if (firstArg.startsWith('`') && firstArg.endsWith('`') && !firstArg.includes('${')) {
|
||||||
|
firstArg = JSON.stringify(firstArg.slice(1, -1));
|
||||||
|
}
|
||||||
|
s ??= new MagicString(code);
|
||||||
|
s.overwrite(
|
||||||
|
firstArgStart,
|
||||||
|
lastArgEnd,
|
||||||
|
`import.meta.glob(${firstArg}), () => ${firstArg}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap the `Astro.glob()` argument with `import.meta.glob`.
|
|
||||||
const argsPath = path.get('arguments', 0) as NodePath;
|
|
||||||
const args = argsPath.value;
|
|
||||||
argsPath.replace(
|
|
||||||
{
|
|
||||||
type: 'CallExpression',
|
|
||||||
callee: {
|
|
||||||
type: 'MemberExpression',
|
|
||||||
object: {
|
|
||||||
type: 'MetaProperty',
|
|
||||||
meta: { type: 'Identifier', name: 'import' },
|
|
||||||
property: { type: 'Identifier', name: 'meta' },
|
|
||||||
},
|
|
||||||
property: { type: 'Identifier', name: 'glob' },
|
|
||||||
computed: false,
|
|
||||||
},
|
|
||||||
arguments: [args],
|
|
||||||
} as CallExpressionKind,
|
|
||||||
{
|
|
||||||
type: 'ArrowFunctionExpression',
|
|
||||||
body: args,
|
|
||||||
params: [],
|
|
||||||
} as ArrowFunctionExpressionKind
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = print(ast);
|
if (s) {
|
||||||
return { code: result.code, map: result.map };
|
return {
|
||||||
|
code: s.toString(),
|
||||||
|
map: s.generateMap(),
|
||||||
|
};
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -422,7 +422,7 @@ importers:
|
||||||
'@types/send': ^0.17.1
|
'@types/send': ^0.17.1
|
||||||
'@types/unist': ^2.0.6
|
'@types/unist': ^2.0.6
|
||||||
'@types/yargs-parser': ^21.0.0
|
'@types/yargs-parser': ^21.0.0
|
||||||
ast-types: ^0.14.2
|
acorn: ^8.8.1
|
||||||
astro-scripts: workspace:*
|
astro-scripts: workspace:*
|
||||||
boxen: ^6.2.1
|
boxen: ^6.2.1
|
||||||
chai: ^4.3.6
|
chai: ^4.3.6
|
||||||
|
@ -436,6 +436,7 @@ importers:
|
||||||
diff: ^5.1.0
|
diff: ^5.1.0
|
||||||
eol: ^0.9.1
|
eol: ^0.9.1
|
||||||
es-module-lexer: ^1.1.0
|
es-module-lexer: ^1.1.0
|
||||||
|
estree-walker: ^3.0.1
|
||||||
execa: ^6.1.0
|
execa: ^6.1.0
|
||||||
fast-glob: ^3.2.11
|
fast-glob: ^3.2.11
|
||||||
github-slugger: ^1.4.0
|
github-slugger: ^1.4.0
|
||||||
|
@ -500,6 +501,7 @@ importers:
|
||||||
'@types/babel__core': 7.1.20
|
'@types/babel__core': 7.1.20
|
||||||
'@types/html-escaper': 3.0.0
|
'@types/html-escaper': 3.0.0
|
||||||
'@types/yargs-parser': 21.0.0
|
'@types/yargs-parser': 21.0.0
|
||||||
|
acorn: 8.8.1
|
||||||
boxen: 6.2.1
|
boxen: 6.2.1
|
||||||
ci-info: 3.6.1
|
ci-info: 3.6.1
|
||||||
common-ancestor-path: 1.0.1
|
common-ancestor-path: 1.0.1
|
||||||
|
@ -509,6 +511,7 @@ importers:
|
||||||
devalue: 4.2.0
|
devalue: 4.2.0
|
||||||
diff: 5.1.0
|
diff: 5.1.0
|
||||||
es-module-lexer: 1.1.0
|
es-module-lexer: 1.1.0
|
||||||
|
estree-walker: 3.0.1
|
||||||
execa: 6.1.0
|
execa: 6.1.0
|
||||||
fast-glob: 3.2.12
|
fast-glob: 3.2.12
|
||||||
github-slugger: 1.5.0
|
github-slugger: 1.5.0
|
||||||
|
@ -567,7 +570,6 @@ importers:
|
||||||
'@types/rimraf': 3.0.2
|
'@types/rimraf': 3.0.2
|
||||||
'@types/send': 0.17.1
|
'@types/send': 0.17.1
|
||||||
'@types/unist': 2.0.6
|
'@types/unist': 2.0.6
|
||||||
ast-types: 0.14.2
|
|
||||||
astro-scripts: link:../../scripts
|
astro-scripts: link:../../scripts
|
||||||
chai: 4.3.7
|
chai: 4.3.7
|
||||||
cheerio: 1.0.0-rc.12
|
cheerio: 1.0.0-rc.12
|
||||||
|
@ -10703,6 +10705,7 @@ packages:
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib: 2.4.1
|
tslib: 2.4.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/astring/1.8.3:
|
/astring/1.8.3:
|
||||||
resolution: {integrity: sha512-sRpyiNrx2dEYIMmUXprS8nlpRg2Drs8m9ElX9vVEXaCB4XEAJhKfs7IcX0IwShjuOAjLR6wzIrgoptz1n19i1A==}
|
resolution: {integrity: sha512-sRpyiNrx2dEYIMmUXprS8nlpRg2Drs8m9ElX9vVEXaCB4XEAJhKfs7IcX0IwShjuOAjLR6wzIrgoptz1n19i1A==}
|
||||||
|
|
Loading…
Reference in a new issue