vue-skeleton-webpack-plugin这是一个基于 vue 的 webpack 插件,为单页和多页应用生成 skeleton,提升首屏展示体验。
安装
1.在package.json文件引入依赖 "vue-skeleton-webpack-plugin": "^1.1.17"
2.npm install vue-skeleton-webpack-plugin
使用
首先创建一个仅使用骨架屏组件的入口文件:
// src/components/Skeleton/entry-skeleton.js
import Vue from 'vue' // 创建的骨架屏 Vue 实例 import SkeletonFinanceSubMenuMore from './SkeletonFinanceSubMenuMore' import SkeletonInvestmentFinanceHome from './SkeletonInvestmentFinanceHome' import SkeletonWalletHome from './SkeletonWalletHome' export default new Vue({ components: { SkeletonFinanceSubMenuMore, SkeletonInvestmentFinanceHome, SkeletonWalletHome }, template: ` <div> <SkeletonInvestmentFinanceHome id="skeleton-investmentfinancehome" style="display:none"/> <SkeletonFinanceSubMenuMore id="skeleton-financesubmenu-more" style="display:none"/> <SkeletonWalletHome id="skeleton-wallethome" style="display:none"/> </div> ` })
接下来创建一个用于服务端渲染的 webpack 配置对象,将刚创建的入口文件指定为 entry 依赖入口:
// build/webpack.skeleton.conf.js
'use strict'; const path = require('path') const merge = require('webpack-merge') const baseWebpackConfig = require('./webpack.base.conf') const nodeExternals = require('webpack-node-externals') const utils = require('./utils') const config = require('../config') const isProduction = process.env.NODE_ENV === 'production' const sourceMapEnabled = isProduction ? config.build.productionSourceMap : config.dev.cssSourceMap function resolve(dir) { return path.join(__dirname, dir) } let skeletonWebpackConfig = merge(baseWebpackConfig, { target: 'node', devtool: false, entry: { app: resolve('../src/components/Skeleton/entry-skeleton.js') }, output: Object.assign({}, baseWebpackConfig.output, { libraryTarget: 'commonjs2' }), externals: nodeExternals({ whitelist: /\.css$/ }), plugins: [] }) // important: enable extract-text-webpack-plugin skeletonWebpackConfig.module.rules[0].options.loaders = utils.cssLoaders({ sourceMap: sourceMapEnabled, extract: true }), module.exports = skeletonWebpackConfig
在 webpack 中引入插件,在多页或单页应用中pro模式下自动插入路由规则
(运行打好的包浏览器输入配置的路由路径即可显示效果)亲测试多页显示需要配置绝对路径
(如 path: '/InvestmentFinance/FinanceSubMenu/more'; path: '/InvestmentFinance/WalletHome')
// build/webpack.prod.conf.js
const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin')
plugins: [ // inject skeleton content(DOM & CSS) into HTML new SkeletonWebpackPlugin({ webpackConfig: require('./webpack.skeleton.conf'), quiet: true, minimize: true, router: { mode: 'history', routes: [ { path: '', skeletonId: 'skeleton-investmentfinancehome' }, { path: '/InvestmentFinance', skeletonId: 'skeleton-investmentfinancehome' }, { path: '/InvestmentFinance/FinanceSubMenu/more', skeletonId: 'skeleton-financesubmenu-more' }, { path: '/InvestmentFinance/WalletHome', skeletonId: 'skeleton-wallethome' } ] } }) ]
开发模式下开发调试骨架屏
由于 skeleton 的渲染结果在 JS 前端渲染完成后就会被替换,如何在开发时方便的查看呢? 在开发模式中插入 skeleton 对应的路由规则,使多个页面的 skeleton 能像其他路由组件一样被访问,将使开发调试变得更加方便。
// src/router/Test /index.js
module.exports = { path: '/Test', component: (resolve) => import('@comp/EmptyTmpl').then(module => resolve(module)), children: [ { path: 'SkeletonFinanceSubMenuMore', name: 'TestSkeletonFinanceSubMenuMore', component: (resolve) => import('@comp/Skeleton/SkeletonFinanceSubMenuMore').then(module => resolve(module)), meta: { title: 'SkeletonFinanceSubMenuMore' } }, { path: 'SkeletonInvestmentFinanceHome', name: 'TestSkeletonInvestmentFinanceHome', component: (resolve) => import('@comp/Skeleton/SkeletonInvestmentFinanceHome').then(module => resolve(module)), meta: { title: 'SkeletonInvestmentFinanceHome' } }, { path: 'SkeletonWalletHome', name: 'TestSkeletonWalletHome', component: (resolve) => import('@comp/Skeleton/SkeletonWalletHome').then(module => resolve(module)), meta: { title: 'SkeletonWalletHome' } } ] }
// src/router/index.js
import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) export default new Router({ mode: 'history', routes: [ { path: '/', redirect: 'Test' }, { path: '*', component: (resolve) => import(/* webpackChunkName: 'global-error-page' */'@comp/GlobalErrorPage/GlobalErrorPage').then(module => resolve(module)), meta: { title: '访问失联', subRoot: true, closeBtnVisible: true } }, // require('./Test/index') ], scrollBehavior() { return {x: 0, y: 0} } })