mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-26 08:36:19 +08:00
initial commit
This commit is contained in:
26
build/config/glob/lessModifyVars.ts
Normal file
26
build/config/glob/lessModifyVars.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* less global variable
|
||||
*/
|
||||
const primaryColor = '#018ffb';
|
||||
//{
|
||||
const modifyVars = {
|
||||
'primary-color': primaryColor, // Global dominant color
|
||||
'info-color': primaryColor, // Default color
|
||||
'success-color': '#55D187', // Success color
|
||||
'error-color': '#ED6F6F', // False color
|
||||
'warning-color': '#EFBD47', // Warning color
|
||||
'link-color': primaryColor, // Link color
|
||||
'disabled-color': '#C2C2CC', // Failure color
|
||||
'heading-color': '#2C3A61', // Title color
|
||||
'text-color': '#2C3A61', // Main text color
|
||||
'text-color-secondary ': '#606266', // Subtext color
|
||||
'background-color-base': '#F0F2F5', // background color
|
||||
'font-size-base': '14px', // Main font size
|
||||
'box-shadow-base': '0 2px 8px rgba(0, 0, 0, 0.15)', // Floating shadow
|
||||
'border-color-base': '#cececd', // Border color,
|
||||
'border-color-split': '#cececd', // Border color,
|
||||
'border-radius-base': '2px', // Component/float fillet
|
||||
};
|
||||
//}
|
||||
|
||||
export { modifyVars, primaryColor };
|
10
build/config/vite/env.ts
Normal file
10
build/config/vite/env.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import moment from 'moment';
|
||||
// @ts-ignore
|
||||
import pkg from '../../../package.json';
|
||||
export function setupBasicEnv() {
|
||||
// version
|
||||
process.env.VITE_VERSION = (pkg as any).version;
|
||||
// build time
|
||||
process.env.VITE_APP_BUILD_TIME = moment().format('YYYY-MM-DD HH:mm:ss');
|
||||
process.env.VITE_BUILD_SHORT_TIME = moment().format('MMDDHHmmss');
|
||||
}
|
15
build/config/vite/proxy.ts
Normal file
15
build/config/vite/proxy.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
type ProxyItem = [string, string];
|
||||
|
||||
type ProxyList = ProxyItem[];
|
||||
|
||||
export function createProxy(list: ProxyList) {
|
||||
const ret: any = {};
|
||||
for (const [prefix, target] of list) {
|
||||
ret[prefix] = {
|
||||
target: target,
|
||||
changeOrigin: true,
|
||||
rewrite: (path: string) => path.replace(new RegExp(`^${prefix}`), ''),
|
||||
};
|
||||
}
|
||||
return ret;
|
||||
}
|
22
build/gzip/index.ts
Normal file
22
build/gzip/index.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
// 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);
|
56
build/gzip/types.ts
Normal file
56
build/gzip/types.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import type { ZlibOptions } from 'zlib';
|
||||
|
||||
export type StringMappingOption = (originalString: string) => string;
|
||||
export type CustomCompressionOption = (
|
||||
content: string | Buffer
|
||||
) => string | Buffer | Promise<string | Buffer>;
|
||||
|
||||
export interface GzipPluginOptions {
|
||||
/**
|
||||
* Control which of the output files to compress
|
||||
*
|
||||
* Defaults to `/\.(js|mjs|json|css|html)$/`
|
||||
*/
|
||||
filter?: RegExp | ((fileName: string) => boolean);
|
||||
|
||||
/**
|
||||
* GZIP compression options, see https://nodejs.org/api/zlib.html#zlib_class_options
|
||||
*/
|
||||
gzipOptions?: ZlibOptions;
|
||||
|
||||
/**
|
||||
* Specified the minimum size in Bytes for a file to get compressed.
|
||||
* Files that are smaller than this threshold will not be compressed.
|
||||
* This does not apply to the files specified through `additionalFiles`!
|
||||
*/
|
||||
minSize?: number;
|
||||
|
||||
/**
|
||||
* This option allows you to compress additional files outside of the main rollup bundling process.
|
||||
* The processing is delayed to make sure the files are written on disk; the delay is controlled
|
||||
* through `additionalFilesDelay`.
|
||||
*/
|
||||
additionalFiles?: string[];
|
||||
|
||||
/**
|
||||
* This options sets a delay (ms) before the plugin compresses the files specified through `additionalFiles`.
|
||||
* Increase this value if your artifacts take a long time to generate.
|
||||
*
|
||||
* Defaults to `2000`
|
||||
*/
|
||||
additionalFilesDelay?: number;
|
||||
|
||||
/**
|
||||
* Set a custom compression algorithm. The function can either return the compressed contents synchronously,
|
||||
* or otherwise return a promise for asynchronous processing.
|
||||
*/
|
||||
customCompression?: CustomCompressionOption;
|
||||
|
||||
/**
|
||||
* Set a custom file name convention for the compressed files. Can be a suffix string or a function
|
||||
* returning the file name.
|
||||
*
|
||||
* Defaults to `.gz`
|
||||
*/
|
||||
fileName?: string | StringMappingOption;
|
||||
}
|
39
build/script/changelog.ts
Normal file
39
build/script/changelog.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
// #!/usr/bin/env node
|
||||
|
||||
import { sh } from 'tasksfile';
|
||||
import chalk from 'chalk';
|
||||
|
||||
const createChangeLog = async () => {
|
||||
try {
|
||||
let cmd = `conventional-changelog -p angular -i CHANGELOG.md -s -r 0 `;
|
||||
// let cmd = `conventional-changelog -p angular -i CHANGELOG.md -s -r 0 `;
|
||||
// if (shell.which('git')) {
|
||||
// cmd += '&& git add CHANGELOG.md';
|
||||
// }
|
||||
await sh(cmd, {
|
||||
async: true,
|
||||
nopipe: true,
|
||||
});
|
||||
|
||||
await sh('prettier --write **/CHANGELOG.md ', {
|
||||
async: true,
|
||||
nopipe: true,
|
||||
});
|
||||
console.log(
|
||||
chalk.blue.bold('**************** ') +
|
||||
chalk.green.bold('CHANGE_LOG generated successfully!') +
|
||||
chalk.blue.bold(' ****************')
|
||||
);
|
||||
} catch (error) {
|
||||
console.log(
|
||||
chalk.blue.red('**************** ') +
|
||||
chalk.green.red('CHANGE_LOG generated error\n' + error) +
|
||||
chalk.blue.red(' ****************')
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
createChangeLog();
|
||||
module.exports = {
|
||||
createChangeLog,
|
||||
};
|
10
build/script/postinstall.ts
Normal file
10
build/script/postinstall.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { exec, which } from 'shelljs';
|
||||
|
||||
function ignoreCaseGit() {
|
||||
try {
|
||||
if (which('git')) {
|
||||
exec('git config core.ignorecase false ');
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
ignoreCaseGit();
|
67
build/script/preserve.ts
Normal file
67
build/script/preserve.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
// 是否需要更新依赖,防止package.json更新了依赖,其他人获取代码后没有install
|
||||
|
||||
import path from 'path';
|
||||
import fs from 'fs-extra';
|
||||
import { isEqual } from 'lodash';
|
||||
import chalk from 'chalk';
|
||||
import { sh } from 'tasksfile';
|
||||
|
||||
const resolve = (dir: string) => {
|
||||
return path.resolve(process.cwd(), dir);
|
||||
};
|
||||
|
||||
let NEED_INSTALL = false;
|
||||
|
||||
fs.mkdirp(resolve('build/.cache'));
|
||||
function checkPkgUpdate() {
|
||||
const pkg = require('../../package.json');
|
||||
const { dependencies, devDependencies } = pkg;
|
||||
const depsFile = resolve('build/.cache/deps.json');
|
||||
if (!fs.pathExistsSync(depsFile)) {
|
||||
NEED_INSTALL = true;
|
||||
return;
|
||||
}
|
||||
const depsJson = require('../.cache/deps.json');
|
||||
|
||||
if (!isEqual(depsJson, { dependencies, devDependencies })) {
|
||||
NEED_INSTALL = true;
|
||||
}
|
||||
}
|
||||
checkPkgUpdate();
|
||||
|
||||
(async () => {
|
||||
if (NEED_INSTALL) {
|
||||
console.log(
|
||||
chalk.blue.bold('**************** ') +
|
||||
chalk.red.bold('检测到依赖变化,正在安装依赖(Tip: 项目首次运行也会执行)!') +
|
||||
chalk.blue.bold(' ****************')
|
||||
);
|
||||
try {
|
||||
// 从代码执行貌似不会自动读取.npmrc 所以手动加上源地址
|
||||
// await run('yarn install --registry=https://registry.npm.taobao.org ', {
|
||||
await sh('yarn install ', {
|
||||
async: true,
|
||||
nopipe: true,
|
||||
});
|
||||
console.log(
|
||||
chalk.blue.bold('**************** ') +
|
||||
chalk.green.bold('依赖安装成功,正在运行!') +
|
||||
chalk.blue.bold(' ****************')
|
||||
);
|
||||
|
||||
const pkg = require('../../package.json');
|
||||
const { dependencies, devDependencies } = pkg;
|
||||
const depsFile = resolve('build/.cache/deps.json');
|
||||
const deps = { dependencies, devDependencies };
|
||||
if (!fs.pathExistsSync(depsFile)) {
|
||||
fs.writeFileSync(depsFile, JSON.stringify(deps));
|
||||
} else {
|
||||
const depsFile = resolve('build/.cache/deps.json');
|
||||
const depsJson = require('../.cache/deps.json');
|
||||
if (!isEqual(depsJson, deps)) {
|
||||
fs.writeFileSync(depsFile, JSON.stringify(deps));
|
||||
}
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
})();
|
70
build/script/preview.ts
Normal file
70
build/script/preview.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
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';
|
||||
|
||||
const BUILD = 1;
|
||||
const NO_BUILD = 2;
|
||||
|
||||
// 启动服务器
|
||||
const startApp = () => {
|
||||
const port = 9680;
|
||||
portfinder.basePort = port;
|
||||
const app = new Koa();
|
||||
// const connect = require('connect');
|
||||
// const serveStatic = require('serve-static');
|
||||
// const app = connect();
|
||||
|
||||
app.use(staticServer(resolve(process.cwd(), viteConfig.outDir || 'dist')));
|
||||
|
||||
portfinder.getPort(async (err, port) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
} else {
|
||||
// const publicPath = process.env.BASE_URL;
|
||||
app.listen(port, function () {
|
||||
const empty = ' ';
|
||||
const common = `The preview program is already running:
|
||||
- LOCAL: http://localhost:${port}/
|
||||
- NETWORK: http://${getIPAddress()}:${port}/
|
||||
`;
|
||||
console.log(chalk.cyan('\n' + empty + common));
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const preview = async () => {
|
||||
const prompt = inquirer.prompt({
|
||||
type: 'list',
|
||||
message: 'Please select a preview method',
|
||||
name: 'type',
|
||||
choices: [
|
||||
{
|
||||
name: 'Preview after packaging',
|
||||
value: BUILD,
|
||||
},
|
||||
{
|
||||
name: `No packaging, preview directly (need to have dist file after packaging)`,
|
||||
value: NO_BUILD,
|
||||
},
|
||||
],
|
||||
});
|
||||
const { type } = await prompt;
|
||||
if (type === BUILD) {
|
||||
await sh('npm run build', {
|
||||
async: true,
|
||||
nopipe: true,
|
||||
});
|
||||
}
|
||||
startApp();
|
||||
};
|
||||
|
||||
(() => {
|
||||
preview();
|
||||
})();
|
18
build/tsconfig.json
Normal file
18
build/tsconfig.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"jsx": "react",
|
||||
"baseUrl": ".",
|
||||
"esModuleInterop": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"experimentalDecorators": true,
|
||||
"lib": ["dom", "esnext"],
|
||||
"incremental": true,
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
87
build/utils.ts
Normal file
87
build/utils.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import fs from 'fs';
|
||||
import { networkInterfaces } from 'os';
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
export const isFunction = (arg: unknown): arg is (...args: any[]) => any =>
|
||||
typeof arg === 'function';
|
||||
export const isRegExp = (arg: unknown): arg is RegExp =>
|
||||
Object.prototype.toString.call(arg) === '[object RegExp]';
|
||||
|
||||
/*
|
||||
* Read all files in the specified folder, filter through regular rules, and return file path array
|
||||
* @param root Specify the folder path
|
||||
* [@param] reg Regular expression for filtering files, optional parameters
|
||||
* Note: It can also be deformed to check whether the file path conforms to regular rules. The path can be a folder or a file. The path that does not exist is also fault-tolerant.
|
||||
*/
|
||||
export function readAllFile(root: string, reg: RegExp) {
|
||||
let resultArr: string[] = [];
|
||||
try {
|
||||
if (fs.existsSync(root)) {
|
||||
const stat = fs.lstatSync(root);
|
||||
if (stat.isDirectory()) {
|
||||
// dir
|
||||
const files = fs.readdirSync(root);
|
||||
files.forEach(function (file) {
|
||||
const t = readAllFile(root + '/' + file, reg);
|
||||
resultArr = resultArr.concat(t);
|
||||
});
|
||||
} else {
|
||||
if (reg !== undefined) {
|
||||
if (isFunction(reg.test) && reg.test(root)) {
|
||||
resultArr.push(root);
|
||||
}
|
||||
} else {
|
||||
resultArr.push(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {}
|
||||
|
||||
return resultArr;
|
||||
}
|
||||
|
||||
export function getIPAddress() {
|
||||
let interfaces = networkInterfaces();
|
||||
for (let devName in interfaces) {
|
||||
let iFace = interfaces[devName];
|
||||
if (!iFace) return;
|
||||
for (let i = 0; i < iFace.length; i++) {
|
||||
let alias = iFace[i];
|
||||
if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
|
||||
return alias.address;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
export function isDevFn(): boolean {
|
||||
return process.env.NODE_ENV === 'development';
|
||||
}
|
||||
|
||||
export function isProdFn(): boolean {
|
||||
return process.env.NODE_ENV === 'production';
|
||||
}
|
||||
|
||||
export function isReportMode(): boolean {
|
||||
return process.env.REPORT === 'true';
|
||||
}
|
||||
|
||||
export function loadEnv() {
|
||||
const env = process.env.NODE_ENV;
|
||||
const ret: any = {};
|
||||
const envList = [`.env.${env}.local`, `.env.${env}`, '.env.local', '.env', ,];
|
||||
envList.forEach((e) => {
|
||||
dotenv.config({
|
||||
path: e,
|
||||
});
|
||||
});
|
||||
|
||||
for (const envName of Object.keys(process.env)) {
|
||||
const realName = (process.env as any)[envName].replace(/\\n/g, '\n');
|
||||
ret[envName] = realName;
|
||||
process.env[envName] = realName;
|
||||
}
|
||||
return ret;
|
||||
}
|
Reference in New Issue
Block a user