Skip to content

骨架屏 ​

本节目标:理解“骨架屏”的核心思路,并能把它用于实际开发或面试表达。

说明:原 OneNote 中有图片引用,但图片未包含在导出目录中;本页保留了可用的文字与代码内容。 5.

  • Skeleton Screen(骨架屏)就是在页面数据尚未加载前先给用户展示出页面的大致结构,直到请求数据返回后再渲染页面,补充进需要显示的数据内容。常用于文章列表、动态列表页。
  • react-content-loader SVG-Powered component to easily create placeholder loadings
  • create-content-loader
  • react-skeleton-webpack-plugin is a Webpack plugin based on React which generates Skeleton Screen for SPA

cnpm i @babel/core @babel/plugin-proposal-class-properties@babel/plugin-proposal-decorators@babel/preset-env@babel/preset-reactbabel-loaderhtml-webpack-pluginwebpackwebpack-cliwebpack-dev-serverwebpack-mergewebpack-node-externalsmemory-fsrequire-from-stringreact-content-loaderreact-router-domprerender-spa-pluginreact-lazyloadreact-windowimmutable-Dnpxwebpack--configwebpack.skeleton.jsnpxwebpack

5.1 skeleton.js src\skeleton.js importReact from'react';importReactDOM from'react-dom';importReactDOMServer from'react-dom/server';importContentLoader from'react-content-loader';exportdefaultReactDOMServer.renderToStaticMarkup(<ContentLoader/>); 5.2 index.js src\index.js importReact from"react";importReactDOM from"react-dom";letstyle = { width: "100%", height: "300px", backgroundColor: "orange"};setTimeout(()=>{ ReactDOM.render(<divstyle={style}></div>, document.getElementById("root"));}, 2000); 5.3 index.html src\index.html <!DOCTYPE html><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><metahttp-equiv="X-UA-Compatible"content="ie=edge"><title>Document</title></head><body><divid="root"></div></body></html> 5.4 webpack.base.js webpack.base.js constpath = require('path');module.exports = { mode:'development', devtool:"none", context: process.cwd(), output: { path: path.resolve(__dirname, "dist") }, module: { rules: [ { test: /.jsx?$/, use: { loader: "babel-loader", options: { presets: ["@babel/preset-env","@babel/preset-react"], plugins: [ ["@babel/plugin-proposal-decorators", { legacy: true}], ["@babel/plugin-proposal-class-properties", { loose: true}] ] } }, include: path.join(__dirname, "src"), exclude: /node_modules/} ] }}; 5.5 webpack.skeleton.js webpack.skeleton.js

constpath = require("path");constHtmlWebpackPlugin = require("html-webpack-plugin");const{ smart } = require("webpack-merge");constbase = require("./webpack.base");constnodeExternals = require('webpack-node-externals');module.exports = smart(base, { target: 'node', mode: "development", context: process.cwd(), entry: "./src/skeleton.js", output:{ filename:'skeleton.js', libraryTarget: 'commonjs2'}, externals: nodeExternals()}); 5.6 webpack.config.js webpack.config.js constpath = require("path");constHtmlWebpackPlugin = require("html-webpack-plugin");const{ smart } = require("webpack-merge");constbase = require("./webpack.base");constSkeletonWebpackPlugin = require('./SkeletonWebpackPlugin');module.exports = smart(base, { mode: "development", context: process.cwd(), entry: {main:"./src/index.js"}, output:{ filename:'main.js'}, plugins: [ newHtmlWebpackPlugin({ template: "./src/index.html", //指定模板文件filename: "index.html"//产出后的文件名}), newSkeletonWebpackPlugin({ webpackConfig: require('./webpack.skeleton') }) ]}); 5.7 SkeletonWebpackPlugin.js SkeletonWebpackPlugin.js

letrequireFromString = require('require-from-string');letresult = requireFromString('module.exports = "hello"');console.log(result);// hello letwebpack = require("webpack");letpath = require('path');letMFS = require("memory-fs");varrequireFromString = require("require-from-string");letmfs = newMFS();classSkeletonPlugin{ constructor(options) { this.options = options; } apply(compiler) { let{ webpackConfig } = this.options; compiler.hooks.compilation.tap("SkeletonPlugin", compilation => { compilation.hooks.htmlWebpackPluginBeforeHtmlProcessing.tapAsync( "SkeletonPlugin", (htmlPluginData, callback) => { letoutputPath = path.join(webpackConfig.output.path,webpackConfig.output.filename); letchildCompiler = webpack(webpackConfig); childCompiler.outputFileSystem = mfs; childCompiler.run((err, stats) =>{ letskeleton= mfs.readFileSync(outputPath, "utf8"); letskeletonHtml = requireFromString(skeleton); if(skeletonHtml.default) { skeletonHtml = skeletonHtml.default; } htmlPluginData.html=htmlPluginData.html.replace(\<div id="root"\>\</div\>,\<div id="root"\>${skeletonHtml}\</div\>); callback(null, htmlPluginData); }); } ); }); }}module.exports = SkeletonPlugin;

本站总访问 — 次