jinxyang 5 년 전
부모
커밋
0f97fcc380
11개의 변경된 파일803개의 추가작업 그리고 81개의 파일을 삭제
  1. 424 24
      package-lock.json
  2. 6 1
      package.json
  3. 47 0
      scripts/build.js
  4. 9 0
      scripts/config.js
  5. 4 0
      scripts/prod.js
  6. 6 0
      scripts/webpack/dev.js
  7. 151 0
      scripts/webpack/prod.js
  8. 16 0
      scripts1/config.js
  9. 27 0
      scripts1/server.js
  10. 113 0
      scripts1/webpack/dev.js
  11. 0 56
      src/jarvis/index.js

+ 424 - 24
package-lock.json

@@ -1005,6 +1005,24 @@
       "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
       "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA=="
     },
+    "aggregate-error": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
+      "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==",
+      "dev": true,
+      "requires": {
+        "clean-stack": "^2.0.0",
+        "indent-string": "^4.0.0"
+      },
+      "dependencies": {
+        "indent-string": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+          "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+          "dev": true
+        }
+      }
+    },
     "ajv": {
       "version": "6.10.2",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
@@ -1218,6 +1236,12 @@
       "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
       "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
     },
+    "ast-types": {
+      "version": "0.9.6",
+      "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz",
+      "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=",
+      "dev": true
+    },
     "astral-regex": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
@@ -1895,6 +1919,12 @@
         }
       }
     },
+    "clean-stack": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+      "dev": true
+    },
     "cli-cursor": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@@ -2895,6 +2925,16 @@
         "is-symbol": "^1.0.2"
       }
     },
+    "es6-templates": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/es6-templates/-/es6-templates-0.2.3.tgz",
+      "integrity": "sha1-XLmsn7He1usSOTQrgdeSu7QHjuQ=",
+      "dev": true,
+      "requires": {
+        "recast": "~0.11.12",
+        "through": "~2.3.6"
+      }
+    },
     "escape-html": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -3589,6 +3629,12 @@
       "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
       "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
     },
+    "fastparse": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
+      "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
+      "dev": true
+    },
     "fibers": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/fibers/-/fibers-4.0.2.tgz",
@@ -3905,6 +3951,15 @@
         "universalify": "^0.1.0"
       }
     },
+    "fs-minipass": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.0.0.tgz",
+      "integrity": "sha512-40Qz+LFXmd9tzYVnnBmZvFfvAADfUA14TXPK1s7IfElJTIZ97rA8w4Kin7Wt5JBrC3ShnnFJO/5vPjPEeJIq9A==",
+      "dev": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
     "fs-write-stream-atomic": {
       "version": "1.0.10",
       "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
@@ -4790,6 +4845,19 @@
       "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz",
       "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8="
     },
+    "html-loader": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-0.5.5.tgz",
+      "integrity": "sha512-7hIW7YinOYUpo//kSYcPB6dCKoceKLmOwjEMmhIobHuWGDVl0Nwe4l68mdG/Ru0wcUxQjVMEoZpkalZ/SE7zog==",
+      "dev": true,
+      "requires": {
+        "es6-templates": "^0.2.3",
+        "fastparse": "^1.1.1",
+        "html-minifier": "^3.5.8",
+        "loader-utils": "^1.1.0",
+        "object-assign": "^4.1.1"
+      }
+    },
     "html-minifier": {
       "version": "3.5.21",
       "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz",
@@ -5299,6 +5367,12 @@
       "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
       "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8="
     },
+    "is-plain-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+      "dev": true
+    },
     "is-plain-object": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@@ -5401,6 +5475,27 @@
         "v-click-outside-x": "^4.0.19"
       }
     },
+    "jest-worker": {
+      "version": "24.9.0",
+      "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz",
+      "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==",
+      "dev": true,
+      "requires": {
+        "merge-stream": "^2.0.0",
+        "supports-color": "^6.1.0"
+      },
+      "dependencies": {
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
     "js-base64": {
       "version": "2.5.1",
       "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz",
@@ -5905,6 +6000,12 @@
         }
       }
     },
+    "merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true
+    },
     "methods": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@@ -5963,11 +6064,13 @@
       "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
     },
     "mini-css-extract-plugin": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz",
