webpack单页应用多路由多骨架屏插件

前言

在单页应用中可能会有一些特殊情况,需要不同的路由下显示不同的首骨屏。比如新闻列页和新闻详情页。一般这种需求可以后端动态生成包含首骨屏代码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>

相关推荐