29 changed files with 562 additions and 117 deletions
@ -0,0 +1,21 @@ |
|||
const css = ['//cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.min.css']; |
|||
|
|||
// TODO use esm?
|
|||
const js = [ |
|||
'//cdn.bootcdn.net/ajax/libs/vue/3.0.0/vue.global.prod.js', |
|||
'//cdn.bootcdn.net/ajax/libs/vue-router/4.0.0-beta.13/vue-router.global.min.js', |
|||
'//cdn.bootcdn.net/ajax/libs/vuex/4.0.0-beta.4/vuex.global.prod.js', |
|||
'//cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.min.js', |
|||
'//cdn.bootcdn.net/ajax/libs/qs/6.9.4/qs.min.js', |
|||
'//cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.min.js', |
|||
// '//cdn.bootcdn.net/ajax/libs/lodash.js/4.17.15/lodash.min.js',
|
|||
// '//cdn.bootcdn.net/ajax/libs/crypto-js/3.3.0/crypto-js.min.js',
|
|||
// '//cdn.bootcdn.net/ajax/libs/vue-i18n/8.18.1/vue-i18n.min.js',
|
|||
]; |
|||
|
|||
export const externals = ['vue', 'vuex', 'vue-router', 'axios', 'qs', 'nprogress']; |
|||
|
|||
export const cdnConf = { |
|||
css, |
|||
js, |
|||
}; |
|||
@ -1,10 +0,0 @@ |
|||
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'); |
|||
} |
|||
@ -0,0 +1 @@ |
|||
export const GLOB_CONFIG_FILE_NAME = '_app.config.js'; |
|||
@ -0,0 +1,5 @@ |
|||
export const getShortName = (env: any) => { |
|||
return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__` |
|||
.toUpperCase() |
|||
.replace(/\s/g, ''); |
|||
}; |
|||
@ -0,0 +1,36 @@ |
|||
// js调用cli 兼容调用ts
|
|||
|
|||
const { sh } = require('tasksfile'); |
|||
const { argv } = require('yargs'); |
|||
|
|||
let command = ``; |
|||
|
|||
Object.keys(argv).forEach((key) => { |
|||
if (!/^\$/.test(key) && key !== '_') { |
|||
// @ts-ignore
|
|||
if (argv[key]) { |
|||
command += `--${key} `; |
|||
} |
|||
} |
|||
}); |
|||
|
|||
// 执行任务名称
|
|||
let taskList = argv._; |
|||
|
|||
let NODE_ENV = process.env.NODE_ENV || 'development'; |
|||
|
|||
if (taskList.includes('build') || taskList.includes('report') || taskList.includes('preview')) { |
|||
NODE_ENV = 'production'; |
|||
} |
|||
|
|||
if (taskList && Array.isArray(taskList) && taskList.length) { |
|||
sh( |
|||
`cross-env NODE_ENV=${NODE_ENV} ts-node --project ./build/tsconfig.json ./build/script/cli.ts ${taskList.join( |
|||
' ' |
|||
)} ${command}`,
|
|||
{ |
|||
async: true, |
|||
nopipe: true, |
|||
} |
|||
); |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
// #!/usr/bin/env node
|
|||
|
|||
import { sh } from 'tasksfile'; |
|||
import { argv } from 'yargs'; |
|||
import { runBuildConfig } from './buildConf'; |
|||
import { runUpdateHtml } from './updateHtml'; |
|||
import { errorConsole, successConsole } from '../utils'; |
|||
|
|||
export const runBuild = async () => { |
|||
try { |
|||
const argvList = argv._; |
|||
let cmd = `cross-env NODE_ENV=production vite build`; |
|||
await sh(cmd, { |
|||
async: true, |
|||
nopipe: true, |
|||
}); |
|||
|
|||
// Generate configuration file
|
|||
if (!argvList.includes('no-conf')) { |
|||
await runBuildConfig(); |
|||
} |
|||
await runUpdateHtml(); |
|||
successConsole('Vite Build successfully!'); |
|||
} catch (error) { |
|||
errorConsole('Vite Build Error\n' + error); |
|||
process.exit(1); |
|||
} |
|||
}; |
|||
@ -0,0 +1,44 @@ |
|||
import { GLOB_CONFIG_FILE_NAME } from '../constant'; |
|||
import fs, { writeFileSync } from 'fs-extra'; |
|||
|
|||
import viteConfig from '../../vite.config'; |
|||
import { errorConsole, successConsole, getCwdPath, getEnvConfig } from '../utils'; |
|||
|
|||
const getShortName = (env: any) => { |
|||
return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__` |
|||
.toUpperCase() |
|||
.replace(/\s/g, ''); |
|||
}; |
|||
|
|||
function createConfig( |
|||
{ |
|||
configName, |
|||
config, |
|||
configFileName = GLOB_CONFIG_FILE_NAME, |
|||
}: { configName: string; config: any; configFileName?: string } = { configName: '', config: {} } |
|||
) { |
|||
try { |
|||
const windowConf = `window.${configName}`; |
|||
const outDir = viteConfig.outDir || 'dist'; |
|||
const configStr = `${windowConf}=${JSON.stringify(config)};
|
|||
|
|||
Object.freeze(${windowConf}); |
|||
Object.defineProperty(window, "${configName}", { |
|||
configurable: false, |
|||
writable: false, |
|||
}); |
|||
`;
|
|||
fs.mkdirp(getCwdPath(outDir)); |
|||
writeFileSync(getCwdPath(`${outDir}/${configFileName}`), configStr); |
|||
|
|||
successConsole('The configuration file is build successfully!'); |
|||
} catch (error) { |
|||
errorConsole('Configuration file configuration file failed to package\n' + error); |
|||
} |
|||
} |
|||
|
|||
export function runBuildConfig() { |
|||
const config = getEnvConfig(); |
|||
const configFileName = getShortName(config); |
|||
createConfig({ config, configName: configFileName }); |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
#!/usr/bin/env node |
|||
|
|||
import chalk from 'chalk'; |
|||
import { argv } from 'yargs'; |
|||
|
|||
import { runChangeLog } from './changelog'; |
|||
import { runPostInstall } from './postinstall'; |
|||
import { runPreview } from './preview'; |
|||
import { runPreserve } from './preserve'; |
|||
import { runBuild } from './build'; |
|||
|
|||
const task = (argv._ || [])[0]; |
|||
|
|||
console.log('Run Task: ' + chalk.cyan(task)); |
|||
|
|||
switch (task) { |
|||
// change log
|
|||
case 'log': |
|||
runChangeLog(); |
|||
break; |
|||
|
|||
case 'build': |
|||
runBuild(); |
|||
break; |
|||
|
|||
case 'preserve': |
|||
runPreserve(); |
|||
break; |
|||
|
|||
case 'postinstall': |
|||
runPostInstall(); |
|||
break; |
|||
|
|||
case 'preview': |
|||
runPreview(); |
|||
break; |
|||
|
|||
// TODO
|
|||
case 'gzip': |
|||
break; |
|||
default: |
|||
break; |
|||
} |
|||
|
|||
export default {}; |
|||
@ -0,0 +1,12 @@ |
|||
// 百度统计代码 用于站点部署
|
|||
// 只在build:site开启
|
|||
export const hmScript = `<script>
|
|||
var _hmt = _hmt || []; |
|||
(function() { |
|||
var hm = document.createElement("script"); |
|||
hm.src = "https://hm.baidu.com/hm.js?384d6046e02f6ac4ea075357bd0e9b43"; |
|||
var s = document.getElementsByTagName("script")[0]; |
|||
s.parentNode.insertBefore(hm, s); |
|||
})(); |
|||
</script> |
|||
`;
|
|||
@ -0,0 +1,98 @@ |
|||
import { readFileSync, writeFileSync, existsSync } from 'fs-extra'; |
|||
import viteConfig, { htmlConfig } from '../../vite.config'; |
|||
import { getCwdPath, successConsole, errorConsole } from '../utils'; |
|||
import { GLOB_CONFIG_FILE_NAME } from '../constant'; |
|||
import { hmScript } from './hm'; |
|||
const pkg = require('../../package.json'); |
|||
|
|||
const { title, addHm, cdnConf, useCdn } = htmlConfig; |
|||
|
|||
function injectTitle(html: string, htmlTitle: string) { |
|||
if (/<\/title>/.test(html)) { |
|||
return html.replace(/<\/title>/, `${htmlTitle}</title>`); |
|||
} |
|||
return html; |
|||
} |
|||
|
|||
function injectConfigScript(html: string) { |
|||
const tag = `\t\t<script src='${viteConfig.base || './'}${GLOB_CONFIG_FILE_NAME}?v=${ |
|||
pkg.version |
|||
}-${new Date().getTime()}'></script>`;
|
|||
|
|||
if (/<\/head>/.test(html)) { |
|||
return html.replace(/<\/head>/, `${tag}\n\t\t</head>`); |
|||
} |
|||
return html; |
|||
} |
|||
|
|||
function injectHmScript(html: string) { |
|||
if (/<head>/.test(html)) { |
|||
return html.replace(/<head>/, `<head>\n${hmScript}`); |
|||
} |
|||
return html; |
|||
} |
|||
|
|||
function injectCdnCss(html: string) { |
|||
if (!cdnConf) return html; |
|||
const { css } = cdnConf; |
|||
if (!css || css.length === 0) return html; |
|||
|
|||
let cdnCssTag = ''; |
|||
for (const cssLink of css) { |
|||
cdnCssTag += `<link rel="stylesheet" href="${cssLink}">`; |
|||
} |
|||
if (/<\/head>/.test(html)) { |
|||
return html.replace(/<\/head>/, `${cdnCssTag}\n\t\t</head>`); |
|||
} |
|||
return html; |
|||
} |
|||
|
|||
function injectCdnjs(html: string) { |
|||
if (!cdnConf) return html; |
|||
const { js } = cdnConf; |
|||
if (!js || js.length === 0) return html; |
|||
|
|||
let cdnJsTag = ''; |
|||
for (const src of js) { |
|||
// TODO
|
|||
// <script type="importmap">
|
|||
// { "imports": {
|
|||
// "vue": "https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.0/vue.esm-browser.js",
|
|||
// "vue-router": "https://cdnjs.cloudflare.com/ajax/libs/vue-router/4.0.0-alpha.13/vue-router.esm.js",
|
|||
// "vuex": "https://cdnjs.cloudflare.com/ajax/libs/vuex/4.0.0-beta.2/vuex.esm-browser.js"
|
|||
// } }
|
|||
// </script>
|
|||
cdnJsTag += `\t<script type="text/javascript" src="${src}"></script>\n`; |
|||
} |
|||
if (/<\/body>/.test(html)) { |
|||
return html.replace(/<\/body>/, `${cdnJsTag}\n</body>`); |
|||
} |
|||
return html; |
|||
} |
|||
|
|||
export async function runUpdateHtml() { |
|||
const outDir = viteConfig.outDir || 'dist'; |
|||
const indexPath = getCwdPath(outDir, 'index.html'); |
|||
if (!existsSync(`${indexPath}`)) { |
|||
return; |
|||
} |
|||
try { |
|||
let processedHtml = ''; |
|||
const rawHtml = readFileSync(indexPath, 'utf-8'); |
|||
processedHtml = rawHtml; |
|||
processedHtml = injectTitle(processedHtml, title); |
|||
processedHtml = injectConfigScript(processedHtml); |
|||
if (addHm) { |
|||
processedHtml = injectHmScript(processedHtml); |
|||
} |
|||
if (useCdn) { |
|||
processedHtml = injectCdnCss(processedHtml); |
|||
processedHtml = injectCdnjs(processedHtml); |
|||
} |
|||
|
|||
writeFileSync(indexPath, processedHtml); |
|||
successConsole('Update Html Successfully!'); |
|||
} catch (error) { |
|||
errorConsole('Update Html Error\n' + error); |
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
import type { GlobEnvConfig } from './src/types/config'; |
|||
|
|||
export const getGlobEnvConfig = (): GlobEnvConfig => { |
|||
const env = import.meta.env; |
|||
return (env as unknown) as GlobEnvConfig; |
|||
}; |
|||
@ -1,12 +1,13 @@ |
|||
import { isDevMode, getEnv } from '/@/utils/env'; |
|||
import { useSetting } from '/@/hooks/core/useSetting'; |
|||
|
|||
import moment from 'moment'; |
|||
import pkg from '../../../package.json'; |
|||
const { globSetting } = useSetting(); |
|||
|
|||
// Generate cache key according to version
|
|||
export const getStorageShortName = () => { |
|||
const shortTime = moment().format('MMDDHHmmss'); |
|||
return `${globSetting.shortName}__${getEnv()}${ |
|||
isDevMode() ? `__${(pkg as any).version}` : '__' + process.env.VITE_BUILD_SHORT_TIME |
|||
`__${pkg.version}` + (isDevMode() ? '' : `__${shortTime}`) |
|||
}__`.toUpperCase();
|
|||
}; |
|||
|
|||
Loading…
Reference in new issue