-      "integrity": "sha512-IuaLjruM0vMKhUUT51fQdQzBYTX49dLj8w68ALEAe2A4iYNpIC4eMac67mt3NzycvjOlf07/kYxJDc0RTl1Wqw==",
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.0.tgz",
+      "integrity": "sha512-MNpRGbNA52q6U92i0qbVpQNsgk7LExy41MdAlG84FeytfDOtRIf/mCHdEgG8rpTKOaNKiqUnZdlptF469hxqOw==",
+      "dev": true,
       "requires": {
         "loader-utils": "^1.1.0",
+        "normalize-url": "1.9.1",
         "schema-utils": "^1.0.0",
         "webpack-sources": "^1.1.0"
       }
@@ -5995,6 +6098,50 @@
       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
       "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
     },
+    "minipass": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz",
+      "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==",
+      "dev": true,
+      "requires": {
+        "yallist": "^4.0.0"
+      },
+      "dependencies": {
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+          "dev": true
+        }
+      }
+    },
+    "minipass-collect": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
+      "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
+      "dev": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
+    "minipass-flush": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+      "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+      "dev": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
+    "minipass-pipeline": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz",
+      "integrity": "sha512-3JS5A2DKhD2g0Gg8x3yamO0pj7YeKGwVlDS90pF++kxptwx/F+B//roxf9SqYil5tQo65bijy+dAuAFZmYOouA==",
+      "dev": true,
+      "requires": {
+        "minipass": "^3.0.0"
+      }
+    },
     "mississippi": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
@@ -6314,9 +6461,16 @@
       "dev": true
     },
     "normalize-url": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
-      "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg=="
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz",
+      "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
+      "dev": true,
+      "requires": {
+        "object-assign": "^4.0.1",
+        "prepend-http": "^1.0.0",
+        "query-string": "^4.1.0",
+        "sort-keys": "^1.0.0"
+      }
     },
     "npm-run-path": {
       "version": "2.0.2",
@@ -6636,6 +6790,15 @@
         "p-limit": "^2.0.0"
       }
     },
+    "p-map": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
+      "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
+      "dev": true,
+      "requires": {
+        "aggregate-error": "^3.0.0"
+      }
+    },
     "p-try": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
@@ -7501,6 +7664,11 @@
         "postcss-value-parser": "^3.0.0"
       },
       "dependencies": {
+        "normalize-url": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
+          "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg=="
+        },
         "postcss-value-parser": {
           "version": "3.3.1",
           "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
@@ -7742,6 +7910,12 @@
       "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
       "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
     },
+    "prepend-http": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
+      "dev": true
+    },
     "prettier": {
       "version": "1.19.1",
       "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
@@ -7863,6 +8037,16 @@
       "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
       "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
     },
+    "query-string": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
+      "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
+      "dev": true,
+      "requires": {
+        "object-assign": "^4.1.0",
+        "strict-uri-encode": "^1.0.0"
+      }
+    },
     "querystring": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
@@ -7994,6 +8178,26 @@
         "readable-stream": "^2.0.2"
       }
     },
+    "recast": {
+      "version": "0.11.23",
+      "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz",
+      "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=",
+      "dev": true,
+      "requires": {
+        "ast-types": "0.9.6",
+        "esprima": "~3.1.0",
+        "private": "~0.1.5",
+        "source-map": "~0.5.0"
+      },
+      "dependencies": {
+        "esprima": {
+          "version": "3.1.3",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
+          "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=",
+          "dev": true
+        }
+      }
+    },
     "redent": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
@@ -8641,9 +8845,10 @@
       }
     },
     "serialize-javascript": {
-      "version": "1.9.1",
-      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz",
-      "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A=="
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.0.tgz",
+      "integrity": "sha512-a/mxFfU00QT88umAJQsNWOnUKckhNCqOl028N48e7wFmo2/EHpTo9Wso+iJJCMrQnmFvcjto5RJdAHEvVhcyUQ==",
+      "dev": true
     },
     "serve-static": {
       "version": "1.14.1",
@@ -8867,6 +9072,15 @@
         }
       }
     },
+    "sort-keys": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
+      "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
+      "dev": true,
+      "requires": {
+        "is-plain-obj": "^1.0.0"
+      }
+    },
     "source-list-map": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
