如何在webpack+vue+vue-cli下搭建多模塊/單模塊多路由骨架屏
前言
骨架屏的用戶感知比loading更好,此前看過很多專欄以及文章,此次實踐中還是遇到需要學習的部分。
對於骨架屏或者佔位符學習了Vue頁面骨架屏注入實踐,通過服務器渲染出靜態頁面,在js加載完之前進行首屏加載是感知比較合理的一個選擇。
包括因爲可能信息面不全,對插件源碼進行了詳細解讀,希望對於將要在項目中搭建骨架屏的小夥伴們有所幫助。
此次使用的vue版本是2.4.5因此vue-server-renderer也需要使用同一個版本
參考的文章有
vue-skeleton-webpack-plugin骨架屏與page-skeleton-webpack-plugin骨架屏生成插件
基於vue和webpack的skeleton插件
以上參考文章裏有注入骨架屏的原理與知識,在此就不搬運了,感謝以上巨人。
vue-skeleton-webpack-plugin插件GITHUB地址
引用的組件
-
vue-skeleton-webpack-plugin
主要利用這個骨架屏組件 以及他依賴的其他組件 此組件我使用1.22版本,最新的將插件提供的loader放到了非主要API部分,因此在本文章中未使用此loader,以防版本升級將此loader刪去。
-
vue-server-renderer
熟悉ssr的小夥伴對這個插件都不陌生,通過其API createBundleRenderer創建render進行渲染,具體參考[Vue頁面骨架屏注入實踐][5]。 **注意點:vue與vue-server-renderer要使用同一個版本,否則會報錯**
-
extract-text-webpack-plugin
這也是比較重要的一個插件,如果你的腳手架沒有對html與css進行分離,那麼你的樣式(除了內聯樣式以外)將無法被應用,後續將會對此講解。
正文
如何配置多模塊(多頁面)骨架屏
在你的webpack配置文件的plugins 加入插件,爲了節省性能我只在prod的時候進行plugins插入,開發模式配置以路由的模式進行開發,後續會詳解。
webpackConfig.plugins.push(
new SkeletonWebpackPlugin({
webpackConfig: require('./webpack.skeleton.conf'), //主要的配置在個部分
quiet: true,
minimize: true,
/**router: {
mode: 'hash',
routes: skeletonPluginRoutes //此部分配置是SPA(單頁面)多路由腳手架配置
}**/
}));
webpack.skeleton.conf.js
...//以上常規配置不寫明
let merge = require('webpack-merge');
let path = require('path')
let merge = require('webpack-merge')
let config = require('../config')
let utils = require('./utils')
let baseWebpackConfig = require('./webpack.base.conf')
let SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin');
let 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,
module: {},
entry: {
'key':'../entry-skeleton.js',//這是你骨架屏入口文件的map,注意這裏的key必須與你在webpack裏模塊的入口文件相同
'key':value,//對應的鍵值是你的骨架屏入口文件
},
output: Object.assign({}, baseWebpackConfig.output, {
libraryTarget: 'commonjs2'
}),
plugins: []
});
//如果項目中沒有樣式與html的分離,可以扎到自己rules配置的.vue loader 進行開啓
skeletonWebpackConfig.module.rules[1].options.loaders = utils.cssLoaders({
sourceMap: sourceMapEnabled,
extract: true
});
module.exports = skeletonWebpackConfig
配置此config文件最重要的
- 將entry文件的key與webpack的key進行配對
- 一定要將自己的css與HTML分離(如果出現無法載入樣式的情況)
entry-skeleton.js
import Vue from 'vue'
import homeSkeleton from './home.skeleton.vue';
// import indexOverViewSkeleton from './indexOverView.skeleton.vue';
export default new Vue({
components: {
homeSkeleton,
// indexOverViewSkeleton
},
template:
`<homeSkeleton id="homeSkeleton" style="display:none"/>`
});
只是簡單的VUE入口文件,依舊要注意VUE的語法與規則,比如template只允許存在一個根元素
如何配置單頁面多路由骨架屏
webpackConfig.plugins.push(
new SkeletonWebpackPlugin({
webpackConfig: require('./webpack.skeleton.conf'),
quiet: true,
minimize: true,
router: {
mode: 'hash',
routes: [{
path:'/home', //你希望這個路由頁面時出現骨架屏
skeletonId:'homeSkeleton', //在skeleton入口文件裏配置的id
entryName:'key' //webpack打包時你入口文件的entryName,應與在plugin 入口文件一樣的MAPkey一致
},{
path:'/main', //你希望這個路由頁面時出現骨架屏
skeletonId:'mainSkeleton', //在skeleton入口文件裏配置的id
entryName:'key' //webpack打包時你入口文件的entryName,應與在plugin 入口文件一樣的MAPkey一致
},]
}
}));
entry-skeleton.js
import Vue from 'vue'
import homeSkeleton from './home.skeleton.vue';
import indexOverViewSkeleton from './indexOverView.skeleton.vue';
export default new Vue({
components: {
homeSkeleton,
indexOverViewSkeleton
},
template:
`<div>
<indexOverViewSkeleton id="indexOverViewSkeleton"
style="display:none"/>
<homeSkeleton id="homeSkeleton" style="display:none"/>
</div>`
});
配置中需要注意的幾點
1、保持自己的entryName,config裏entryKey與webpack腳手架入口文件的key一致
2、開啓樣式分離!!!!!!!!重要的事情說三遍
3、因爲插件經歷了幾個版本的更新,目前版本是接受loader的,但配置已經扁平化,所以建議不適用插件提供的loader配置。
4、省去了筆者部分根據腳手架配置的自動獲取入口的代碼,使用手寫的,減少配置,能夠讓腳手架做的事情,我們就不要做了哦!!!筆者的建議。
這篇小小的筆記先介紹配置文件吧~~~希望對大家有所幫助,也很感謝網上的各位碼字作者提供的思路。
看了插件的源碼思路也很清晰,對於骨架屏的原理有了更深的理解。
鴨,到點去敷面膜了,希望自己有一天也可以開源一款前端插件,成爲皮膚最好的前端。哈哈哈哈哈哈。