提交 173d4021 作者: vben

refactor: add vite-plugin-html. Delete updateHtml related logic

上级 7bd0b8eb
## # 2.0.0-rc.5 (2020-10-26)
## Wip
### 🎫 Chores
- 升级 vite 版本为`v1.0.0.rc8`
- vite.config.ts 内部 plugins 抽取
- build 目录结构调整
- 依赖更新
### ✨ Refactor
- 独立出`vite-plugin-html`,并修改相关插入 html 的逻辑
## 2.0.0-rc.5 (2020-10-26)
### ✨ Features
......
......@@ -31,6 +31,7 @@
- [Finished features](#finished-features)
- [Developing features](#developing-features)
- [Browser support](#browser-support)
- [Plugins](#plugins)
## Introduction
......@@ -250,3 +251,10 @@ Support modern browsers, Not currently supported ie11,Follow-up consideration
| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
More browsers can view [Can I Use Es Module](https://caniuse.com/?search=ES%20Module)
## Plugins
If these plugins are helpful to you, you can give a star
- [vite-plugin-mock](https://github.com/anncwb/vite-plugin-mock)
- [vite-plugin-html](https://github.com/anncwb/vite-plugin-html)
......@@ -31,6 +31,7 @@
- [已完成功能](#已完成功能)
- [正在开发的功能](#正在开发的功能)
- [浏览器支持](#浏览器支持)
- [插件](#插件-1)
- [加入我们](#加入我们)
## 介绍
......@@ -249,6 +250,13 @@ yarn clean:lib # 删除node_modules,兼容window系统
更多浏览器可以查看 [Can I Use Es Module](https://caniuse.com/?search=ES%20Module)
## 插件
如果这些插件对你有帮助,可以给一个 star 支持下
- [vite-plugin-mock](https://github.com/anncwb/vite-plugin-mock)
- [vite-plugin-html](https://github.com/anncwb/vite-plugin-html)
## 加入我们
`Vue-Vben-Aadmin` 是完全开源免费的项目,在帮助开发者更方便地进行中大型管理系统开发,同时也提供 QQ 交流群(项目刚起步,人数较少,有兴趣的可以加群一起讨论),使用问题欢迎在群内提问。
......
......@@ -4,15 +4,15 @@ import { sh } from 'tasksfile';
import { argv } from 'yargs';
import { runBuildConfig } from './buildConf';
import { runUpdateHtml } from './updateHtml';
// import { runUpdateHtml } from './updateHtml';
import { errorConsole, successConsole } from '../utils';
import { startGzipStyle } from '../plugin/gzip/compress';
import { startGzipStyle } from '../vite/plugin/gzip/compress';
export const runBuild = async (preview = false) => {
try {
const argvList = argv._;
if (preview) {
let cmd = `npm run build`;
let cmd = `cross-env NODE_ENV=production vite build`;
await sh(cmd, {
async: true,
nopipe: true,
......@@ -23,7 +23,7 @@ export const runBuild = async (preview = false) => {
if (!argvList.includes('no-conf')) {
await runBuildConfig();
}
await runUpdateHtml();
// await runUpdateHtml();
if (!preview) {
await startGzipStyle();
}
......
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';
import HtmlMinifier from 'html-minifier';
const pkg = require('../../package.json');
const { title, addHm, cdnConf, useCdn, minify } = 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);
}
if (minify) {
const { enable, ...miniOpt } = minify;
if (enable) {
processedHtml = HtmlMinifier.minify(processedHtml, miniOpt);
}
}
writeFileSync(indexPath, processedHtml);
successConsole('Update Html Successfully!');
} catch (error) {
errorConsole('Update Html Error\n' + error);
}
}
......@@ -2,7 +2,6 @@
// https://github.com/luxueyan/vite-transform-globby-import/blob/master/src/index.ts
// TODO 目前还不能监听文件新增及删除 内容已经改变,缓存问题?
// 可以使用,先不打算集成
import { join } from 'path';
import { lstatSync } from 'fs';
import glob from 'glob';
......
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';
import viteConfig from '../../../../vite.config';
import { readAllFile, getCwdPath, isBuildGzip, isSiteMode } from '../../../utils';
export function startGzip(
fileContent: string | Buffer,
......
import type { Plugin as VitePlugin } from 'vite';
import type { Plugin as rollupPlugin } from 'rollup';
import { createMockServer } from 'vite-plugin-mock';
import ViteHtmlPlugin from 'vite-plugin-html';
import PurgeIcons from 'vite-plugin-purge-icons';
import visualizer from 'rollup-plugin-visualizer';
import gzipPlugin from './gzip/index';
import { hmScript } from '../hm';
const pkg = require('../../../package.json');
import { isDevFn, isProdFn, isSiteMode, ViteEnv, isReportMode, isBuildGzip } from '../../utils';
import { GLOB_CONFIG_FILE_NAME } from '../../constant';
// gen vite plugins
export function createVitePlugins(viteEnv: ViteEnv) {
const { VITE_USE_MOCK, VITE_GLOB_APP_TITLE, VITE_PUBLIC_PATH } = viteEnv;
const vitePlugins: VitePlugin[] = [];
// vite-plugin-html
vitePlugins.push(
ViteHtmlPlugin({
// html title
title: VITE_GLOB_APP_TITLE,
minify: isProdFn(),
options: {
// Package and insert additional configuration files
injectConfig: isProdFn()
? `<script src='${VITE_PUBLIC_PATH || './'}${GLOB_CONFIG_FILE_NAME}?v=${
pkg.version
}-${new Date().getTime()}'></script>`
: '',
// Insert Baidu statistics code
hmScript: isSiteMode() ? hmScript : '',
},
})
);
// vite-plugin-purge-icons
vitePlugins.push(PurgeIcons());
// vite-plugin-mock
if (isDevFn() && VITE_USE_MOCK) {
// open mock
vitePlugins.push(
createMockServer({
ignore: /^\_/,
mockPath: 'mock',
})
);
}
return vitePlugins;
}
// gen rollup plugins
export function createRollupPlugin() {
const rollupPlugins: rollupPlugin[] = [];
if (isProdFn()) {
if (isReportMode()) {
// rollup-plugin-visualizer
rollupPlugins.push(
visualizer({ filename: './build/.cache/stats.html', open: true }) as Plugin
);
}
if (isBuildGzip() || isSiteMode()) {
// rollup-plugin-gizp
rollupPlugins.push(gzipPlugin());
}
}
return rollupPlugins;
}
<!DOCTYPE html>
<html lang="en">
<head>
<%= viteHtmlPluginOptions.hmScript %>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="renderer" content="webkit" />
......@@ -10,6 +11,7 @@
/>
<title></title>
<link rel="icon" href="/favicon.ico" />
<%= viteHtmlPluginOptions.injectConfig %>
</head>
<body>
<div id="app">
......
......@@ -4,7 +4,7 @@
"scripts": {
"bootstrap": "yarn install",
"serve": "esno ./build/script/preserve.ts && cross-env NODE_ENV=development vite",
"build": "cross-env NODE_ENV=production vite build && esno ./build/script/postBuild.ts",
"build": "rimraf dist && cross-env NODE_ENV=production vite build && esno ./build/script/postBuild.ts",
"build:site": "cross-env SITE=true npm run build ",
"build:no-cache": "yarn clean:cache && npm run build",
"report": "cross-env REPORT=true npm run build ",
......@@ -48,7 +48,6 @@
"@purge-icons/generated": "^0.4.1",
"@types/echarts": "^4.8.3",
"@types/fs-extra": "^9.0.2",
"@types/html-minifier": "^4.0.0",
"@types/koa-static": "^4.0.1",
"@types/lodash-es": "^4.17.3",
"@types/mockjs": "^1.0.3",
......@@ -72,7 +71,6 @@
"eslint-plugin-vue": "^7.1.0",
"esno": "^0.2.4",
"fs-extra": "^9.0.1",
"html-minifier": "^4.0.0",
"husky": "^4.3.0",
"koa-static": "^5.0.0",
"less": "^3.12.2",
......@@ -90,6 +88,7 @@
"tasksfile": "^5.1.1",
"ts-node": "^9.0.0",
"typescript": "^4.0.5",
"vite-plugin-html": "^1.0.0-beta.2",
"vite-plugin-mock": "^1.0.4",
"vite-plugin-purge-icons": "^0.4.4",
"vue-eslint-parser": "^7.1.1",
......
......@@ -2,7 +2,7 @@ import type { ProjectConfig } from '/@/types/config';
import { MenuTypeEnum, MenuThemeEnum, MenuModeEnum } from '/@/enums/menuEnum';
import { ContentEnum, PermissionModeEnum, RouterTransitionEnum } from '/@/enums/appEnum';
import { primaryColor } from '../../build/config/glob/lessModifyVars';
import { primaryColor } from '../../build/config/lessModifyVars';
import { isProdMode } from '/@/utils/env';
// ! 改动后需要清空浏览器缓存
const setting: ProjectConfig = {
......
import type { UserConfig } from 'vite';
import { resolve } from 'path';
import type { UserConfig, Plugin as VitePlugin } from 'vite';
import { modifyVars } from './build/config/lessModifyVars';
import { createProxy } from './build/vite/proxy';
import globbyTransform from './build/vite/plugin/context/transform';
import { isDevFn, loadEnv } from './build/utils';
import visualizer from 'rollup-plugin-visualizer';
import { modifyVars } from './build/config/glob/lessModifyVars';
import {
// externals,
cdnConf,
} from './build/config/vite/cdn';
import { createProxy } from './build/config/vite/proxy';
import { createMockServer } from 'vite-plugin-mock';
import PurgeIcons from 'vite-plugin-purge-icons';
import gzipPlugin from './build/plugin/gzip/index';
import globbyTransform from './build/plugin/vite-plugin-context/transform';
import { createRollupPlugin, createVitePlugins } from './build/vite/plugin';
import { isDevFn, isReportMode, isProdFn, loadEnv, isBuildGzip, isSiteMode } from './build/utils';
const pkg = require('./package.json');
const viteEnv = loadEnv();
const {
VITE_USE_MOCK,
VITE_PORT,
VITE_PUBLIC_PATH,
VITE_PROXY,
VITE_GLOB_APP_TITLE,
VITE_DROP_CONSOLE,
// VITE_USE_CDN,
} = loadEnv();
} = viteEnv;
function pathResolve(dir: string) {
return resolve(__dirname, '.', dir);
}
const rollupPlugins: any[] = [];
const vitePlugins: VitePlugin[] = [];
(() => {
if (isProdFn()) {
if (isReportMode()) {
// report
rollupPlugins.push(
visualizer({ filename: './build/.cache/stats.html', open: true }) as Plugin
);
}
if (isBuildGzip() || isSiteMode()) {
rollupPlugins.push(gzipPlugin());
}
}
if (isDevFn() && VITE_USE_MOCK) {
// open mock
vitePlugins.push(
createMockServer({
ignore: /^\_/,
mockPath: 'mock',
})
);
}
})();
const viteConfig: UserConfig = {
/**
* Entry. Use this to specify a js entry file in use cases where an
......@@ -152,54 +120,14 @@ const viteConfig: UserConfig = {
// 本地跨域代理
proxy: createProxy(VITE_PROXY),
plugins: [PurgeIcons(), ...vitePlugins],
rollupOutputOptions: {},
plugins: createVitePlugins(viteEnv),
rollupInputOptions: {
// TODO
// external: VITE_USE_CDN ? externals : [],
plugins: rollupPlugins,
plugins: createRollupPlugin(),
},
};
// 扩展配置, 往打包后的html注入内容
// 只针对生产环境
// TODO 目前只是简单手动注入实现,后续vite应该会提供配置项
export const htmlConfig: {
title: string;
addHm?: boolean;
cdnConf?: {
css?: string[];
js?: string[];
};
useCdn: boolean;
minify: {
enable: boolean;
removeComments: boolean;
collapseWhitespace: boolean;
minifyJS: boolean;
minifyCSS: boolean;
};
} = {
// html title
title: VITE_GLOB_APP_TITLE,
// 百度统计,不需要可以删除
// 用于打包部署站点使用。实际项目可以删除
addHm: isSiteMode(),
// 使用cdn打包
// TODO Cdn esm使用方式需要只能支持google,暂时关闭,后续查询更好的方式
useCdn: false,
// useCdn: VITE_USE_CDN,
// cdn列表
cdnConf,
minify: {
enable: true,
removeComments: true,
collapseWhitespace: true,
minifyJS: true,
minifyCSS: true,
},
};
export default {
...viteConfig,
transforms: [globbyTransform(viteConfig)],
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论