Skip to content

Commit 1cb1083

Browse files
committed
add some comments
1 parent bd9903e commit 1cb1083

File tree

4 files changed

+43
-23
lines changed

4 files changed

+43
-23
lines changed

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,29 @@ vue-skeleton-webpack-plugin
66

77
[![NPM](https://nodei.co/npm/vue-skeleton-webpack-plugin.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/vue-skeleton-webpack-plugin/)
88

9-
基于 vue 的 webpack 插件,为单页/多页应用生成 skeleton,提升首屏展示体验
9+
这是一个基于 Vue 的 webpack 插件,为单页/多页应用生成骨架屏 skeleton,减少白屏时间,在页面完全渲染之前提升用户感知体验
1010

1111
## 基本实现
1212

13-
参考了[Ele.me的这篇文章](https://medium.com/elemefe/upgrading-ele-me-to-progressive-web-app-2a446832e509)
13+
参考了[饿了么的 PWA 升级实践](https://huangxuan.me/2017/07/12/upgrading-eleme-to-pwa/)一文
1414
使用服务端渲染在构建时渲染 skeleton 组件,将 DOM 和样式内联到最终输出的 html 中。
1515

1616
另外,为了开发时调试方便,会将对应路由写入`router.js`中,可通过`/skeleton`路由访问。
1717

18+
插件具体实现可参考[我的这篇文章](https://xiaoiver.github.io/coding/2017/07/30/%E4%B8%BAvue%E9%A1%B9%E7%9B%AE%E6%B7%BB%E5%8A%A0%E9%AA%A8%E6%9E%B6%E5%B1%8F.html)
19+
1820
## 使用方法
1921

2022
安装:
2123
```bash
2224
npm install vue-skeleton-webpack-plugin
2325
```
2426

27+
运行测试用例:
28+
```bash
29+
npm run test
30+
```
31+
2532
在 webpack 中引入插件:
2633
```js
2734
// webpack.conf.js

src/index.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,6 @@ const DEFAULT_PLUGIN_OPTIONS = {
1313
insertAfter: '<div id="app">'
1414
};
1515

16-
const DEFAULT_LOADER_OPTIONS = {
17-
importTemplate: 'import [nameCap] from \'@/pages/[nameCap].vue\';',
18-
routePathTemplate: '/skeleton-[name]',
19-
insertAfter: 'routes: ['
20-
};
21-
2216
class SkeletonPlugin {
2317

2418
constructor(options = {}) {
@@ -43,10 +37,12 @@ class SkeletonPlugin {
4337

4438
compiler.plugin('compilation', compilation => {
4539

40+
// add listener for html-webpack-plugin
4641
compilation.plugin('html-webpack-plugin-before-html-processing', (htmlPluginData, callback) => {
4742

4843
let usedChunks = htmlPluginData.plugin.options.chunks;
4944
let entryKey;
45+
5046
// find current processing entry
5147
if (Array.isArray(usedChunks)) {
5248
entryKey = Object.keys(skeletonEntries);
@@ -56,6 +52,7 @@ class SkeletonPlugin {
5652
entryKey = 'app';
5753
}
5854

55+
// set current entry & output in webpack config
5956
webpackConfig.entry = skeletonEntries[entryKey];
6057
webpackConfig.output.filename = `skeleton-${entryKey}.js`;
6158

@@ -76,8 +73,7 @@ class SkeletonPlugin {
7673
static loader(ruleOptions = {}) {
7774
return Object.assign(ruleOptions, {
7875
loader: require.resolve('./loader'),
79-
options: Object.assign({}, DEFAULT_LOADER_OPTIONS,
80-
Object.assign({}, ruleOptions.options))
76+
options: Object.assign({}, ruleOptions.options)
8177
});
8278
}
8379
}

src/loader.js

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
/**
22
* @file loader
3+
* @desc Insert route of skeleton into router.js, so that developer can
4+
* visit route path in dev mode to debug skeleton components
35
* @author panyuqi <panyuqi@baidu.com>
46
*/
57

@@ -8,34 +10,47 @@
810
const loaderUtils = require('loader-utils');
911
const insertAt = require('./util').insertAt;
1012

13+
const DEFAULT_LOADER_OPTIONS = {
14+
// template of importing skeleton component
15+
importTemplate: 'import [nameCap] from \'@/pages/[nameCap].vue\';',
16+
// template of route path
17+
routePathTemplate: '/skeleton-[name]',
18+
// position to insert route object in router.js file
19+
insertAfter: 'routes: ['
20+
};
21+
1122
const ENTRY_NAME_HOLDER = /\[name\]/gi;
1223
const ENTRY_NAME_CAP_HOLDER = /\[nameCap\]/gi;
1324

1425
module.exports = function (source) {
15-
const options = loaderUtils.getOptions(this);
26+
const options = Object.assign({}, DEFAULT_LOADER_OPTIONS, loaderUtils.getOptions(this));
1627
let {entry, importTemplate, routePathTemplate, insertAfter} = options;
1728

18-
// position to insert in router.js
29+
// find position to insert in router.js
1930
let routesPos = source.indexOf(insertAfter) + insertAfter.length;
2031

21-
if (!Array.isArray(entry)) {
22-
entry = [entry];
23-
}
32+
entry = Array.isArray(entry) ? entry : [entry];
2433

2534
entry.forEach(entryName => {
26-
// capitalize first letter
35+
// capitalize first letter in entryName eg.skeleton -> Skeleton
2736
let entryCap = entryName.replace(/([a-z])(.*)/, (w, firstLetter, rest) => firstLetter.toUpperCase() + rest);
28-
// route path
29-
let skeletonRoutePath = routePathTemplate.replace(ENTRY_NAME_HOLDER, entryName)
30-
.replace(ENTRY_NAME_CAP_HOLDER, entryCap);
31-
let importExpression = importTemplate.replace(ENTRY_NAME_HOLDER, entryName)
32-
.replace(ENTRY_NAME_CAP_HOLDER, entryCap);
37+
38+
// replace placeholder in routeTpl and importTpl
39+
let [skeletonRoutePath, importExpression] = [routePathTemplate, importTemplate]
40+
.map(pathStr => pathStr.replace(ENTRY_NAME_HOLDER, entryName)
41+
.replace(ENTRY_NAME_CAP_HOLDER, entryCap));
42+
43+
// route object to insert
3344
let routeExpression = `{
3445
path: '${skeletonRoutePath}',
3546
name: '${entryName}-skeleton',
3647
component: ${entryCap}
3748
},`;
49+
50+
// insert route object into routes array
3851
source = insertAt(source, routeExpression, routesPos);
52+
53+
// insert import sentence in the head
3954
source += importExpression;
4055
});
4156

src/ssr.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/**
22
* @file ssr
3+
* @desc Use vue ssr to render skeleton components. The result contains html and css.
34
* @author panyuqi <panyuqi@baidu.com>
45
*/
56

@@ -20,7 +21,7 @@ module.exports = serverWebpackConfig => new Promise((resolve, reject) => {
2021

2122
console.log(`Generate skeleton for ${outputBasename}...`);
2223

23-
// extract css
24+
// extract css into a single file
2425
serverWebpackConfig.plugins.push(new ExtractTextPlugin({
2526
filename: outputCssBasename
2627
}));
@@ -47,8 +48,9 @@ module.exports = serverWebpackConfig => new Promise((resolve, reject) => {
4748

4849
let bundle = mfs.readFileSync(outputPath, 'utf-8');
4950
let skeletonCss = mfs.readFileSync(outputCssPath, 'utf-8');
51+
// create renderer with bundle
5052
let renderer = createBundleRenderer(bundle);
51-
// ssr skeleton
53+
// use vue ssr to render skeleton
5254
renderer.renderToString({}, (err, skeletonHtml) => {
5355
if (err) {
5456
reject(err);

0 commit comments

Comments
 (0)