@@ -9052,6 +9266,12 @@
       "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
       "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI="
     },
+    "strict-uri-encode": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+      "dev": true
+    },
     "string-width": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
@@ -9256,9 +9476,9 @@
       }
     },
     "terser": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/terser/-/terser-4.4.0.tgz",
-      "integrity": "sha512-oDG16n2WKm27JO8h4y/w3iqBGAOSCtq7k8dRmrn4Wf9NouL0b2WpMHGChFGZq4nFAQy1FsNJrVQHfurXOSTmOA==",
+      "version": "4.4.2",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-4.4.2.tgz",
+      "integrity": "sha512-Uufrsvhj9O1ikwgITGsZ5EZS6qPokUOkCegS7fYOdGTv+OA90vndUbU6PEjr5ePqHfNUbGyMO7xyIZv2MhsALQ==",
       "requires": {
         "commander": "^2.20.0",
         "source-map": "~0.6.1",
@@ -9273,25 +9493,141 @@
       }
     },
     "terser-webpack-plugin": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz",
-      "integrity": "sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==",
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.2.1.tgz",
+      "integrity": "sha512-jwdauV5Al7zopR6OAYvIIRcxXCSvLjZjr7uZE8l2tIWb/ryrGN48sJftqGf5k9z09tWhajx53ldp0XPI080YnA==",
+      "dev": true,
       "requires": {
-        "cacache": "^12.0.2",
-        "find-cache-dir": "^2.1.0",
-        "is-wsl": "^1.1.0",
-        "schema-utils": "^1.0.0",
-        "serialize-javascript": "^1.7.0",
+        "cacache": "^13.0.1",
+        "find-cache-dir": "^3.0.0",
+        "jest-worker": "^24.9.0",
+        "schema-utils": "^2.5.0",
+        "serialize-javascript": "^2.1.0",
         "source-map": "^0.6.1",
-        "terser": "^4.1.2",
-        "webpack-sources": "^1.4.0",
-        "worker-farm": "^1.7.0"
+        "terser": "^4.3.9",
+        "webpack-sources": "^1.4.3"
       },
       "dependencies": {
+        "cacache": {
+          "version": "13.0.1",
+          "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz",
+          "integrity": "sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w==",
+          "dev": true,
+          "requires": {
+            "chownr": "^1.1.2",
+            "figgy-pudding": "^3.5.1",
+            "fs-minipass": "^2.0.0",
+            "glob": "^7.1.4",
+            "graceful-fs": "^4.2.2",
+            "infer-owner": "^1.0.4",
+            "lru-cache": "^5.1.1",
+            "minipass": "^3.0.0",
+            "minipass-collect": "^1.0.2",
+            "minipass-flush": "^1.0.5",
+            "minipass-pipeline": "^1.2.2",
+            "mkdirp": "^0.5.1",
+            "move-concurrently": "^1.0.1",
+            "p-map": "^3.0.0",
+            "promise-inflight": "^1.0.1",
+            "rimraf": "^2.7.1",
+            "ssri": "^7.0.0",
+            "unique-filename": "^1.1.1"
+          }
+        },
+        "find-cache-dir": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.1.0.tgz",
+          "integrity": "sha512-zw+EFiNBNPgI2NTrKkDd1xd7q0cs6wr/iWnr/oUkI0yF9K9GqQ+riIt4aiyFaaqpaWbxPrJXHI+QvmNUQbX+0Q==",
+          "dev": true,
+          "requires": {
+            "commondir": "^1.0.1",
+            "make-dir": "^3.0.0",
+            "pkg-dir": "^4.1.0"
+          }
+        },
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "make-dir": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz",
+          "integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==",
+          "dev": true,
+          "requires": {
+            "semver": "^6.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+          "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+          "dev": true
+        },
+        "pkg-dir": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+          "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+          "dev": true,
+          "requires": {
+            "find-up": "^4.0.0"
+          }
+        },
+        "schema-utils": {
+          "version": "2.6.1",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.1.tgz",
+          "integrity": "sha512-0WXHDs1VDJyo+Zqs9TKLKyD/h7yDpHUhEFsM2CzkICFdoX1av+GBq/J2xRTFfsQO5kBfhZzANf2VcIm84jqDbg==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.10.2",
+            "ajv-keywords": "^3.4.1"
+          }
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        },
         "source-map": {
           "version": "0.6.1",
           "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
+        "ssri": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.0.tgz",
+          "integrity": "sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g==",
+          "dev": true,
+          "requires": {
+            "figgy-pudding": "^3.5.1",
+            "minipass": "^3.1.1"
+          }
         }
       }
     },
