test02/node_modules/@vuepress/bundler-vite/dist/index.js
罗佳鸿 6aa1ebe342
Some checks are pending
部署文档 / deploy-gh-pages (push) Waiting to run
first commit
2024-08-13 10:11:19 +08:00

478 lines
13 KiB
JavaScript

// src/build/build.ts
import { colors, debug, fs as fs3, importFile, withSpinner } from "@vuepress/utils";
import { build as viteBuild } from "vite";
// src/resolveViteConfig.ts
import { mergeConfig } from "vite";
// src/plugins/vuepressMainPlugin.ts
import { fs, sanitizeFileName } from "@vuepress/utils";
import autoprefixer from "autoprefixer";
import history from "connect-history-api-fallback";
import postcssrc from "postcss-load-config";
var vuepressMainPlugin = ({
app,
isBuild,
isServer
}) => ({
name: "vuepress:main",
config: async () => {
if (!isBuild) {
await app.writeTemp(
"vite-root/index.html",
fs.readFileSync(app.options.templateDev).toString().replace(
/<\/body>/,
`<script type="module">
import 'vuepress/client-app'
</script>
</body>`
)
);
}
const clientPackages = [
// although discouraged, but users may still use `@vuepress/client` directly
"@vuepress/client",
"vuepress",
...app.pluginApi.plugins.filter(({ name }) => name !== "user-config").map(({ name }) => name)
];
let postcssPlugins;
try {
const postcssConfigResult = await postcssrc();
postcssPlugins = postcssConfigResult.plugins;
} catch (error) {
postcssPlugins = [autoprefixer];
}
return {
root: app.dir.temp("vite-root"),
base: app.options.base,
mode: !isBuild || app.env.isDebug ? "development" : "production",
define: await resolveDefine({ app, isBuild, isServer }),
publicDir: app.dir.public(),
cacheDir: app.dir.cache(),
resolve: {
alias: await resolveAlias({ app, isServer })
},
css: {
postcss: {
plugins: isServer ? [] : postcssPlugins
},
preprocessorOptions: {
scss: { charset: false }
}
},
server: {
host: app.options.host,
port: app.options.port,
open: app.options.open,
// ref: https://github.com/vitejs/vite/issues/15784#issuecomment-1923683823
fs: { cachedChecks: false }
},
build: {
ssr: isServer,
outDir: isServer ? app.dir.temp(".server") : app.dir.dest(),
emptyOutDir: false,
cssCodeSplit: false,
rollupOptions: {
input: app.dir.client(
fs.readJsonSync(app.dir.client("package.json")).exports["./app"]
),
output: {
sanitizeFileName,
...isServer ? {
// also add hash to ssr entry file, so that users could build multiple sites in a single process
entryFileNames: `[name].[hash].mjs`
} : {}
},
preserveEntrySignatures: "allow-extension"
},
minify: isServer ? false : !app.env.isDebug
},
optimizeDeps: {
exclude: clientPackages
},
ssr: {
format: "esm",
noExternal: clientPackages
}
};
},
generateBundle(_, bundle) {
if (isServer) {
Object.keys(bundle).forEach((key) => {
if (bundle[key].type === "asset") {
delete bundle[key];
}
});
}
},
configureServer(server) {
return () => {
server.middlewares.use(
history({
rewrites: [
{
from: /\.html$/,
to: "/index.html"
}
]
})
);
};
}
});
var resolveAlias = async ({
app,
isServer
}) => {
const alias = {
"@internal": app.dir.temp("internal"),
"@temp": app.dir.temp(),
"@source": app.dir.source()
};
const aliasResult = await app.pluginApi.hooks.alias.process(app, isServer);
aliasResult.forEach(
(aliasObject) => Object.entries(aliasObject).forEach(([key, value]) => {
alias[key] = value;
})
);
return [
...Object.keys(alias).map((item) => ({
find: item,
replacement: alias[item]
})),
...isServer ? [] : [
{
find: /^vue$/,
replacement: "vue/dist/vue.runtime.esm-bundler.js"
},
{
find: /^vue-router$/,
replacement: "vue-router/dist/vue-router.esm-bundler.js"
}
]
];
};
var resolveDefine = async ({
app,
isBuild,
isServer
}) => {
const define = {
__VUEPRESS_VERSION__: JSON.stringify(app.version),
__VUEPRESS_BASE__: JSON.stringify(app.options.base),
__VUEPRESS_DEV__: JSON.stringify(!isBuild),
__VUEPRESS_SSR__: JSON.stringify(isServer),
// @see http://link.vuejs.org/feature-flags
// enable options API by default
__VUE_OPTIONS_API__: JSON.stringify(true),
__VUE_PROD_DEVTOOLS__: JSON.stringify(app.env.isDebug),
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: JSON.stringify(app.env.isDebug)
};
if (app.env.isDebug) {
define["process.env.NODE_ENV"] = JSON.stringify("development");
}
const defineResult = await app.pluginApi.hooks.define.process(app, isServer);
defineResult.forEach(
(defineObject) => Object.entries(defineObject).forEach(([key, value]) => {
define[key] = JSON.stringify(value);
})
);
return define;
};
// src/plugins/vuepressUserConfigPlugin.ts
var vuepressUserConfigPlugin = (options) => ({
name: "vuepress:user-config",
config: () => options.viteOptions ?? {}
});
// src/plugins/vuepressVuePlugin.ts
import vuePlugin from "@vitejs/plugin-vue";
var vuepressVuePlugin = (options) => {
return vuePlugin({
...options.vuePluginOptions,
template: {
...options.vuePluginOptions?.template,
transformAssetUrls: resolveTransformAssetUrls(options)
}
});
};
var isAssetURLTagConfig = (transformAssetUrls) => Object.values(transformAssetUrls).some((val) => Array.isArray(val));
var resolveTransformAssetUrls = (options) => {
const defaultTransformAssetUrls = { includeAbsolute: true };
const { transformAssetUrls: userTransformAssetUrls } = options.vuePluginOptions?.template ?? {};
if (typeof userTransformAssetUrls !== "object") {
return defaultTransformAssetUrls;
}
if (isAssetURLTagConfig(userTransformAssetUrls)) {
return {
...defaultTransformAssetUrls,
tags: userTransformAssetUrls
};
}
return {
...defaultTransformAssetUrls,
...userTransformAssetUrls
};
};
// src/resolveViteConfig.ts
var resolveViteConfig = async ({
app,
options,
isBuild,
isServer
}) => {
return mergeConfig(
{
clearScreen: false,
configFile: false,
logLevel: !isBuild || app.env.isDebug ? "info" : "warn",
esbuild: {
charset: "utf8"
},
plugins: [
vuepressVuePlugin(options),
vuepressMainPlugin({ app, isBuild, isServer }),
vuepressUserConfigPlugin(options)
]
},
// some vite options would not take effect inside a plugin, so we still need to merge them here in addition to userConfigPlugin
options.viteOptions ?? {}
);
};
// src/build/renderPage.ts
import { fs as fs2, renderHead } from "@vuepress/utils";
import { ssrContextKey } from "vue";
// src/build/renderPagePrefetchLinks.ts
var renderPagePrefetchLinks = ({
app,
outputEntryChunk,
pageChunkFiles
}) => {
const shouldPrefetch = app.options.shouldPrefetch;
if (shouldPrefetch === false) {
return "";
}
const prefetchFiles = outputEntryChunk.dynamicImports.filter(
(item) => !pageChunkFiles.some((file) => file === item)
);
return prefetchFiles.map((item) => {
const type = item.endsWith(".js") ? "script" : item.endsWith(".css") ? "style" : "";
if (shouldPrefetch !== true && !shouldPrefetch(item, type)) {
return "";
}
return `<link rel="prefetch" href="${app.options.base}${item}" as="${type}">`;
}).join("");
};
// src/build/renderPagePreloadLinks.ts
var renderPagePreloadLinks = ({
app,
outputEntryChunk,
pageChunkFiles
}) => {
const shouldPreload = app.options.shouldPreload;
if (shouldPreload === false) {
return "";
}
const preloadFiles = Array.from(
/* @__PURE__ */ new Set([
outputEntryChunk.fileName,
...outputEntryChunk.imports,
...pageChunkFiles
])
);
return preloadFiles.map((item) => {
const type = item.endsWith(".js") ? "script" : item.endsWith(".css") ? "style" : "";
if (shouldPreload === true && type !== "script" && type !== "style") {
return "";
}
if (shouldPreload !== true && !shouldPreload(item, type)) {
return "";
}
if (type === "script") {
return `<link rel="modulepreload" href="${app.options.base}${item}">`;
}
return `<link rel="preload" href="${app.options.base}${item}"${type !== "" ? ` as="${type}"` : ""}>`;
}).join("");
};
// src/build/renderPageScripts.ts
var renderPageScripts = ({
app,
outputEntryChunk
}) => `<script type="module" src="${app.options.base}${outputEntryChunk.fileName}" defer></script>`;
// src/build/renderPageStyles.ts
var renderPageStyles = ({
app,
outputCssAsset
}) => outputCssAsset ? [
`<link rel="preload" href="${app.options.base}${outputCssAsset.fileName}" as="style">`,
`<link rel="stylesheet" href="${app.options.base}${outputCssAsset.fileName}">`
].join("") : "";
// src/build/resolvePageChunkFiles.ts
var resolvePageChunkFiles = ({
page,
output
}) => output.filter(
(item) => item.type === "chunk" && item.facadeModuleId === page.chunkFilePath
).flatMap(({ fileName, imports, dynamicImports }) => [
fileName,
...imports,
...dynamicImports
]);
// src/build/renderPage.ts
var renderPage = async ({
app,
page,
vueApp,
vueRouter,
renderToString,
ssrTemplate,
output,
outputEntryChunk,
outputCssAsset
}) => {
await vueRouter.push(page.path);
await vueRouter.isReady();
delete vueApp._context.provides[ssrContextKey];
const ssrContext = {
lang: "en",
head: []
};
const pageRendered = await renderToString(vueApp, ssrContext);
const pageChunkFiles = resolvePageChunkFiles({ page, output });
const html = await app.options.templateBuildRenderer(ssrTemplate, {
content: pageRendered,
head: ssrContext.head.map(renderHead).join(""),
lang: ssrContext.lang,
prefetch: renderPagePrefetchLinks({
app,
outputEntryChunk,
pageChunkFiles
}),
preload: renderPagePreloadLinks({
app,
outputEntryChunk,
pageChunkFiles
}),
scripts: renderPageScripts({ app, outputEntryChunk }),
styles: renderPageStyles({ app, outputCssAsset }),
version: app.version
});
await fs2.outputFile(page.htmlFilePath, html);
};
// src/build/build.ts
var log = debug("vuepress:bundler-vite/build");
var build = async (options, app) => {
await app.pluginApi.hooks.extendsBundlerOptions.process(options, app);
log("compiling start");
let clientOutput;
let serverOutput;
await withSpinner("Compiling with vite")(async () => {
const clientConfig = await resolveViteConfig({
app,
options,
isBuild: true,
isServer: false
});
const serverConfig = await resolveViteConfig({
app,
options,
isBuild: true,
isServer: true
});
[clientOutput, serverOutput] = await Promise.all([
viteBuild(clientConfig),
viteBuild(serverConfig)
]);
});
log("compiling finish");
await withSpinner(`Rendering ${app.pages.length} pages`)(async (spinner) => {
const clientEntryChunk = clientOutput.output.find(
(item) => item.type === "chunk" && item.isEntry
);
const clientCssAsset = clientOutput.output.find(
(item) => item.type === "asset" && item.fileName.endsWith(".css")
);
const serverEntryChunk = serverOutput.output.find(
(item) => item.type === "chunk" && item.isEntry
);
const serverEntryPath = app.dir.temp(".server", serverEntryChunk.fileName);
const { createVueApp } = await importFile(serverEntryPath);
const { app: vueApp, router: vueRouter } = await createVueApp();
const { renderToString } = await import("vue/server-renderer");
const ssrTemplate = await fs3.readFile(app.options.templateBuild, {
encoding: "utf8"
});
for (const page of app.pages) {
if (spinner) spinner.text = `Rendering pages ${colors.magenta(page.path)}`;
await renderPage({
app,
page,
vueApp,
vueRouter,
renderToString,
ssrTemplate,
output: clientOutput.output,
outputEntryChunk: clientEntryChunk,
outputCssAsset: clientCssAsset
});
}
});
if (!app.env.isDebug) {
await fs3.remove(app.dir.temp(".server"));
}
};
// src/dev.ts
import { createRequire } from "module";
import { colors as colors2, fs as fs4 } from "@vuepress/utils";
import { createServer } from "vite";
var require2 = createRequire(import.meta.url);
var dev = async (options, app) => {
await app.pluginApi.hooks.extendsBundlerOptions.process(options, app);
const viteConfig = await resolveViteConfig({
app,
options,
isBuild: false,
isServer: false
});
const server = await createServer(viteConfig);
await server.listen();
const viteVersion = fs4.readJsonSync(
require2.resolve("vite/package.json")
).version;
server.config.logger.info(
colors2.cyan(`
vite v${viteVersion}`) + colors2.green(` dev server running at:
`),
{
clear: !server.config.logger.hasWarned
}
);
server.printUrls();
return server.close.bind(server);
};
// src/viteBundler.ts
var viteBundler = (options = {}) => ({
name: "@vuepress/bundler-vite",
dev: (app) => dev(options, app),
build: (app) => build(options, app)
});
// src/index.ts
var src_default = viteBundler;
export {
src_default as default,
viteBundler
};