Skip to content

Commit ff5c47c

Browse files
committed
feat: add remote component loader function
affects: @vue-async/module-loader
1 parent f18c8ef commit ff5c47c

File tree

6 files changed

+5020
-241
lines changed

6 files changed

+5020
-241
lines changed

.gitignore

Lines changed: 90 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,90 @@
1-
.DS_Store
2-
node_modules
3-
dist
4-
5-
# local env files
6-
.env.local
7-
.env.*.local
8-
9-
# Log files
10-
npm-debug.log*
11-
yarn-debug.log*
12-
yarn-error.log*
13-
lerna-debug.log*
14-
15-
# Editor directories and files
16-
.idea
17-
# .vscode
18-
.changelog
19-
.eslintcache
20-
*.suo
21-
*.ntvs*
22-
*.njsproj
23-
*.sln
24-
*.sw?
1+
# Created by .ignore support plugin (hsz.mobi)
2+
### Node template
3+
# Logs
4+
/logs
5+
*.log
6+
npm-debug.log*
7+
yarn-debug.log*
8+
yarn-error.log*
9+
10+
# Runtime data
11+
pids
12+
*.pid
13+
*.seed
14+
*.pid.lock
15+
16+
# Directory for instrumented libs generated by jscoverage/JSCover
17+
lib-cov
18+
19+
# Coverage directory used by tools like istanbul
20+
coverage
21+
22+
# nyc test coverage
23+
.nyc_output
24+
25+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26+
.grunt
27+
28+
# Bower dependency directory (https://bower.io/)
29+
bower_components
30+
31+
# node-waf configuration
32+
.lock-wscript
33+
34+
# Compiled binary addons (https://nodejs.org/api/addons.html)
35+
build/Release
36+
37+
# Dependency directories
38+
node_modules/
39+
jspm_packages/
40+
41+
# TypeScript v1 declaration files
42+
typings/
43+
44+
# Optional npm cache directory
45+
.npm
46+
47+
# Optional eslint cache
48+
.eslintcache
49+
50+
# Optional REPL history
51+
.node_repl_history
52+
53+
# Output of 'npm pack'
54+
*.tgz
55+
56+
# Yarn Integrity file
57+
.yarn-integrity
58+
59+
# dotenv environment variables file
60+
.env
61+
62+
# parcel-bundler cache (https://parceljs.org/)
63+
.cache
64+
65+
# next.js build output
66+
.next
67+
68+
# nuxt.js build output
69+
.nuxt
70+
71+
# Nuxt generate
72+
dist
73+
74+
# vuepress build output
75+
.vuepress/dist
76+
77+
# Serverless directories
78+
.serverless
79+
80+
# IDE / Editor
81+
.idea
82+
83+
# Service worker
84+
sw.*
85+
86+
# macOS
87+
.DS_Store
88+
89+
# Vim swap files
90+
*.swp

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"name": "vue-async",
33
"version": "0.1.0",
4+
"description": "Vue Async",
45
"private": true,
56
"repository": {
67
"type": "git",
@@ -56,7 +57,8 @@
5657
"prettier": "^2.0.5",
5758
"ts-jest": "^24.2.0",
5859
"typescript": "^3.7.2",
59-
"util": "^0.12.1"
60+
"util": "^0.12.1",
61+
"vuepress": "^1.5.0"
6062
},
6163
"husky": {
6264
"hooks": {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* componentLoader
3+
*/
4+
5+
import { Component as VueComponent } from 'vue';
6+
7+
export default () => {
8+
return function loader(componentName: string, url: string): Promise<VueComponent> {
9+
return new Promise<VueComponent>((resolve, reject) => {
10+
let component = (window as any)[componentName];
11+
if (component) {
12+
resolve(component);
13+
} else {
14+
const script = document.createElement('script');
15+
script.src = url;
16+
script.async = true;
17+
script.onload = () => {
18+
component = (window as any)[componentName];
19+
resolve(component);
20+
};
21+
script.onerror = () => {
22+
reject(new Error(`component "${componentName}" had a problem to load. ${url}`));
23+
};
24+
document.body.appendChild(script);
25+
}
26+
});
27+
};
28+
};

packages/module-loader/src/install.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import _Vue from 'vue';
22
import { Route, RawLocation } from 'vue-router';
33
import dynamicComponent from './ability/dynamicComponent';
44
import dynamicComponentState from './ability/dynamicComponent/storeModule';
5-
import eventBus from './ability/eventBus';
6-
import moduleLoader from './ability/moduleLoader';
5+
import createEventBus from './ability/eventBus';
6+
import createModuleLoader from './ability/moduleLoader';
7+
import createComponentLoader from './ability/componentLoader';
78
import { UseOptions } from '../types';
89

910
export default function install(Vue: typeof _Vue, options: UseOptions = {}) {
@@ -23,11 +24,15 @@ export default function install(Vue: typeof _Vue, options: UseOptions = {}) {
2324

2425
Object.defineProperties(Vue.prototype, {
2526
$eventBus: {
26-
value: eventBus(Vue),
27+
value: createEventBus(Vue),
2728
writable: false,
2829
},
2930
$moduleLoader: {
30-
value: moduleLoader(Vue, vm.status),
31+
value: createModuleLoader(Vue, vm.status),
32+
writable: false,
33+
},
34+
$componentLoader: {
35+
value: createComponentLoader(),
3136
writable: false,
3237
},
3338
});
@@ -47,7 +52,11 @@ export default function install(Vue: typeof _Vue, options: UseOptions = {}) {
4752
// router
4853
// 解决动态路由404问题
4954
if (router) {
50-
const resolveRoute = (to: Route, next: (to?: RawLocation | false | ((vm: _Vue) => void) | void) => void) => {
55+
const resolveRoute = (
56+
to: Route,
57+
from: Route,
58+
next: (to?: RawLocation | false | ((vm: _Vue) => void) | void) => void,
59+
) => {
5160
const fullPath = to.redirectedFrom || to.fullPath;
5261

5362
const { resolved, location } = router.resolve(fullPath);
@@ -61,17 +70,17 @@ export default function install(Vue: typeof _Vue, options: UseOptions = {}) {
6170
};
6271

6372
router.beforeEach((to, from, next) => {
64-
if (!to.name || to.name === '404' || to.name === 'page-not-found') {
73+
if (!to.name || to.name === '404' || to.name === 'page-not-found' || to.path === '*') {
6574
// 模块已经被加载完成, 但由于在其之前添加 beforeEach 阻止时间过长,vm.$watch还没开始监听
6675
if (vm.status.current) {
67-
resolveRoute(to, next);
76+
resolveRoute(to, from, next);
6877
}
6978
vm.$watch(
7079
() => vm.status.current,
7180
(newVal, oldVal) => {
7281
// false => true
7382
if (newVal && !oldVal) {
74-
resolveRoute(to, next);
83+
resolveRoute(to, from, next);
7584
}
7685
},
7786
);

packages/module-loader/types/vue.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
* Augment the typings of Vue.js
33
*/
44

5-
import Vue from 'vue';
5+
import Vue, { Component as VueComponent } from 'vue';
66
import { Framework, ModuleLoader, Modules, DynamicComponent } from './module';
77

88
declare module 'vue/types/vue' {
99
interface Vue {
1010
$moduleLoader: (moduleData: Modules) => Promise<void>;
11+
$componentLoader: (componentName: string, path: string) => Promise<VueComponent>;
1112
$moduleLoadManager: Framework;
1213
$dynamicComponent: {
1314
add: (component: DynamicComponent, position?: string) => void;

0 commit comments

Comments
 (0)