mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-26 08:36:19 +08:00
feat: auto import route
This commit is contained in:
@@ -1,22 +0,0 @@
|
||||
// Build gzip after packaging
|
||||
// import { readFile, writeFile } from 'fs';
|
||||
import viteConfig from '../../vite.config';
|
||||
import {
|
||||
// basename,
|
||||
join,
|
||||
} from 'path';
|
||||
// import { promisify } from 'util';
|
||||
// import { gzip, ZlibOptions } from 'zlib';
|
||||
import { readAllFile } from '../utils';
|
||||
|
||||
// const readFilePromise = promisify(readFile);
|
||||
// const writeFilePromise = promisify(writeFile);
|
||||
|
||||
// function createGzip() {}
|
||||
|
||||
const FILE_REG = /\.(js|mjs|json|css|html)$/;
|
||||
|
||||
const OUT_DIR = viteConfig.outDir || 'dist';
|
||||
|
||||
// TODO 待开发
|
||||
const files = readAllFile(join(process.cwd(), OUT_DIR), FILE_REG);
|
36
build/plugin/gzip/compress.ts
Normal file
36
build/plugin/gzip/compress.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { gzip } from 'zlib';
|
||||
import { readFileSync, writeFileSync } from 'fs';
|
||||
import { GzipPluginOptions } from './types';
|
||||
import viteConfig from '../../vite.config';
|
||||
import { readAllFile, getCwdPath, isBuildGzip, isSiteMode } from '../utils';
|
||||
|
||||
export function startGzip(
|
||||
fileContent: string | Buffer,
|
||||
options: GzipPluginOptions = {}
|
||||
): Promise<Buffer> {
|
||||
return new Promise((resolve, reject) => {
|
||||
gzip(fileContent, options.gzipOptions || {}, (err, result) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 手动压缩css
|
||||
export async function startGzipStyle() {
|
||||
if (isBuildGzip() || isSiteMode()) {
|
||||
const outDir = viteConfig.outDir || 'dist';
|
||||
const assets = viteConfig.assetsDir || '_assets';
|
||||
const allCssFile = readAllFile(getCwdPath(outDir, assets), /\.(css)$/);
|
||||
for (const path of allCssFile) {
|
||||
const source = readFileSync(path);
|
||||
const content = await startGzip(source);
|
||||
const ds = path.split('/');
|
||||
const fileName = ds[ds.length - 1];
|
||||
writeFileSync(getCwdPath(outDir, assets, `${fileName}.gz`), content);
|
||||
}
|
||||
}
|
||||
}
|
195
build/plugin/gzip/index.ts
Normal file
195
build/plugin/gzip/index.ts
Normal file
@@ -0,0 +1,195 @@
|
||||
// 修改自https://github.com/kryops/rollup-plugin-gzip
|
||||
// 因为rollup-plugin-gzip不支持vite
|
||||
// vite对css打包独立的。所以不能在打包的时候顺带打包css
|
||||
|
||||
import { readFile, writeFile } from 'fs';
|
||||
import { basename } from 'path';
|
||||
import { promisify } from 'util';
|
||||
import { gzip } from 'zlib';
|
||||
|
||||
import { OutputAsset, OutputChunk, OutputOptions, Plugin } from 'rollup';
|
||||
import { GzipPluginOptions } from './types';
|
||||
|
||||
const isFunction = (arg: unknown): arg is (...args: any[]) => any => typeof arg === 'function';
|
||||
const isRegExp = (arg: unknown): arg is RegExp =>
|
||||
Object.prototype.toString.call(arg) === '[object RegExp]';
|
||||
|
||||
export type StringMappingOption = (originalString: string) => string;
|
||||
export type CustomCompressionOption = (
|
||||
content: string | Buffer
|
||||
) => string | Buffer | Promise<string | Buffer>;
|
||||
|
||||
const readFilePromise = promisify(readFile);
|
||||
const writeFilePromise = promisify(writeFile);
|
||||
|
||||
// functionality partially copied from rollup
|
||||
|
||||
/**
|
||||
* copied from https://github.com/rollup/rollup/blob/master/src/rollup/index.ts#L450
|
||||
*/
|
||||
function isOutputChunk(file: OutputAsset | OutputChunk): file is OutputChunk {
|
||||
return typeof (file as OutputChunk).code === 'string';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string/buffer content from a file object.
|
||||
* Important for adding source map comments
|
||||
*
|
||||
* Copied partially from rollup.writeOutputFile
|
||||
* https://github.com/rollup/rollup/blob/master/src/rollup/index.ts#L454
|
||||
*/
|
||||
function getOutputFileContent(
|
||||
outputFileName: string,
|
||||
outputFile: OutputAsset | OutputChunk,
|
||||
outputOptions: OutputOptions
|
||||
): string | Buffer {
|
||||
if (isOutputChunk(outputFile)) {
|
||||
let source: string | Buffer;
|
||||
source = outputFile.code;
|
||||
if (outputOptions.sourcemap && outputFile.map) {
|
||||
const url =
|
||||
outputOptions.sourcemap === 'inline'
|
||||
? outputFile.map.toUrl()
|
||||
: `${basename(outputFileName)}.map`;
|
||||
|
||||
// https://github.com/rollup/rollup/blob/master/src/utils/sourceMappingURL.ts#L1
|
||||
source += `//# source` + `MappingURL=${url}\n`;
|
||||
}
|
||||
return source;
|
||||
} else {
|
||||
return typeof outputFile.source === 'string'
|
||||
? outputFile.source
|
||||
: // just to be sure, as it is typed string | Uint8Array in rollup 2.0.0
|
||||
Buffer.from(outputFile.source);
|
||||
}
|
||||
}
|
||||
|
||||
// actual plugin code
|
||||
|
||||
function gzipPlugin(options: GzipPluginOptions = {}): Plugin {
|
||||
// check for old options
|
||||
if ('algorithm' in options) {
|
||||
console.warn(
|
||||
'[rollup-plugin-gzip] The "algorithm" option is not supported any more! ' +
|
||||
'Use "customCompression" instead to specify a different compression algorithm.'
|
||||
);
|
||||
}
|
||||
if ('options' in options) {
|
||||
console.warn('[rollup-plugin-gzip] The "options" option was renamed to "gzipOptions"!');
|
||||
}
|
||||
if ('additional' in options) {
|
||||
console.warn('[rollup-plugin-gzip] The "additional" option was renamed to "additionalFiles"!');
|
||||
}
|
||||
if ('delay' in options) {
|
||||
console.warn('[rollup-plugin-gzip] The "delay" option was renamed to "additionalFilesDelay"!');
|
||||
}
|
||||
|
||||
const compressGzip: CustomCompressionOption = (fileContent) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
gzip(fileContent, options.gzipOptions || {}, (err, result) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const doCompress = options.customCompression || compressGzip;
|
||||
|
||||
const mapFileName: StringMappingOption = isFunction(options.fileName)
|
||||
? (options.fileName as StringMappingOption)
|
||||
: (fileName: string) => fileName + (options.fileName || '.gz');
|
||||
|
||||
const plugin: Plugin = {
|
||||
name: 'gzip',
|
||||
|
||||
generateBundle(outputOptions, bundle) {
|
||||
return Promise.all(
|
||||
Object.keys(bundle)
|
||||
.map((fileName) => {
|
||||
const fileEntry = bundle[fileName];
|
||||
|
||||
// file name filter option check
|
||||
|
||||
const fileNameFilter = options.filter || /\.(js|mjs|json|css|html)$/;
|
||||
|
||||
if (isRegExp(fileNameFilter) && !fileName.match(fileNameFilter)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (
|
||||
isFunction(fileNameFilter) &&
|
||||
!(fileNameFilter as (x: string) => boolean)(fileName)
|
||||
) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const fileContent = getOutputFileContent(fileName, fileEntry, outputOptions);
|
||||
|
||||
// minSize option check
|
||||
if (options.minSize && options.minSize > fileContent.length) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return Promise.resolve(doCompress(fileContent))
|
||||
.then((compressedContent) => {
|
||||
const compressedFileName = mapFileName(fileName);
|
||||
bundle[compressedFileName] = {
|
||||
type: 'asset', // Rollup >= 1.21
|
||||
name: compressedFileName,
|
||||
fileName: compressedFileName,
|
||||
isAsset: true, // Rollup < 1.21
|
||||
source: compressedContent,
|
||||
};
|
||||
})
|
||||
.catch((err: any) => {
|
||||
console.error(err);
|
||||
return Promise.reject('[rollup-plugin-gzip] Error compressing file ' + fileName);
|
||||
});
|
||||
})
|
||||
.concat([
|
||||
(() => {
|
||||
if (!options.additionalFiles || !options.additionalFiles.length)
|
||||
return Promise.resolve();
|
||||
|
||||
const compressAdditionalFiles = () =>
|
||||
Promise.all(
|
||||
options.additionalFiles!.map((filePath) =>
|
||||
readFilePromise(filePath)
|
||||
.then((fileContent) => doCompress(fileContent))
|
||||
.then((compressedContent) => {
|
||||
return writeFilePromise(mapFileName(filePath), compressedContent);
|
||||
})
|
||||
.catch(() => {
|
||||
return Promise.reject(
|
||||
'[rollup-plugin-gzip] Error compressing additional file ' +
|
||||
filePath +
|
||||
'. Please check the spelling of your configured additionalFiles. ' +
|
||||
'You might also have to increase the value of the additionalFilesDelay option.'
|
||||
);
|
||||
})
|
||||
)
|
||||
) as Promise<any>;
|
||||
|
||||
// additional files can be processed outside of rollup after a delay
|
||||
// for older plugins or plugins that write to disk (curcumventing rollup) without awaiting
|
||||
const additionalFilesDelay = options.additionalFilesDelay || 0;
|
||||
|
||||
if (additionalFilesDelay) {
|
||||
setTimeout(compressAdditionalFiles, additionalFilesDelay);
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return compressAdditionalFiles();
|
||||
}
|
||||
})(),
|
||||
])
|
||||
) as Promise<any>;
|
||||
},
|
||||
};
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
export default gzipPlugin;
|
@@ -49,8 +49,9 @@ const globbyTransform = function (config: SharedConfig): Transform {
|
||||
let result = cache.get(path);
|
||||
if (!result) {
|
||||
const reg = /import\s+([\w\s{}*]+)\s+from\s+(['"])globby(\?path)?!([^'"]+)\2/g;
|
||||
const lastImport = urlMap.get(path);
|
||||
const match = code.match(reg);
|
||||
if (!match) return code;
|
||||
const lastImport = urlMap.get(path);
|
||||
if (lastImport && match) {
|
||||
code = code.replace(lastImport, match[0]);
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ import { argv } from 'yargs';
|
||||
import { runBuildConfig } from './buildConf';
|
||||
import { runUpdateHtml } from './updateHtml';
|
||||
import { errorConsole, successConsole } from '../utils';
|
||||
import { startGzipStyle } from '../plugin/gzip/compress';
|
||||
|
||||
export const runBuild = async () => {
|
||||
try {
|
||||
@@ -22,6 +23,7 @@ export const runBuild = async () => {
|
||||
await runBuildConfig();
|
||||
}
|
||||
await runUpdateHtml();
|
||||
await startGzipStyle();
|
||||
successConsole('Vite Build successfully!');
|
||||
} catch (error) {
|
||||
errorConsole('Vite Build Error\n' + error);
|
||||
|
@@ -1,12 +1,12 @@
|
||||
import chalk from 'chalk';
|
||||
import Koa from 'koa';
|
||||
import inquirer from 'inquirer';
|
||||
import { sh } from 'tasksfile';
|
||||
import staticServer from 'koa-static';
|
||||
import portfinder from 'portfinder';
|
||||
import { resolve } from 'path';
|
||||
import viteConfig from '../../vite.config';
|
||||
import { getIPAddress } from '../utils';
|
||||
import { runBuild } from './build';
|
||||
|
||||
const BUILD = 1;
|
||||
const NO_BUILD = 2;
|
||||
@@ -53,10 +53,7 @@ export const runPreview = async () => {
|
||||
});
|
||||
const { type } = await prompt;
|
||||
if (type === BUILD) {
|
||||
await sh('npm run build', {
|
||||
async: true,
|
||||
nopipe: true,
|
||||
});
|
||||
runBuild();
|
||||
}
|
||||
startApp();
|
||||
};
|
||||
|
@@ -70,6 +70,12 @@ export function isProdFn(): boolean {
|
||||
export function isReportMode(): boolean {
|
||||
return process.env.REPORT === 'true';
|
||||
}
|
||||
export function isBuildGzip(): boolean {
|
||||
return process.env.VITE_BUILD_GZIP === 'true';
|
||||
}
|
||||
export function isSiteMode(): boolean {
|
||||
return process.env.SITE === 'true';
|
||||
}
|
||||
|
||||
export interface ViteEnv {
|
||||
VITE_PORT: number;
|
||||
@@ -78,6 +84,8 @@ export interface ViteEnv {
|
||||
VITE_PROXY: [string, string][];
|
||||
VITE_GLOB_APP_TITLE: string;
|
||||
VITE_USE_CDN: boolean;
|
||||
VITE_DROP_CONSOLE: boolean;
|
||||
VITE_BUILD_GZIP: boolean;
|
||||
}
|
||||
|
||||
export function loadEnv(): ViteEnv {
|
||||
|
Reference in New Issue
Block a user