From 049c9532de2e7315e654b232f0faa53b6f8e9961 Mon Sep 17 00:00:00 2001 From: winixt Date: Mon, 4 Apr 2022 15:32:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=20vite=20build?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/commands/build/getBuildConfig.js | 34 ++++++++++++++----- .../src/commands/dev/getDevConfig.js | 10 +++++- .../fes-build-vite/src/commands/dev/index.js | 5 --- .../fes-build-vite/src/common/getConfig.js | 9 ++--- .../src/features/viteAnalyze.js | 16 ++++++++- .../fes-build-vite/src/features/viteHtml.js | 12 +++++++ .../fes-build-vite/src/features/viteLegacy.js | 12 +++++++ packages/fes-build-vite/src/index.js | 5 +++ .../fes-build-vite/src/registerMethods.js | 5 +++ packages/fes-build-vite/src/registerType.js | 8 +++++ packages/fes-build-vite/types.d.ts | 4 +++ packages/fes-build-webpack/src/index.js | 1 - .../src/plugins/commands/buildDevUtils.js | 2 -- .../plugins/commands/webpackConfig/index.js | 20 +---------- packages/fes-compiler/src/config/index.js | 2 -- packages/fes-preset-built-in/src/index.js | 1 + .../src/plugins/features/proxy.js | 5 ++- .../src/plugins/features/targets.js | 7 ++-- packages/fes-runtime/src/index.js | 3 +- .../fes-template-vite/{public => }/index.html | 5 +-- packages/fes-template-vite/package.json | 3 +- .../fes-template-vite/src/common/utils.js | 1 - .../src/getTargetsAndBrowsersList.js | 17 ++++++++++ packages/fes-utils/src/index.js | 2 ++ 24 files changed, 131 insertions(+), 58 deletions(-) create mode 100644 packages/fes-build-vite/src/features/viteHtml.js create mode 100644 packages/fes-build-vite/src/features/viteLegacy.js create mode 100644 packages/fes-build-vite/src/registerMethods.js create mode 100644 packages/fes-build-vite/src/registerType.js rename packages/{fes-build-webpack => fes-preset-built-in}/src/plugins/features/targets.js (69%) rename packages/fes-template-vite/{public => }/index.html (76%) create mode 100644 packages/fes-utils/src/getTargetsAndBrowsersList.js diff --git a/packages/fes-build-vite/src/commands/build/getBuildConfig.js b/packages/fes-build-vite/src/commands/build/getBuildConfig.js index 9794ca1c..968fe9f6 100644 --- a/packages/fes-build-vite/src/commands/build/getBuildConfig.js +++ b/packages/fes-build-vite/src/commands/build/getBuildConfig.js @@ -1,29 +1,47 @@ +import legacy from '@vitejs/plugin-legacy'; import { getInnerCommonConfig } from '../../common/getConfig'; -/** - * polyfill: @vitejs/plugin-legacy - * 确认 css 最终构建实现 autoprefixer postcss-safe-parser postcss-flexbugs-fixes - */ - export default async (api) => { - const { deepmerge } = api.utils; + const { deepmerge, getTargetsAndBrowsersList } = api.utils; const { build = {} } = api.config.viteOption; + const { browserslist } = getTargetsAndBrowsersList({ config: api.config }); - return deepmerge( + const bundleConfig = deepmerge( { mode: 'production', css: { postcss: { - plugins: [require('postcss-flexbugs-fixes'), require('postcss-safe-parser'), [require('autoprefixer'), {}]], + plugins: [ + require('postcss-flexbugs-fixes'), + require('postcss-safe-parser'), + require('autoprefixer')({ + ...api.config.autoprefixer, + overrideBrowserslist: browserslist, + }), + ], }, }, + plugins: [ + legacy({ + targets: browserslist, + ...api.config.viteLegacy, + }), + ], build: { ...build, + target: build.target || 'es2015', outDir: build.outDir || api.config.outputPath || 'dist', assetsInlineLimit: build.assetsInlineLimit || api.config.inlineLimit || 8192, }, }, getInnerCommonConfig(api), ); + + return api.applyPlugins({ + type: api.ApplyPluginsType.modify, + key: 'modifyBundleConfig', + initialValue: bundleConfig, + args: {}, + }); }; diff --git a/packages/fes-build-vite/src/commands/dev/getDevConfig.js b/packages/fes-build-vite/src/commands/dev/getDevConfig.js index 4f1c6c09..8566c590 100644 --- a/packages/fes-build-vite/src/commands/dev/getDevConfig.js +++ b/packages/fes-build-vite/src/commands/dev/getDevConfig.js @@ -24,12 +24,13 @@ export default async (api, args) => { args: {}, }); - return deepmerge( + const bundleConfig = deepmerge( { mode: 'development', plugins: [viteMiddlewarePlugin(beforeMiddlewares, middlewares)], server: { ...server, + proxy: server?.proxy || api.config.proxy, port, host: hostname, https: process.env.HTTPS || args.https, @@ -37,4 +38,11 @@ export default async (api, args) => { }, getInnerCommonConfig(api), ); + + return api.applyPlugins({ + type: api.ApplyPluginsType.modify, + key: 'modifyBundleConfig', + initialValue: bundleConfig, + args: {}, + }); }; diff --git a/packages/fes-build-vite/src/commands/dev/index.js b/packages/fes-build-vite/src/commands/dev/index.js index 77691eda..d1efea0a 100644 --- a/packages/fes-build-vite/src/commands/dev/index.js +++ b/packages/fes-build-vite/src/commands/dev/index.js @@ -3,11 +3,6 @@ import getDevConfig from './getDevConfig'; /** * TODO - - * - * analyze: rollup-plugin-visualizer - * - * 其他插件如何对内部配置进行修改 * * 共享 webpack 和 vite 的部分配置,降低熟悉 vite 的成本 */ diff --git a/packages/fes-build-vite/src/common/getConfig.js b/packages/fes-build-vite/src/common/getConfig.js index 7b8b782d..4e30b223 100644 --- a/packages/fes-build-vite/src/common/getConfig.js +++ b/packages/fes-build-vite/src/common/getConfig.js @@ -5,11 +5,8 @@ import { createHtmlPlugin } from 'vite-plugin-html'; import SFCConfigBlockPlugin from './SFCConfigBlockPlugin'; import getDefine from './getDefine'; -// TODO -// * 如何处理 html (改 mountId or title 等)(比较麻烦,晚点再看看有无更好的方案) - export function getInnerCommonConfig(api) { - const { deepmerge } = api.utils; + const { deepmerge, resolveRuntimeEnv } = api.utils; const { server, build, define, base, ...otherViteOption } = api.config.viteOption; const publicPath = base || api.config.publicPath || '/'; @@ -27,10 +24,10 @@ export function getInnerCommonConfig(api) { createHtmlPlugin({ minify: true, entry: join(api.paths.absTmpPath, 'fes.js'), - template: 'public/index.html', + template: 'index.html', inject: { data: { - title: 'Fes.js', + ...resolveRuntimeEnv(publicPath), mountElementId: api.config.mountElementId, }, }, diff --git a/packages/fes-build-vite/src/features/viteAnalyze.js b/packages/fes-build-vite/src/features/viteAnalyze.js index f69c9c96..8c91faaf 100644 --- a/packages/fes-build-vite/src/features/viteAnalyze.js +++ b/packages/fes-build-vite/src/features/viteAnalyze.js @@ -3,10 +3,24 @@ export default (api) => { key: 'viteAnalyze', config: { schema(joi) { - return joi.object({}).unknown(true); + return joi.object(); }, default: {}, }, enableBy: () => !!process.env.ANALYZE, }); + + api.modifyBundleConfig((memo) => { + memo.plugins.push( + require('rollup-plugin-visualizer').visualizer({ + filename: './.cache/visualizer/stats.html', + open: true, + gzipSize: true, + brotliSize: true, + ...api.viteAnalyze, + }), + ); + + return memo; + }); }; diff --git a/packages/fes-build-vite/src/features/viteHtml.js b/packages/fes-build-vite/src/features/viteHtml.js new file mode 100644 index 00000000..68792060 --- /dev/null +++ b/packages/fes-build-vite/src/features/viteHtml.js @@ -0,0 +1,12 @@ +export default (api) => { + api.describe({ + key: 'viteHtml', + config: { + schema(joi) { + return joi.object(); + }, + default: {}, + }, + enableBy: () => !!process.env.ANALYZE, + }); +}; diff --git a/packages/fes-build-vite/src/features/viteLegacy.js b/packages/fes-build-vite/src/features/viteLegacy.js new file mode 100644 index 00000000..9f833202 --- /dev/null +++ b/packages/fes-build-vite/src/features/viteLegacy.js @@ -0,0 +1,12 @@ +export default (api) => { + api.describe({ + key: 'viteLegacy', + config: { + schema(joi) { + return joi.object(); + }, + default: {}, + }, + enableBy: () => !!process.env.ANALYZE, + }); +}; diff --git a/packages/fes-build-vite/src/index.js b/packages/fes-build-vite/src/index.js index be6f0867..1e795b9d 100644 --- a/packages/fes-build-vite/src/index.js +++ b/packages/fes-build-vite/src/index.js @@ -1,10 +1,15 @@ export default function () { return { plugins: [ + require.resolve('./registerMethods'), + require.resolve('./registerType'), + // bundle configs require.resolve('./features/viteOption'), require.resolve('./features/viteVueJsx'), require.resolve('./features/viteVuePlugin'), + require.resolve('./features/viteAnalyze'), + require.resolve('./features/viteLegacy'), // commands require.resolve('./commands/build'), diff --git a/packages/fes-build-vite/src/registerMethods.js b/packages/fes-build-vite/src/registerMethods.js new file mode 100644 index 00000000..f551707a --- /dev/null +++ b/packages/fes-build-vite/src/registerMethods.js @@ -0,0 +1,5 @@ +export default function (api) { + ['modifyBundleConfig'].forEach((name) => { + api.registerMethod({ name }); + }); +} diff --git a/packages/fes-build-vite/src/registerType.js b/packages/fes-build-vite/src/registerType.js new file mode 100644 index 00000000..d9dbaca4 --- /dev/null +++ b/packages/fes-build-vite/src/registerType.js @@ -0,0 +1,8 @@ +import { name } from '../package.json'; + +export default function (api) { + api.addConfigType(() => ({ + source: name, + build: ['ViteBuildConfig'], + })); +} diff --git a/packages/fes-build-vite/types.d.ts b/packages/fes-build-vite/types.d.ts index 59d83578..96b23fe8 100644 --- a/packages/fes-build-vite/types.d.ts +++ b/packages/fes-build-vite/types.d.ts @@ -1,10 +1,14 @@ import type {UserConfig} from 'vite'; import type {Options} from '@vitejs/plugin-vue' +import {Options as PolyfillOptions } from '@vitejs/plugin-legacy' import createPlugin from '@vitejs/plugin-vue-jsx' +import {createHtmlPlugin} from 'vite-plugin-html' export interface ViteBuildConfig { viteOption: UserConfig; viteVuePlugin: Options; viteVueJsx: Parameters[0]; + viteLegacy: PolyfillOptions; + viteHtml: Parameters[0] } diff --git a/packages/fes-build-webpack/src/index.js b/packages/fes-build-webpack/src/index.js index e8ba92aa..d1ee8dbc 100644 --- a/packages/fes-build-webpack/src/index.js +++ b/packages/fes-build-webpack/src/index.js @@ -25,7 +25,6 @@ export default function () { require.resolve('./plugins/features/outputPath'), require.resolve('./plugins/features/postcssLoader'), require.resolve('./plugins/features/publicPath'), - require.resolve('./plugins/features/targets'), require.resolve('./plugins/features/terserOptions'), require.resolve('./plugins/features/nodeModulesTransform'), require.resolve('./plugins/features/vueLoader'), diff --git a/packages/fes-build-webpack/src/plugins/commands/buildDevUtils.js b/packages/fes-build-webpack/src/plugins/commands/buildDevUtils.js index dc95bb1c..8087423b 100644 --- a/packages/fes-build-webpack/src/plugins/commands/buildDevUtils.js +++ b/packages/fes-build-webpack/src/plugins/commands/buildDevUtils.js @@ -167,8 +167,6 @@ export function printFileSizes(stats, dir) { console.log(`${ui.toString()}\n\n ${chalk.gray('Images and other types of assets omitted.')}\n`); if (orderedAssets?.some((asset) => asset.suggested)) { - // We'll warn for bundles exceeding them. - // TODO: use umi docs console.log(); console.log(chalk.yellow('The bundle size is significantly larger than recommended.')); console.log(chalk.yellow('Consider reducing it with code splitting')); diff --git a/packages/fes-build-webpack/src/plugins/commands/webpackConfig/index.js b/packages/fes-build-webpack/src/plugins/commands/webpackConfig/index.js index 569f9722..73449394 100644 --- a/packages/fes-build-webpack/src/plugins/commands/webpackConfig/index.js +++ b/packages/fes-build-webpack/src/plugins/commands/webpackConfig/index.js @@ -9,24 +9,6 @@ import createDefineWebpackConfig from './define'; import createMinimizerWebpackConfig from './minimizer'; import createHtmlWebpackConfig from './html'; -function getTargetsAndBrowsersList({ config }) { - let targets = config.targets || {}; - - targets = Object.keys(targets) - .filter((key) => targets[key] !== false) - .reduce((memo, key) => { - memo[key] = targets[key]; - return memo; - }, {}); - - const browserslist = targets.browsers || Object.keys(targets).map((key) => `${key} >= ${targets[key] === true ? '0' : targets[key]}`); - - return { - targets, - browserslist, - }; -} - const DEFAULT_EXCLUDE_NODE_MODULES = [ 'vue', 'vuex', @@ -139,7 +121,7 @@ export default async function getConfig({ api, cwd, config, env, entry = {}, mod esModule: false, }); - const { targets, browserslist } = getTargetsAndBrowsersList({ config }); + const { targets, browserslist } = api.utils.getTargetsAndBrowsersList({ config }); const babelOpts = await getBabelOpts({ cwd, config, diff --git a/packages/fes-compiler/src/config/index.js b/packages/fes-compiler/src/config/index.js index 351e18ce..0f2ebc89 100644 --- a/packages/fes-compiler/src/config/index.js +++ b/packages/fes-compiler/src/config/index.js @@ -15,8 +15,6 @@ import mergeDefault from './utils/mergeDefault'; const CONFIG_FILES = ['.fes.js']; -// TODO: -// 1. custom config file export default class Config { cwd; diff --git a/packages/fes-preset-built-in/src/index.js b/packages/fes-preset-built-in/src/index.js index 21aa71cd..ec54edee 100644 --- a/packages/fes-preset-built-in/src/index.js +++ b/packages/fes-preset-built-in/src/index.js @@ -21,6 +21,7 @@ export default function () { require.resolve('./plugins/features/plugins'), require.resolve('./plugins/features/proxy'), require.resolve('./plugins/features/singular'), + require.resolve('./plugins/features/targets'), // route require.resolve('./plugins/route'), diff --git a/packages/fes-preset-built-in/src/plugins/features/proxy.js b/packages/fes-preset-built-in/src/plugins/features/proxy.js index 55b505df..795e7e89 100644 --- a/packages/fes-preset-built-in/src/plugins/features/proxy.js +++ b/packages/fes-preset-built-in/src/plugins/features/proxy.js @@ -2,13 +2,16 @@ import { extname } from 'path'; import historyFallback from 'connect-history-api-fallback'; const ASSET_EXT_NAMES = ['.ico', '.png', '.jpg', '.jpeg', '.gif', '.svg']; +const SKIP_PATHS_PREFIX = ['/@vite', '/@id']; const proxyMiddleware = (api) => (req, res, next) => { const proxyConfig = api.config.proxy; if (proxyConfig && Object.keys(proxyConfig).some((path) => req.url.startsWith(path))) { return next(); } - + if (SKIP_PATHS_PREFIX.find((prefix) => req.url.startsWith(prefix))) { + return next(); + } if (ASSET_EXT_NAMES.includes(extname(req.url))) { return next(); } diff --git a/packages/fes-build-webpack/src/plugins/features/targets.js b/packages/fes-preset-built-in/src/plugins/features/targets.js similarity index 69% rename from packages/fes-build-webpack/src/plugins/features/targets.js rename to packages/fes-preset-built-in/src/plugins/features/targets.js index 847bd248..0ff68fc1 100644 --- a/packages/fes-build-webpack/src/plugins/features/targets.js +++ b/packages/fes-preset-built-in/src/plugins/features/targets.js @@ -3,11 +3,10 @@ export default (api) => { key: 'targets', config: { default: { - chrome: 49, - firefox: 64, - safari: 10, + chrome: 56, + firefox: 67, + safari: 10.4, edge: 13, - ios: 10, }, schema(joi) { return joi.object(); diff --git a/packages/fes-runtime/src/index.js b/packages/fes-runtime/src/index.js index 15283e0c..e320f11f 100644 --- a/packages/fes-runtime/src/index.js +++ b/packages/fes-runtime/src/index.js @@ -1,4 +1,3 @@ -// TODO 其他 API export { useRoute, useRouter, @@ -10,7 +9,7 @@ export { createWebHashHistory, createWebHistory, createMemoryHistory, - createRouter + createRouter, } from 'vue-router'; export { default as Plugin, ApplyPluginsType } from './plugin'; diff --git a/packages/fes-template-vite/public/index.html b/packages/fes-template-vite/index.html similarity index 76% rename from packages/fes-template-vite/public/index.html rename to packages/fes-template-vite/index.html index 06bf3c3b..bdb42527 100644 --- a/packages/fes-template-vite/public/index.html +++ b/packages/fes-template-vite/index.html @@ -11,15 +11,12 @@ - <%= title %> + Fes & vite -
- - \ No newline at end of file diff --git a/packages/fes-template-vite/package.json b/packages/fes-template-vite/package.json index 8132a00c..d8ffef55 100644 --- a/packages/fes-template-vite/package.json +++ b/packages/fes-template-vite/package.json @@ -4,7 +4,8 @@ "description": "fes vite 构建模版", "scripts": { "prod": "FES_ENV=prod fes build", - "dev": "fes dev" + "dev": "fes dev", + "analyze": "ANALYZE=1 fes build" }, "keywords": [ "管理端", diff --git a/packages/fes-template-vite/src/common/utils.js b/packages/fes-template-vite/src/common/utils.js index 27bf8a19..c768364b 100644 --- a/packages/fes-template-vite/src/common/utils.js +++ b/packages/fes-template-vite/src/common/utils.js @@ -1,4 +1,3 @@ -// TODO // 时间格式化 // js 数字精度计算 // 手机号、身份证号 等的校验 diff --git a/packages/fes-utils/src/getTargetsAndBrowsersList.js b/packages/fes-utils/src/getTargetsAndBrowsersList.js new file mode 100644 index 00000000..47f17bff --- /dev/null +++ b/packages/fes-utils/src/getTargetsAndBrowsersList.js @@ -0,0 +1,17 @@ +export default function getTargetsAndBrowsersList({ config }) { + let targets = config.targets || {}; + + targets = Object.keys(targets) + .filter((key) => targets[key] !== false) + .reduce((memo, key) => { + memo[key] = targets[key]; + return memo; + }, {}); + + const browserslist = targets.browsers || Object.keys(targets).map((key) => `${key} >= ${targets[key] === true ? '0' : targets[key]}`); + + return { + targets, + browserslist, + }; +} diff --git a/packages/fes-utils/src/index.js b/packages/fes-utils/src/index.js index 7eb1fdd6..1d1ce052 100644 --- a/packages/fes-utils/src/index.js +++ b/packages/fes-utils/src/index.js @@ -31,6 +31,7 @@ import changePort from './changePort'; import getHostName from './getHostName'; import resolveRuntimeEnv from './resolveRuntimeEnv'; import stringifyObjValue from './stringifyObjValue'; +import getTargetsAndBrowsersList from './getTargetsAndBrowsersList'; export { chalk, @@ -68,4 +69,5 @@ export { getHostName, resolveRuntimeEnv, stringifyObjValue, + getTargetsAndBrowsersList, };