前言
在单页应用中可能会有一些特殊情况,需要不同的路由下显示不同的首骨屏。比如新闻列页和新闻详情页。一般这种需求可以后端动态生成包含首骨屏代码 HTML 实现,但如果想要纯前端实现的话目前并未发现比较好的库或插件。在公司的一个项目中有这种需求的情况,因此自己手动弄了一个 webpack 插件 — spa-skeleton-webpack-plugin
。
插件实现
一般首骨屏插件其实是用 html-webpack-plugin
插件提供的钩子在 webpack 打包时将首骨屏的样式和 HTML 写进 index.html 里面,本插件实现也是利用了 html-webpack-plugin
的钩子,然后将 js 代码和模板写入 html,页面加载完后执行 js 代码再渲染模板。这种做法会比直接在后台动态生成 html 慢一点点,且 HTML 会比较大。
插件引入
npm install --save-dev spa-skeleton-webpack-plugin
项目地址:https://github.com/JhonMr/spa…
插件配置
1.webpack 插件配置
webpack3 请用
const SkeletonPlugin = require('html-webpack-plugin/src/skeletonPlugin3.js');
并在 webpack.base.conf.js 里引入,配置如下边代码的 new SkeletonPlugin()
webpack4 代码
const HtmlWebpackPlugin = require('html-webpack-plugin')
const SkeletonPlugin = require('spa-skeleton-webpack-plugin')
const path = require('path')
const webpackConfig = {
entry: 'index.js',
output: {
path: __dirname + '/dist',
filename: 'index.bundle.js'
},
plugin: [
new HtmlWebpackPlugin({// Your HtmlWebpackPlugin config}),
new SkeletonPlugin({
wrapEl: '#app', // 包裹元素
mode: 'hash', //router 模式(or history),
templates: [ // routes: 路由,格式可以是字符串、数组、正则。template: 首骨屏代码路径。{routes: '/', template: path.resolve(__dirname, `${customPath1}`},
{routes: ['/search', '/list'], template: path.resolve(__dirname, `${customPath2}`},
{
routes: [{pattern: '^/detail\\?id=\\d+', attributes: 'g'} // RegExp config
],
template: path.resolve(__dirname, `${customPath2}`
}
]
})
]
}
2.index.html 配置
添加 <!--skeletonScript-->
在包裹元素下面,如 VUE 项目的包裹标签 #app 下面。
例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>cli3</title>
</head>
<body>
<div id="app">
</div>
<!--skeletonScript-->
</body>
</html>
首骨屏模板
<style lang="text/css" scoped>
.index p {color: #45fdee; font-size: 20px;}
</style>
<div class="index">
<p>Index Skeleton</p>
</div>