first commit

This commit is contained in:
zhangchuanlong
2022-01-08 17:20:46 +08:00
commit 8d0158be7c
80 changed files with 5240 additions and 0 deletions

3
build/constant.js Normal file
View File

@@ -0,0 +1,3 @@
export const GLOB_CONFIG_FILE_NAME = 'app.config.js'
export const GLOB_CONFIG_NAME = '__APP__GLOB__CONF__'
export const OUTPUT_DIR = 'dist'

View File

@@ -0,0 +1,29 @@
import { GLOB_CONFIG_FILE_NAME, GLOB_CONFIG_NAME, OUTPUT_DIR } from '../constant'
import fs, { writeFileSync } from 'fs-extra'
import chalk from 'chalk'
import { getEnvConfig, getRootPath } from '../utils'
function createConfig(option) {
const { config, configName, configFileName } = option
try {
const windowConf = `window.${configName}`
const configStr = `${windowConf}=${JSON.stringify(config)};
Object.freeze(${windowConf});
Object.defineProperty(window, "${configName}", {
configurable: false,
writable: false,
});
`.replace(/\s/g, '')
fs.mkdirp(getRootPath(OUTPUT_DIR))
writeFileSync(getRootPath(`${OUTPUT_DIR}/${configFileName}`), configStr)
} catch (error) {
console.log(chalk.red('configuration file configuration file failed to package:\n' + error))
}
}
export function runBuildConfig() {
const config = getEnvConfig()
const configName = GLOB_CONFIG_NAME
const configFileName = GLOB_CONFIG_FILE_NAME
createConfig({ config, configName, configFileName })
}

14
build/script/index.js Normal file
View File

@@ -0,0 +1,14 @@
import chalk from 'chalk'
import { runBuildConfig } from './build-config'
export const runBuild = async () => {
try {
runBuildConfig()
console.log(`${chalk.cyan('build successfully!')}`)
} catch (error) {
console.log(chalk.red('vite build error:\n' + error))
process.exit(1)
}
}
runBuild()

69
build/utils.js Normal file
View File

@@ -0,0 +1,69 @@
import fs from 'fs'
import path from 'path'
import dotenv from 'dotenv'
export function wrapperEnv(envOptions) {
if (!envOptions) return {}
const ret = {}
for (const key in envOptions) {
let val = envOptions[key]
if (['true', 'false'].includes(val)) {
val = val === 'true'
}
if (['VITE_PORT'].includes(key)) {
val = +val
}
if (key === 'VITE_PROXY' && val) {
try {
val = JSON.parse(val.replace(/'/g, '"'))
} catch (error) {
val = ''
}
}
ret[key] = val
if (typeof key === 'string') {
process.env[key] = val
} else if (typeof key === 'object') {
process.env[key] = JSON.stringify(val)
}
}
return ret
}
/**
* 获取当前环境下生效的配置文件名
*/
function getConfFiles() {
const script = process.env.npm_lifecycle_script
const reg = new RegExp('--mode ([a-z_\\d]+)')
const result = reg.exec(script)
if (result) {
const mode = result[1]
return ['.env', `.env.${mode}`]
}
return ['.env', '.env.production']
}
export function getEnvConfig(match = 'VITE_APP_GLOB_', confFiles = getConfFiles()) {
let envConfig = {}
confFiles.forEach((item) => {
try {
const env = dotenv.parse(fs.readFileSync(path.resolve(process.cwd(), item)))
envConfig = { ...envConfig, ...env }
} catch (e) {
console.error(`Error in parsing ${item}`, e)
}
})
const reg = new RegExp(`^(${match})`)
Object.keys(envConfig).forEach((key) => {
if (!reg.test(key)) {
Reflect.deleteProperty(envConfig, key)
}
})
return envConfig
}
export function getRootPath(...dir) {
return path.resolve(process.cwd(), ...dir)
}

32
build/vite/plugin/html.js Normal file
View File

@@ -0,0 +1,32 @@
import html from 'vite-plugin-html'
import { version } from '../../../package.json'
import { GLOB_CONFIG_FILE_NAME } from '../../constant'
export function configHtmlPlugin(viteEnv, isBuild) {
const { VITE_APP_TITLE, VITE_PUBLIC_PATH } = viteEnv
const path = VITE_PUBLIC_PATH.endsWith('/') ? VITE_PUBLIC_PATH : `${VITE_PUBLIC_PATH}/`
const getAppConfigSrc = () => {
return `${path}${GLOB_CONFIG_FILE_NAME}?v=${version}-${new Date().getTime()}`
}
const htmlPlugin = html({
minify: isBuild,
inject: {
data: {
title: VITE_APP_TITLE,
},
tags: isBuild
? [
{
tag: 'script',
attrs: {
src: getAppConfigSrc(),
},
},
]
: [],
},
})
return htmlPlugin
}

View File

@@ -0,0 +1,12 @@
import vue from '@vitejs/plugin-vue'
import { configHtmlPlugin } from './html'
import { configMockPlugin } from './mock'
import { unocss } from './unocss'
export function createVitePlugins(viteEnv, isBuild) {
const plugins = [vue(), unocss(), configHtmlPlugin(viteEnv, isBuild)]
viteEnv?.VITE_APP_USE_MOCK && plugins.push(configMockPlugin(isBuild))
return plugins
}

14
build/vite/plugin/mock.js Normal file
View File

@@ -0,0 +1,14 @@
import { viteMockServe } from 'vite-plugin-mock'
export function configMockPlugin(isBuild) {
return viteMockServe({
ignore: /^\_/,
mockPath: 'mock',
localEnabled: !isBuild,
prodEnabled: isBuild,
injectCode: `
import { setupProdMockServer } from '../mock/_createProdServer';
setupProdMockServer();
`,
})
}

View File

@@ -0,0 +1,9 @@
import Unocss from 'unocss/vite'
import { presetUno, presetAttributify, presetIcons } from 'unocss'
// https://github.com/antfu/unocss
export function unocss() {
return Unocss({
presets: [presetUno(), presetAttributify(), presetIcons()],
})
}

18
build/vite/proxy.js Normal file
View File

@@ -0,0 +1,18 @@
const httpsRE = /^https:\/\//
export function createProxy(list = []) {
const ret = {}
for (const [prefix, target] of list) {
const isHttps = httpsRE.test(target)
// https://github.com/http-party/node-http-proxy#options
ret[prefix] = {
target: target,
changeOrigin: true,
ws: true,
rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''),
// https is require secure=false
...(isHttps ? { secure: false } : {}),
}
}
return ret
}