/
plugin-pages.ts
95 lines (81 loc) · 3.05 KB
/
plugin-pages.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import type { Plugin as VitePlugin } from 'vite';
import { addRollupInput } from '../add-rollup-input.js';
import { type BuildInternals } from '../internal.js';
import type { AstroBuildPlugin } from '../plugin';
import type { StaticBuildOptions } from '../types';
import { RENDERERS_MODULE_ID } from './plugin-renderers.js';
import { extname } from 'node:path';
import { MIDDLEWARE_PATH_SEGMENT_NAME } from '../../constants';
export const ASTRO_PAGE_MODULE_ID = '@astro-page:';
export const ASTRO_PAGE_RESOLVED_MODULE_ID = '\0@astro-page:';
// This is an arbitrary string that we are going to replace the dot of the extension
export const ASTRO_PAGE_EXTENSION_POST_PATTERN = '@_@';
function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): VitePlugin {
return {
name: '@astro/plugin-build-pages',
options(options) {
if (opts.settings.config.output === 'static') {
const inputs: Set<string> = new Set();
for (const path of Object.keys(opts.allPages)) {
const extension = extname(path);
// we mask the extension, so this virtual file
// so rollup won't trigger other plugins in the process
const virtualModuleName = `${ASTRO_PAGE_MODULE_ID}${path.replace(
extension,
extension.replace('.', ASTRO_PAGE_EXTENSION_POST_PATTERN)
)}`;
inputs.add(virtualModuleName);
}
return addRollupInput(options, Array.from(inputs));
}
},
resolveId(id) {
if (id.startsWith(ASTRO_PAGE_MODULE_ID)) {
return '\0' + id;
}
},
async load(id) {
if (id.startsWith(ASTRO_PAGE_RESOLVED_MODULE_ID)) {
const imports: string[] = [];
const exports: string[] = [];
// split by ":", the second element is the page name, which will start with "src/..."
const [, pageName] = id.split(':');
// We replaced the `.` of the extension with ASTRO_PAGE_EXTENSION_POST_PATTERN, let's replace it back
const pageData = internals.pagesByComponent.get(
`${pageName.replace(ASTRO_PAGE_EXTENSION_POST_PATTERN, '.')}`
);
if (pageData) {
const resolvedPage = await this.resolve(pageData.moduleSpecifier);
if (resolvedPage) {
imports.push(`const page = () => import(${JSON.stringify(pageData.moduleSpecifier)});`);
exports.push(`export { page }`);
imports.push(`import { renderers } from "${RENDERERS_MODULE_ID}";`);
exports.push(`export { renderers };`);
if (opts.settings.config.experimental.middleware) {
const middlewareId = await this.resolve(
`${opts.settings.config.srcDir.pathname}/${MIDDLEWARE_PATH_SEGMENT_NAME}`
);
if (middlewareId) {
imports.push(`import * as _middleware from "${middlewareId.id}";`);
exports.push(`export const middleware = _middleware;`);
}
}
return `${imports.join('\n')}${exports.join('\n')}`;
}
}
}
},
};
}
export function pluginPages(opts: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin {
return {
build: 'ssr',
hooks: {
'build:before': () => {
return {
vitePlugin: vitePluginPages(opts, internals),
};
},
},
};
}