@@ -10081,6 +10417,16 @@
           "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
           "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
         },
+        "mini-css-extract-plugin": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz",
+          "integrity": "sha512-IuaLjruM0vMKhUUT51fQdQzBYTX49dLj8w68ALEAe2A4iYNpIC4eMac67mt3NzycvjOlf07/kYxJDc0RTl1Wqw==",
+          "requires": {
+            "loader-utils": "^1.1.0",
+            "schema-utils": "^1.0.0",
+            "webpack-sources": "^1.1.0"
+          }
+        },
         "mute-stream": {
           "version": "0.0.7",
           "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
@@ -10156,6 +10502,16 @@
             }
           }
         },
+        "serialize-javascript": {
+          "version": "1.9.1",
+          "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz",
+          "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A=="
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+        },
         "string-width": {
           "version": "2.1.1",
           "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@@ -10187,6 +10543,22 @@
             "schema-utils": "^1.0.0"
           }
         },
+        "terser-webpack-plugin": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz",
+          "integrity": "sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==",
+          "requires": {
+            "cacache": "^12.0.2",
+            "find-cache-dir": "^2.1.0",
+            "is-wsl": "^1.1.0",
+            "schema-utils": "^1.0.0",
+            "serialize-javascript": "^1.7.0",
+            "source-map": "^0.6.1",
+            "terser": "^4.1.2",
+            "webpack-sources": "^1.4.0",
+            "worker-farm": "^1.7.0"
+          }
+        },
         "v-viewer": {
           "version": "0.3.2",
           "resolved": "https://registry.npmjs.org/v-viewer/-/v-viewer-0.3.2.tgz",
@@ -10289,6 +10661,34 @@
         "terser-webpack-plugin": "^1.4.1",
         "watchpack": "^1.6.0",
         "webpack-sources": "^1.4.1"
+      },
+      "dependencies": {
+        "serialize-javascript": {
+          "version": "1.9.1",
+          "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz",
+          "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A=="
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+        },
+        "terser-webpack-plugin": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz",
+          "integrity": "sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==",
+          "requires": {
+            "cacache": "^12.0.2",
+            "find-cache-dir": "^2.1.0",
+            "is-wsl": "^1.1.0",
+            "schema-utils": "^1.0.0",
+            "serialize-javascript": "^1.7.0",
+            "source-map": "^0.6.1",
+            "terser": "^4.1.2",
+            "webpack-sources": "^1.4.0",
+            "worker-farm": "^1.7.0"
+          }
+        }
       }
     },
     "webpack-bundle-analyzer": {

+ 6 - 1
package.json

@@ -4,7 +4,7 @@
   "private": true,
   "scripts": {
     "start": "node scripts/server.js",
-    "build": "node scripts/build.js"
+    "build": "node scripts/prod.js"
   },
   "devDependencies": {
     "@babel/core": "^7.7.4",
@@ -14,6 +14,7 @@
     "autoprefixer": "^9.7.2",
     "babel-eslint": "^10.0.3",
     "babel-loader": "^8.0.6",
+    "case-sensitive-paths-webpack-plugin": "^2.2.0",
     "chalk": "^3.0.0",
     "connect-history-api-fallback": "^1.6.0",
     "copy-webpack-plugin": "^5.0.5",
@@ -28,14 +29,18 @@
     "express": "^4.17.1",
     "fibers": "^4.0.2",
     "friendly-errors-webpack-plugin": "^1.7.0",
+    "html-loader": "^0.5.5",
     "html-webpack-plugin": "^3.2.0",
     "ip": "^1.1.5",
+    "mini-css-extract-plugin": "^0.8.0",
     "node-sass": "^4.13.0",
+    "optimize-css-assets-webpack-plugin": "^5.0.3",
     "postcss-loader": "^3.0.0",
     "postcss-preset-env": "^6.7.0",
     "sass": "^1.23.7",
     "sass-loader": "^8.0.0",
     "style-loader": "^1.0.0",
+    "terser-webpack-plugin": "^2.2.1",
     "vue-eslint-parser": "^7.0.0",
     "vue-loader": "^15.7.2",
     "vue-template-compiler": "^2.6.10",

+ 47 - 0
scripts/build.js

@@ -0,0 +1,47 @@
+
+const path = require('path')
+const fs = require('fs-extra')
+const ora = require('ora')
+const chalk = require('chalk')
+const webpack = require('webpack')
+
+module.exports = (env, config) => {
+  const spinner = ora(`Building for ${env}...`)
+  spinner.start()
+  fs.emptyDirSync(path.resolve(__dirname, '../dist'))
+
+  const compiler = webpack(config)
+  compiler.run((err, stats) => {
+    spinner.stop()
+
+    if (err) {
+      console.error(err.stack || err)
+      if (err.details) {
+        console.error(err.details)
+      }
+      return
+    }
+
+    process.stdout.write(
+      stats.toString({
+        children: false,
+        chunks: false,
+        colors: true,
+        modules: false,
+        chunkModules: false,
+        hash: false,
+      }) +
+      '\n\n',
+    )
+
+    if (stats.hasErrors()) {
+      return console.log(chalk.white.bgRed('Build failed.\n'))
+    }
+
+    // if (stats.hasWarnings()) {
+    //   return console.log(chalk.white.bgGreenBright(
+    //     'Build success, but with warnings.\n'))
+    // }
+    console.log(chalk.white.bgGreen('Build success.\n'))
+  })
+}

+ 9 - 0
scripts/config.js

@@ -13,4 +13,13 @@ module.exports = {
       },
     },
   },
