├── devServer.js
├── .gitignore
├── index.js
├── package.json
├── src
├── state.js
├── runtime.vue
└── parse.js
└── readme.md
/devServer.js:
--------------------------------------------------------------------------------
1 | const { setActive } = require('./src/state')
2 | module.exports = function (app, server, compiler) {
3 | app.get('/start', function (req, res) {
4 | const name = req.query.name
5 | res.send('')
6 | setActive(name)
7 | })
8 | }
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const { init, getVersionFilePath } = require('./src/state')
2 | const { parse, unParse } = require('./src/parse')
3 | module.exports = function (source, map) {
4 | init()
5 | const loaderContext = this
6 | const {
7 | resourcePath,
8 | resourceQuery
9 | } = loaderContext
10 |
11 | loaderContext.addDependency(getVersionFilePath())
12 | const ast = parse(source)
13 | const s = unParse(ast, { resourcePath })
14 |
15 | return s
16 | }
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-fast-dev-server",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/iptop/vue-fast-dev-server.git"
12 | },
13 | "author": "",
14 | "license": "ISC",
15 | "bugs": {
16 | "url": "https://github.com/iptop/vue-fast-dev-server/issues"
17 | },
18 | "homepage": "https://github.com/iptop/vue-fast-dev-server#readme"
19 | }
20 |
--------------------------------------------------------------------------------
/src/state.js:
--------------------------------------------------------------------------------
1 | let isInit = false
2 | let version = 0
3 | const path = require('path')
4 | const fs = require('fs')
5 | const activeRoutes = {}
6 | function getVersionFilePath () {
7 | return path.join(process.cwd(), 'node_modules', 'lazy-route-loader-version')
8 | }
9 |
10 | function setVersion () {
11 | version++
12 | const fileName = getVersionFilePath()
13 | fs.writeFileSync(fileName, version.toString())
14 | }
15 |
16 | function init () {
17 | if (isInit) {
18 | return
19 | }
20 | isInit = true
21 | setVersion()
22 | }
23 |
24 | function getRuntimePath () {
25 | return path.join(require.resolve('./runtime.vue'))
26 | }
27 |
28 | function setActive (name) {
29 | if (activeRoutes[name]) {
30 |
31 | } else {
32 | activeRoutes[name] = true
33 | setVersion()
34 | }
35 | }
36 |
37 | function getActiveRoute () {
38 | return activeRoutes
39 | }
40 |
41 | module.exports = {
42 | init,
43 | getVersionFilePath,
44 | getRuntimePath,
45 | setActive,
46 | getActiveRoute
47 | }
48 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # vue-fast-dev-server
2 |
3 | > 10倍缩短您的vue dev server启动时间
4 |
5 | 
6 | ## 安装
7 |
8 | ``` bash
9 | npm install vue-fast-dev-server --save-dev
10 | ```
11 | vue.config.js
12 |
13 | ``` js
14 | const path = require('path')
15 |
16 | module.exports = {
17 | devServer: {
18 | before: require('vue-fast-dev-server/devServer')
19 | },
20 | configureWebpack: config => {
21 | config.module.rules.push({
22 | test: /\.js$/,
23 | include: [
24 | path.resolve(__dirname, 'src/router/modules')
25 | ],
26 | loader: 'vue-fast-dev-server'
27 | })
28 | }
29 | }
30 |
31 | ```
32 | 请把你的路由定义文件迁移至src/router/modules目录下
33 |
34 | 参考 [iptop/vue-fast-dev-server-demo](https://github.com/iptop/vue-fast-dev-server-demo).
35 |
36 | ## 原理
37 |
38 | > 让浏览器和 dev server 进行联动,没有访问到的路由就直接跳过编译,不管多大的项目都是秒开
39 |
40 | ## 性能提升
41 |
42 |
43 | | 项目 | 加速前 | 加速后|
44 | | --------------------------- | ----------|------|
45 | | dev server 启动时间(带缓存) | 80S | 2S |
46 | | dev server 内存占用 |1600MB |200MB |
47 | | HRM响应速度 | 7.7S | 0.3S|
48 |
--------------------------------------------------------------------------------
/src/runtime.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
lazy-route-loader
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
24 |
25 |
87 |
--------------------------------------------------------------------------------
/src/parse.js:
--------------------------------------------------------------------------------
1 | const { getRuntimePath, getActiveRoute } = require('./state')
2 | function parse (source) {
3 | const reg = new RegExp('{[\\d\\D]*?component[\\d\\D]*?import[\\d\\D]*?}', 'g')
4 | const length = source.length
5 | let lastIndex = 0
6 | const ast = []
7 |
8 | function extractStaticText (s, e) {
9 | const staticText = source.substr(s, e - s)
10 | ast.push({
11 | type: 'static',
12 | raw: staticText
13 | })
14 | }
15 |
16 | function extractRoute (s) {
17 | ast.push({
18 | type: 'route',
19 | raw: s
20 | })
21 | }
22 |
23 | while (true) {
24 | const nrt = reg.exec(source)
25 | if (nrt) {
26 | const s = nrt[0]
27 | const is = nrt.index
28 | extractStaticText(lastIndex, is)
29 | extractRoute(s)
30 | const l = s.length
31 | lastIndex = is + l
32 | } else {
33 | extractStaticText(lastIndex, length)
34 | break
35 | }
36 | }
37 |
38 | return ast
39 | }
40 |
41 | function getRouteName (s) {
42 | const reg = new RegExp("name: \\'(.*?)\\'", 'g')
43 | const rt = reg.exec(s)
44 | if (rt) {
45 | return rt[1]
46 | } else {
47 | return ''
48 | }
49 | }
50 |
51 | function unParse (ast, { resourcePath }) {
52 | let str = ''
53 | for (const s of ast) {
54 | switch (s.type) {
55 | case 'static':
56 | str += s.raw
57 | break
58 | case 'route':
59 | const routerName = getRouteName(s.raw)
60 |
61 | const activeRoute = getActiveRoute()
62 |
63 | if (activeRoute[routerName]) {
64 | str += s.raw
65 | } else {
66 | const reg = new RegExp('(component[\\d\\D]*?import\\().*?(\\))', 'g')
67 | const np = getRuntimePath().replace(new RegExp('\\\\', 'g'), '/')
68 | const ns = s.raw.replace(reg, `$1 '${np}' $2`)
69 | str += ns
70 | }
71 |
72 | break
73 | }
74 | }
75 | return str
76 | }
77 |
78 | module.exports = {
79 | parse,
80 | unParse
81 | }
82 |
--------------------------------------------------------------------------------