+  prod: {
+    publicPath: '/',
+    env: {
+      NODE_ENV: '"prod"',
+      API_URL: {
+        default: '"https://api.uptoyo.com/trace"',
+      },
+    },
+  },
 }

+ 4 - 0
scripts/prod.js

@@ -0,0 +1,4 @@
+
+const config = require('./webpack/prod.js')
+
+require('./build')('prod', config)

+ 6 - 0
scripts/webpack/dev.js

@@ -8,6 +8,7 @@ const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')
 const config = require('../config')
 const clientOptions = '?path=/__what&timeout=5000&reload=true&quiet=true'
 const VueLoaderPlugin = require('vue-loader/lib/plugin')
+const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
 
 module.exports = {
   mode: 'development',
@@ -56,6 +57,10 @@ module.exports = {
         test: /\.(ttf|otf|woff2?|eot)$/i,
         loader: 'file-loader',
       },
+      {
+        test: /\.(html)$/i,
+        loader: 'html-loader',
+      },
       {
         test: /\.js$/,
         enforce: 'pre',
@@ -94,6 +99,7 @@ module.exports = {
     new webpack.DefinePlugin({
       'process.env': config.dev.env,
     }),
+    new CaseSensitivePathsPlugin(),
     new webpack.HotModuleReplacementPlugin(),
     new FriendlyErrorsWebpackPlugin({
       compilationSuccessInfo: {

+ 151 - 0
scripts/webpack/prod.js

@@ -0,0 +1,151 @@
+
+const path = require('path')
+const webpack = require('webpack')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const VueLoaderPlugin = require('vue-loader/lib/plugin')
+const MiniCssExtractPlugin = require('mini-css-extract-plugin')
+const TerserPlugin = require('terser-webpack-plugin')
+const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
+const config = require('../config')
+
+module.exports = {
+  mode: 'production',
+  entry: path.resolve(__dirname, '../../src/index.js'),
+  output: {
+    path: path.resolve(__dirname, '../../dist'),
+    filename: 'assets/scripts/[name].[chunkhash:8].js',
+    publicPath: config.prod.publicPath,
+  },
+  module: {
+    rules: [
+      {
+        test: /\.css$/i,
+        use: [
+          MiniCssExtractPlugin.loader,
+          {
+            loader: 'css-loader',
+            options: {
+              importLoaders: 1,
+            },
+          },
+          'postcss-loader',
+        ],
+      },
+      {
+        test: /\.s[ac]ss$/i,
+        use: [
+          MiniCssExtractPlugin.loader,
+          {
+            loader: 'css-loader',
+            options: {
+              importLoaders: 2,
+            },
+          },
+          'postcss-loader',
+          'sass-loader',
+        ],
+      },
+      {
+        test: /\.(png|jpe?g|gif|svg)$/i,
+        loader: 'file-loader',
+        options: {
+          name: 'assets/images/[name].[contenthash:8].[ext]',
+        },
+      },
+      {
+        test: /\.(ttf|otf|eot|woff2?)$/,
+        loader: 'file-loader',
+        options: {
+          name: 'assets/fonts/[name].[contenthash:8].[ext]',
+        },
+      },
+      {
+        test: /\.js$/,
+        enforce: 'pre',
+        exclude: /node_modules/,
+        loader: 'eslint-loader',
+      },
+      {
+        test: /\.js$/,
+        exclude: /node_modules/,
+        loader: 'babel-loader',
+      },
+      {
+        test: /\.vue$/,
+        loader: 'vue-loader',
+      },
+    ],
+  },
+  optimization: {
+    minimize: true,
+    minimizer: [
+      new TerserPlugin({
+        terserOptions: {
+          parse: {
+            ecma: 8,
+          },
+          compress: {
+            drop_console: true,
+          },
+          mangle: {
+            safari10: true,
+          },
+        },
+        cache: true,
+        parallel: true,
+      }),
+      new OptimizeCSSAssetsPlugin(),
+    ],
+    splitChunks: {
+      chunks: 'all',
+      maxSize: 224000,
+      cacheGroups: {
+        vendors: {
+          test: /[\\/]node_modules[\\/]/,
+          name: 'vendors',
+        },
+      },
+    },
+  },
+  externals: {
+    vue: 'Vue',
+  },
+  resolve: {
+    extensions: [
+      '.js',
+      '.vue',
+    ],
+    alias: {
+      '@': path.resolve(__dirname, '../../src'),
+    },
+  },
+  devtool: 'inline-source-map',
+  plugins: [
+    new HtmlWebpackPlugin({
+      template: config.template,
+      inject: true,
+      minify: {
+        collapseWhitespace: true,
+        removeAttributeQuotes: true,
+        removeComments: true,
+      },
+    }),
+    new VueLoaderPlugin(),
+    new webpack.HashedModuleIdsPlugin(),
+    new webpack.DefinePlugin({
+      'process.env': config.prod.env,
+    }),
+    new MiniCssExtractPlugin({
+      filename: 'assets/styles/[name].[contenthash:8].css',
+      chunkFilename: 'assets/styles/[name].[contenthash:8].chunk.css',
+    }),
+    new CopyWebpackPlugin([
+      {
+        from: path.resolve(__dirname, '../../static'),
+        to: 'static',
+        ignore: ['.*'],
+      },
+    ]),
+  ],
+}

+ 16 - 0
scripts1/config.js

@@ -0,0 +1,16 @@
+
+const path = require('path')
+
+module.exports = {
+  port: 9527,
+  template: path.resolve(__dirname, '../src/index.html'),
+  dev: {
+    publicPath: '/',
+    env: {
+      NODE_ENV: '"dev"',
+      API_URL: {
+        default: '"http://192.168.23.111:9900"',
+      },
+    },
+  },
+}

+ 27 - 0
scripts1/server.js

@@ -0,0 +1,27 @@
+
+const chalk = require('chalk')
+const express = require('express')
+const webpack = require('webpack')
+const history = require('connect-history-api-fallback')
+const webpackDevMiddleware = require('webpack-dev-middleware')
+const webpackHotMiddleware = require('webpack-hot-middleware')
+const config = require('./config')
+const webpackConfig = require('./webpack/dev')
+
+const app = express()
+const compiler = webpack(webpackConfig)
+
+app.use(history())
+app.use(webpackDevMiddleware(compiler, {
+  logLevel: 'silent',
+  publicPath: webpackConfig.output.publicPath,
+}))
+
+app.use(webpackHotMiddleware(compiler, {
+  log: false,
+  path: '/__what',
+  heartbeat: 5000,
+}))
+
+console.log(chalk.cyan('Starting the development server...\n'))
+app.listen(config.port)

+ 113 - 0
scripts1/webpack/dev.js

@@ -0,0 +1,113 @@
+
+const path = require('path')
+const ip = require('ip')
+const webpack = require('webpack')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')
+const config = require('../config')
+const clientOptions = '?path=/__what&timeout=5000&reload=true&quiet=true'
+const VueLoaderPlugin = require('vue-loader/lib/plugin')
+
+module.exports = {
+  mode: 'development',
+  entry: [
+    `webpack-hot-middleware/client${clientOptions}`,
+    path.resolve(__dirname, '../../src/index.js'),
+  ],
+  output: {
+    filename: 'bundle.js',
+    publicPath: config.dev.publicPath,
+  },
+  module: {
+    rules: [
+      {
+        test: /\.css$/i,
+        use: [
+          'style-loader',
+          {
+            loader: 'css-loader',
+            options: {
+              importLoaders: 1,
+            },
+          },
+          'postcss-loader',
+        ],
+      },
+      {
+        test: /\.s[ac]ss$/i,
+        use: [
+          'style-loader',
+          {
+            loader: 'css-loader',
+            options: {
+              importLoaders: 2,
+            },
+          },
+          'postcss-loader',
+          'sass-loader',
+        ],
+      },
+      {
+        test: /\.(png|jpe?g|gif|svg)$/i,
+        loader: 'file-loader',
+      },
+      {
+        test: /\.(ttf|otf|woff2?|eot)$/i,
+        loader: 'file-loader',
+      },
+      {
+        test: /\.js$/,
+        enforce: 'pre',
+        exclude: /node_modules/,
+        loader: 'eslint-loader',
+      },
+      {
+        test: /\.js$/,
+        exclude: /node_modules/,
+        loader: 'babel-loader',
+      },
+      {
+        test: /\.vue$/,
+        loader: 'vue-loader',
+      },
+    ],
+  },
+  externals: {
+    vue: 'Vue',
+  },
+  resolve: {
+    extensions: [
+      '.js',
+      '.vue',
+    ],
+    alias: {
+      '@': path.resolve(__dirname, '../../src'),
+    },
+  },
+  devtool: 'inline-source-map',
+  plugins: [
+    new HtmlWebpackPlugin({
+      template: config.template,
+    }),
+    new VueLoaderPlugin(),
+    new webpack.DefinePlugin({
+      'process.env': config.dev.env,
+    }),
+    new webpack.HotModuleReplacementPlugin(),
+    new FriendlyErrorsWebpackPlugin({
+      compilationSuccessInfo: {
+        messages: [
+          `http://localhost:${config.port} or http://${ip.address()}:${config.port}`,
+        ],
+      },
+    }),
+    new CopyWebpackPlugin([
+      {
+        from: path.resolve(__dirname, '../../static'),
+        to: 'static',
+        ignore: ['.*'],
+      },
+    ]),
+  ],
+}

+ 0 - 56
src/jarvis/index.js

@@ -1,56 +0,0 @@
-
-const fetch = (config, free) => {
-  if (!config) {
-    throw new Error('fetch need config')
-  }
-  return new Promise(resolve => {
-    const { resource, ...init } = config
-    const headers = {
-      Accept: 'application/json, text/plain, */*',
-      'Content-Type': 'application/json;charset=UTF-8',
-    }
-    const token = window.localStorage.getItem('token')
-    if (!free) {
-      headers.Authorization = token
-    }
-    console.log(headers)
-    window.fetch(resource, {
-      headers,
-      ...init,
-    }).then(res => {
-      console.log(res)
-      resolve()
-    })
-  })
-}
-
-const getAPI = (type, store, payload) => {
-  const params = store.state.app.api[type]
-  if (!params) {
-    throw new Error(`api need ${type}`)
-  }
-  const { version, path, method, data } = params
-  const api = process.env.API_URL[version || 'default']
-  const resource = api + `${path[0] === '/' ? '' : '/'}` + path
-  const body = {}
-  data.forEach(({ name }) => {
-    body[name] = payload[name]
-  })
-  return {
-    resource,
-    method,
-    body: JSON.stringify(body),
-  }
-}
-
-function jarvis (vue, store) {
-  const hub = {
-    async login (payload) {
-      await fetch(getAPI('login', store, payload), true)
-    },
-  }
-  vue.hub = hub
-  vue.prototype.$hub = hub
-}
-
-export default jarvis