From 24c04594bbad6335e8bf2bcad19b7fd768a8a2ad Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Mon, 19 Aug 2019 18:08:29 +0800 Subject: [PATCH] init cli --- .eslintignore | 1 + lerna.json | 8 + package.json | 10 +- packages/uni-cli-shared/LICENSE | 202 + .../uni-cli-shared/__tests__/cache.spec.js | 81 + packages/uni-cli-shared/lib/api.js | 23 + packages/uni-cli-shared/lib/cache.js | 242 + packages/uni-cli-shared/lib/index.js | 112 + packages/uni-cli-shared/lib/json.js | 42 + packages/uni-cli-shared/lib/manifest.js | 93 + packages/uni-cli-shared/lib/package.js | 44 + packages/uni-cli-shared/lib/pages.js | 235 + packages/uni-cli-shared/lib/platform.js | 493 + packages/uni-cli-shared/lib/scss.js | 106 + packages/uni-cli-shared/lib/tags.js | 43 + packages/uni-cli-shared/lib/util.js | 119 + packages/uni-cli-shared/package.json | 18 + packages/uni-template-compiler/LICENSE | 202 + .../__tests__/compiler-extra.spec.js | 619 + .../__tests__/compiler-mp-alipay.spec.js | 144 + .../__tests__/compiler-mp-baidu.spec.js | 110 + .../__tests__/compiler-mp-qq.spec.js | 37 + .../__tests__/compiler-mp-toutiao.spec.js | 75 + .../__tests__/compiler-mp-weixin.spec.js | 90 + .../__tests__/compiler.spec.js | 668 + .../uni-template-compiler/lib/codeframe.js | 60 + .../uni-template-compiler/lib/constants.js | 123 + .../lib/data/traverse.js | 66 + packages/uni-template-compiler/lib/h5.js | 127 + packages/uni-template-compiler/lib/index.js | 171 + packages/uni-template-compiler/lib/module.js | 47 + .../lib/platforms/index.js | 26 + .../lib/platforms/mp-alipay.js | 82 + .../lib/platforms/mp-baidu.js | 36 + .../lib/platforms/mp-base.js | 104 + .../lib/platforms/mp-toutiao.js | 5 + .../lib/platforms/mp-weixin.js | 106 + .../lib/script/generate.js | 5 + .../lib/script/traverse/data/attrs.js | 18 + .../lib/script/traverse/data/class.js | 135 + .../lib/script/traverse/data/directives.js | 71 + .../lib/script/traverse/data/event.js | 408 + .../lib/script/traverse/data/index.js | 59 + .../lib/script/traverse/data/model.js | 71 + .../lib/script/traverse/data/ref.js | 43 + .../lib/script/traverse/data/style.js | 177 + .../lib/script/traverse/data/tag.js | 1 + .../lib/script/traverse/data/util.js | 47 + .../lib/script/traverse/filter.js | 179 + .../lib/script/traverse/index.js | 120 + .../lib/script/traverse/member-expr.js | 78 + .../lib/script/traverse/render-list.js | 177 + .../lib/script/traverse/statements.js | 119 + .../lib/script/traverse/visitor.js | 250 + .../lib/template/generate.js | 131 + .../lib/template/traverse.js | 464 + packages/uni-template-compiler/lib/util.js | 170 + packages/uni-template-compiler/package.json | 21 + packages/vue-cli-plugin-hbuilderx/LICENSE | 202 + packages/vue-cli-plugin-hbuilderx/README.md | 3 + .../build/css-loader.conf.js | 87 + .../vue-cli-plugin-hbuilderx/build/utils.js | 71 + .../build/vue-loader.conf.js | 74 + .../build/webpack.nvue.conf.js | 280 + .../fork-ts-checker-webpack-plugin.fake.js | 11 + .../vue-cli-plugin-hbuilderx/generator.js | 10 + packages/vue-cli-plugin-hbuilderx/index.js | 45 + packages/vue-cli-plugin-hbuilderx/logo.png | Bin 0 -> 1453 bytes .../vue-cli-plugin-hbuilderx/module-alias.js | 32 + .../vue-cli-plugin-hbuilderx/package.json | 16 + .../packages/babel-plugin-console/LICENSE | 202 + .../babel-plugin-console/dist/index.js | 52 + .../babel-plugin-console/package.json | 11 + .../packages/uni-app-plus-nvue-v8/LICENSE | 202 + .../uni-app-plus-nvue-v8/dist/index.js | 781 + .../uni-app-plus-nvue-v8/package.json | 11 + .../packages/uni-app-plus-nvue/LICENSE | 202 + .../packages/uni-app-plus-nvue/dist/index.js | 612 + .../packages/uni-app-plus-nvue/package.json | 11 + .../packages/uni-app-plus/LICENSE | 202 + .../packages/uni-app-plus/dist/index.js | 157 + .../packages/uni-app-plus/dist/index.new.js | 626 + .../packages/uni-app-plus/package.json | 11 + .../packages/webpack-app-plus-plugin/index.js | 48 + .../packages/webpack-uni-nvue-loader/LICENSE | 202 + .../webpack-uni-nvue-loader/lib/main.js | 72 + .../webpack-uni-nvue-loader/lib/style.js | 70 + .../lib/styleInjection.js | 135 + .../webpack-uni-nvue-loader/lib/template.js | 4 + .../webpack-uni-nvue-loader/package.json | 10 + .../packages/weex-styler/LICENSE | 21 + .../packages/weex-styler/README.md | 124 + .../packages/weex-styler/circle.yml | 3 + .../packages/weex-styler/gulpfile.js | 25 + .../packages/weex-styler/index.js | 216 + .../weex-styler/lib/shorthand-parser.js | 60 + .../packages/weex-styler/lib/util.js | 30 + .../packages/weex-styler/lib/validator.js | 723 + .../packages/weex-styler/package.json | 67 + .../packages/weex-styler/test/parse.js | 289 + .../weex-styler/test/shorthand-parser.spec.js | 178 + .../packages/weex-styler/test/validate.js | 445 + .../packages/weex-template-compiler/README.md | 3 + .../packages/weex-template-compiler/build.js | 5101 +++++++ .../packages/weex-template-compiler/index.js | 17 + .../weex-template-compiler/package.json | 25 + .../template/bin/uniapp-cli.js | 31 + .../vue-cli-plugin-hbuilderx/typescript.json | 133 + packages/vue-cli-plugin-uni-optimize/LICENSE | 202 + .../vue-cli-plugin-uni-optimize/README.md | 3 + packages/vue-cli-plugin-uni-optimize/index.js | 98 + packages/vue-cli-plugin-uni-optimize/logo.png | Bin 0 -> 4023 bytes .../vue-cli-plugin-uni-optimize/package.json | 14 + .../packages/babel-plugin-uni-api/index.js | 33 + .../packages/vue-loader/index.js | 216 + .../packages/webpack-optimize-plugin/api.js | 219 + .../webpack-optimize-plugin/component.js | 47 + .../packages/webpack-optimize-plugin/index.js | 45 + .../packages/webpack-optimize-plugin/util.js | 22 + .../packages/webpack-style-loader/index.js | 15 + packages/vue-cli-plugin-uni/LICENSE | 202 + packages/vue-cli-plugin-uni/README.md | 3 + packages/vue-cli-plugin-uni/bin/uniapp-cli.js | 48 + packages/vue-cli-plugin-uni/commands/build.js | 145 + packages/vue-cli-plugin-uni/commands/info.js | 13 + packages/vue-cli-plugin-uni/commands/serve.js | 327 + packages/vue-cli-plugin-uni/generator.js | 54 + packages/vue-cli-plugin-uni/index.js | 35 + .../vue-cli-plugin-uni/lib/app-plus/index.js | 2 + .../vue-cli-plugin-uni/lib/chain-webpack.js | 75 + .../vue-cli-plugin-uni/lib/check-update.js | 33 + .../lib/configure-webpack.js | 287 + .../lib/copy-webpack-options.js | 17 + packages/vue-cli-plugin-uni/lib/env.js | 222 + packages/vue-cli-plugin-uni/lib/format-log.js | 44 + .../vue-cli-plugin-uni/lib/format-text.js | 187 + .../vue-cli-plugin-uni/lib/h5/auto-reload.js | 9 + .../lib/h5/compiler-options.js | 94 + packages/vue-cli-plugin-uni/lib/h5/index.js | 169 + .../vue-cli-plugin-uni/lib/mp-alipay/index.js | 2 + .../vue-cli-plugin-uni/lib/mp-baidu/index.js | 2 + .../lib/mp-compiler-options.js | 56 + .../vue-cli-plugin-uni/lib/mp-qq/index.js | 2 + .../lib/mp-toutiao/index.js | 2 + .../vue-cli-plugin-uni/lib/mp-weixin/index.js | 2 + packages/vue-cli-plugin-uni/lib/mp.js | 176 + packages/vue-cli-plugin-uni/lib/options.js | 73 + packages/vue-cli-plugin-uni/lib/scoped.js | 83 + .../vue-cli-plugin-uni/lib/split-chunks.js | 144 + packages/vue-cli-plugin-uni/logo.png | Bin 0 -> 4023 bytes packages/vue-cli-plugin-uni/package.json | 32 + .../@megalo/template-compiler/build.js | 6082 ++++++++ .../@megalo/template-compiler/demo/index.js | 10 + .../@megalo/template-compiler/index.js | 17 + .../@megalo/template-compiler/package.json | 55 + .../packages/h5-vue-router/LICENSE | 21 + .../packages/h5-vue-router/README.md | 65 + .../h5-vue-router/dist/vue-router.common.js | 2783 ++++ .../h5-vue-router/dist/vue-router.esm.js | 2781 ++++ .../packages/h5-vue-router/dist/vue-router.js | 2789 ++++ .../h5-vue-router/dist/vue-router.min.js | 6 + .../packages/h5-vue-router/package.json | 22 + .../packages/h5-vue-router/types/index.d.ts | 16 + .../packages/h5-vue-router/types/router.d.ts | 126 + .../packages/h5-vue-router/types/vue.d.ts | 22 + .../packages/h5-vue-style-loader/CHANGELOG.md | 68 + .../packages/h5-vue-style-loader/LICENSE | 20 + .../packages/h5-vue-style-loader/README.md | 47 + .../packages/h5-vue-style-loader/index.js | 98 + .../lib/addStylesClient.js | 275 + .../lib/addStylesServer.js | 80 + .../lib/addStylesShadow.js | 70 + .../h5-vue-style-loader/lib/listToStyles.js | 27 + .../packages/h5-vue-style-loader/package.json | 26 + .../packages/h5-vue-style-loader/test/test.js | 94 + .../packages/h5-vue-style-loader/yarn.lock | 3274 +++++ .../packages/h5-vue/LICENSE | 21 + .../packages/h5-vue/README.md | 264 + .../packages/h5-vue/dist/README.md | 124 + .../packages/h5-vue/dist/vue.common.dev.js | 11976 +++++++++++++++ .../packages/h5-vue/dist/vue.common.js | 5 + .../packages/h5-vue/dist/vue.common.prod.js | 6 + .../packages/h5-vue/dist/vue.esm.browser.js | 12033 ++++++++++++++++ .../h5-vue/dist/vue.esm.browser.min.js | 6 + .../packages/h5-vue/dist/vue.esm.js | 12010 +++++++++++++++ .../packages/h5-vue/dist/vue.js | 11982 +++++++++++++++ .../packages/h5-vue/dist/vue.min.js | 6 + .../h5-vue/dist/vue.runtime.common.dev.js | 8455 +++++++++++ .../h5-vue/dist/vue.runtime.common.js | 5 + .../h5-vue/dist/vue.runtime.common.prod.js | 6 + .../packages/h5-vue/dist/vue.runtime.esm.js | 8483 +++++++++++ .../h5-vue/dist/vue.runtime.esm.min.js | 6 + .../packages/h5-vue/dist/vue.runtime.js | 8461 +++++++++++ .../packages/h5-vue/dist/vue.runtime.min.js | 6 + .../packages/h5-vue/package.json | 19 + .../packages/h5-vue/types/index.d.ts | 40 + .../packages/h5-vue/types/options.d.ts | 206 + .../packages/h5-vue/types/plugin.d.ts | 8 + .../packages/h5-vue/types/vnode.d.ts | 76 + .../packages/h5-vue/types/vue.d.ts | 128 + .../packages/megalo/LICENSE | 21 + .../packages/megalo/README.md | 39 + .../packages/megalo/dist/README.md | 124 + .../packages/megalo/dist/megalo.mp.esm.js | 7203 +++++++++ .../packages/megalo/dist/vue.common.js | 10959 ++++++++++++++ .../packages/megalo/dist/vue.esm.browser.js | 10733 ++++++++++++++ .../packages/megalo/dist/vue.esm.js | 10957 ++++++++++++++ .../packages/megalo/dist/vue.js | 10946 ++++++++++++++ .../packages/megalo/dist/vue.min.js | 6 + .../megalo/dist/vue.runtime.common.js | 8033 +++++++++++ .../packages/megalo/dist/vue.runtime.esm.js | 8031 +++++++++++ .../packages/megalo/dist/vue.runtime.js | 8020 ++++++++++ .../packages/megalo/dist/vue.runtime.min.js | 6 + .../packages/megalo/package.json | 39 + .../packages/megalo/types/index.d.ts | 37 + .../packages/megalo/types/options.d.ts | 182 + .../packages/megalo/types/plugin.d.ts | 8 + .../packages/megalo/types/vnode.d.ts | 67 + .../packages/megalo/types/vue.d.ts | 124 + .../packages/mp-vue/LICENSE | 21 + .../packages/mp-vue/README.md | 264 + .../packages/mp-vue/dist/mp.runtime.esm.js | 5946 ++++++++ .../packages/mp-vue/package.json | 16 + .../packages/mp-vue/types/index.d.ts | 37 + .../packages/mp-vue/types/options.d.ts | 182 + .../packages/mp-vue/types/plugin.d.ts | 8 + .../packages/mp-vue/types/vnode.d.ts | 67 + .../packages/mp-vue/types/vue.d.ts | 124 + .../packages/mpvue-page-factory/LICENSE | 21 + .../packages/mpvue-page-factory/README.md | 60 + .../packages/mpvue-page-factory/index.d.ts | 7 + .../packages/mpvue-page-factory/index.js | 168 + .../packages/mpvue-page-factory/package.json | 45 + .../mpvue-template-compiler/MODIFY.md | 3 + .../mpvue-template-compiler/README.md | 3 + .../packages/mpvue-template-compiler/build.js | 5167 +++++++ .../packages/mpvue-template-compiler/index.js | 17 + .../mpvue-template-compiler/package.json | 27 + .../packages/mpvue/README.md | 3 + .../packages/mpvue/index.js | 5732 ++++++++ .../packages/postcss/index.js | 249 + .../packages/postcss/tags.js | 123 + .../packages/webpack-errors-plugin/index.js | 4 + .../packages/webpack-errors-plugin/utils.js | 18 + .../webpack-errors-plugin.js | 54 + .../webpack-html-append-plugin/index.js | 20 + .../webpack-preprocess-loader/index.js | 61 + .../preprocess/LICENSE | 13 + .../preprocess/README.md | 410 + .../preprocess/lib/preprocess.js | 431 + .../preprocess/lib/regexrules.js | 114 + .../preprocess/package.json | 68 + .../packages/webpack-scoped-loader/index.js | 15 + packages/vue-cli-plugin-uni/ui-public/h5.png | Bin 0 -> 3544 bytes .../vue-cli-plugin-uni/ui-public/logo.png | Bin 0 -> 4023 bytes packages/vue-cli-plugin-uni/ui.js | 155 + .../vue-cli-plugin-uni/util/format-errors.js | 134 + packages/vue-cli-plugin-uni/util/on-errors.js | 35 + packages/webpack-uni-mp-loader/LICENSE | 202 + .../__tests__/components.spec.js | 92 + .../lib/babel-plugin-global-component.js | 67 + .../lib/babel-plugin-scoped-component.js | 89 + .../lib/babel/global-component-traverse.js | 46 + .../lib/babel/plugin-create-app.js | 25 + .../lib/babel/plugin-dynamic-import.js | 44 + .../lib/babel/scoped-component-traverse.js | 61 + .../webpack-uni-mp-loader/lib/babel/util.js | 85 + .../webpack-uni-mp-loader/lib/main-new.js | 143 + packages/webpack-uni-mp-loader/lib/main.js | 94 + .../lib/plugin/compile-to-template.js | 71 + .../lib/plugin/generate-app.js | 97 + .../lib/plugin/generate-component.js | 92 + .../lib/plugin/generate-components-wxml.js | 221 + .../lib/plugin/generate-json.js | 174 + .../lib/plugin/generate-pages-wxml.js | 28 + .../lib/plugin/index-new.js | 96 + .../webpack-uni-mp-loader/lib/plugin/index.js | 107 + .../webpack-uni-mp-loader/lib/plugin/util.js | 30 + .../webpack-uni-mp-loader/lib/script-new.js | 130 + packages/webpack-uni-mp-loader/lib/script.js | 69 + packages/webpack-uni-mp-loader/lib/shared.js | 110 + packages/webpack-uni-mp-loader/lib/style.js | 66 + .../webpack-uni-mp-loader/lib/template-new.js | 53 + .../webpack-uni-mp-loader/lib/template.js | 69 + packages/webpack-uni-mp-loader/package.json | 14 + packages/webpack-uni-pages-loader/LICENSE | 202 + .../webpack-uni-pages-loader/lib/index-new.js | 85 + .../webpack-uni-pages-loader/lib/index.js | 87 + .../lib/platforms/app-plus/index.js | 400 + .../lib/platforms/app-plus/manifest.json | 37 + .../lib/platforms/app-plus/tabbar.js | 3 + .../lib/platforms/h5.js | 329 + .../lib/platforms/mp-alipay.js | 52 + .../lib/platforms/mp-baidu/index.js | 19 + .../lib/platforms/mp-baidu/project.swan.json | 10 + .../lib/platforms/mp-qq/index.js | 16 + .../lib/platforms/mp-qq/project.config.json | 35 + .../lib/platforms/mp-toutiao/index.js | 7 + .../platforms/mp-toutiao/project.config.json | 11 + .../lib/platforms/mp-weixin/index.js | 7 + .../platforms/mp-weixin/project.config.json | 35 + .../lib/platforms/mp.js | 299 + .../lib/platforms/quickapp.js | 0 packages/webpack-uni-pages-loader/lib/util.js | 107 + .../webpack-uni-pages-loader/package.json | 21 + .../mp-alipay/runtime/api/protocols.js | 2 +- .../mp-toutiao/runtime/api/protocols.js | 28 +- 307 files changed, 215623 insertions(+), 18 deletions(-) create mode 100644 lerna.json create mode 100755 packages/uni-cli-shared/LICENSE create mode 100644 packages/uni-cli-shared/__tests__/cache.spec.js create mode 100644 packages/uni-cli-shared/lib/api.js create mode 100644 packages/uni-cli-shared/lib/cache.js create mode 100644 packages/uni-cli-shared/lib/index.js create mode 100644 packages/uni-cli-shared/lib/json.js create mode 100644 packages/uni-cli-shared/lib/manifest.js create mode 100644 packages/uni-cli-shared/lib/package.js create mode 100644 packages/uni-cli-shared/lib/pages.js create mode 100644 packages/uni-cli-shared/lib/platform.js create mode 100644 packages/uni-cli-shared/lib/scss.js create mode 100644 packages/uni-cli-shared/lib/tags.js create mode 100644 packages/uni-cli-shared/lib/util.js create mode 100644 packages/uni-cli-shared/package.json create mode 100755 packages/uni-template-compiler/LICENSE create mode 100644 packages/uni-template-compiler/__tests__/compiler-extra.spec.js create mode 100644 packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js create mode 100644 packages/uni-template-compiler/__tests__/compiler-mp-baidu.spec.js create mode 100644 packages/uni-template-compiler/__tests__/compiler-mp-qq.spec.js create mode 100644 packages/uni-template-compiler/__tests__/compiler-mp-toutiao.spec.js create mode 100644 packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js create mode 100644 packages/uni-template-compiler/__tests__/compiler.spec.js create mode 100644 packages/uni-template-compiler/lib/codeframe.js create mode 100644 packages/uni-template-compiler/lib/constants.js create mode 100644 packages/uni-template-compiler/lib/data/traverse.js create mode 100644 packages/uni-template-compiler/lib/h5.js create mode 100644 packages/uni-template-compiler/lib/index.js create mode 100644 packages/uni-template-compiler/lib/module.js create mode 100644 packages/uni-template-compiler/lib/platforms/index.js create mode 100644 packages/uni-template-compiler/lib/platforms/mp-alipay.js create mode 100644 packages/uni-template-compiler/lib/platforms/mp-baidu.js create mode 100644 packages/uni-template-compiler/lib/platforms/mp-base.js create mode 100644 packages/uni-template-compiler/lib/platforms/mp-toutiao.js create mode 100644 packages/uni-template-compiler/lib/platforms/mp-weixin.js create mode 100644 packages/uni-template-compiler/lib/script/generate.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/data/attrs.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/data/class.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/data/directives.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/data/event.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/data/index.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/data/model.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/data/ref.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/data/style.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/data/tag.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/data/util.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/filter.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/index.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/member-expr.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/render-list.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/statements.js create mode 100644 packages/uni-template-compiler/lib/script/traverse/visitor.js create mode 100644 packages/uni-template-compiler/lib/template/generate.js create mode 100644 packages/uni-template-compiler/lib/template/traverse.js create mode 100644 packages/uni-template-compiler/lib/util.js create mode 100644 packages/uni-template-compiler/package.json create mode 100755 packages/vue-cli-plugin-hbuilderx/LICENSE create mode 100644 packages/vue-cli-plugin-hbuilderx/README.md create mode 100644 packages/vue-cli-plugin-hbuilderx/build/css-loader.conf.js create mode 100644 packages/vue-cli-plugin-hbuilderx/build/utils.js create mode 100644 packages/vue-cli-plugin-hbuilderx/build/vue-loader.conf.js create mode 100644 packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js create mode 100644 packages/vue-cli-plugin-hbuilderx/fork-ts-checker-webpack-plugin.fake.js create mode 100644 packages/vue-cli-plugin-hbuilderx/generator.js create mode 100644 packages/vue-cli-plugin-hbuilderx/index.js create mode 100644 packages/vue-cli-plugin-hbuilderx/logo.png create mode 100644 packages/vue-cli-plugin-hbuilderx/module-alias.js create mode 100644 packages/vue-cli-plugin-hbuilderx/package.json create mode 100755 packages/vue-cli-plugin-hbuilderx/packages/babel-plugin-console/LICENSE create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/babel-plugin-console/dist/index.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/babel-plugin-console/package.json create mode 100755 packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue-v8/LICENSE create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue-v8/dist/index.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue-v8/package.json create mode 100755 packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue/LICENSE create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue/dist/index.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue/package.json create mode 100755 packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/LICENSE create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/dist/index.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/dist/index.new.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/package.json create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/webpack-app-plus-plugin/index.js create mode 100755 packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/LICENSE create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/main.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/style.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/styleInjection.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/template.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/package.json create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-styler/LICENSE create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-styler/README.md create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-styler/circle.yml create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-styler/gulpfile.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-styler/index.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-styler/lib/shorthand-parser.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-styler/lib/util.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-styler/lib/validator.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-styler/package.json create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-styler/test/parse.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-styler/test/shorthand-parser.spec.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-styler/test/validate.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-template-compiler/README.md create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-template-compiler/build.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-template-compiler/index.js create mode 100644 packages/vue-cli-plugin-hbuilderx/packages/weex-template-compiler/package.json create mode 100644 packages/vue-cli-plugin-hbuilderx/template/bin/uniapp-cli.js create mode 100644 packages/vue-cli-plugin-hbuilderx/typescript.json create mode 100755 packages/vue-cli-plugin-uni-optimize/LICENSE create mode 100644 packages/vue-cli-plugin-uni-optimize/README.md create mode 100644 packages/vue-cli-plugin-uni-optimize/index.js create mode 100755 packages/vue-cli-plugin-uni-optimize/logo.png create mode 100644 packages/vue-cli-plugin-uni-optimize/package.json create mode 100644 packages/vue-cli-plugin-uni-optimize/packages/babel-plugin-uni-api/index.js create mode 100644 packages/vue-cli-plugin-uni-optimize/packages/vue-loader/index.js create mode 100644 packages/vue-cli-plugin-uni-optimize/packages/webpack-optimize-plugin/api.js create mode 100644 packages/vue-cli-plugin-uni-optimize/packages/webpack-optimize-plugin/component.js create mode 100644 packages/vue-cli-plugin-uni-optimize/packages/webpack-optimize-plugin/index.js create mode 100644 packages/vue-cli-plugin-uni-optimize/packages/webpack-optimize-plugin/util.js create mode 100644 packages/vue-cli-plugin-uni-optimize/packages/webpack-style-loader/index.js create mode 100755 packages/vue-cli-plugin-uni/LICENSE create mode 100644 packages/vue-cli-plugin-uni/README.md create mode 100755 packages/vue-cli-plugin-uni/bin/uniapp-cli.js create mode 100644 packages/vue-cli-plugin-uni/commands/build.js create mode 100644 packages/vue-cli-plugin-uni/commands/info.js create mode 100644 packages/vue-cli-plugin-uni/commands/serve.js create mode 100644 packages/vue-cli-plugin-uni/generator.js create mode 100644 packages/vue-cli-plugin-uni/index.js create mode 100644 packages/vue-cli-plugin-uni/lib/app-plus/index.js create mode 100644 packages/vue-cli-plugin-uni/lib/chain-webpack.js create mode 100644 packages/vue-cli-plugin-uni/lib/check-update.js create mode 100644 packages/vue-cli-plugin-uni/lib/configure-webpack.js create mode 100644 packages/vue-cli-plugin-uni/lib/copy-webpack-options.js create mode 100644 packages/vue-cli-plugin-uni/lib/env.js create mode 100644 packages/vue-cli-plugin-uni/lib/format-log.js create mode 100644 packages/vue-cli-plugin-uni/lib/format-text.js create mode 100644 packages/vue-cli-plugin-uni/lib/h5/auto-reload.js create mode 100644 packages/vue-cli-plugin-uni/lib/h5/compiler-options.js create mode 100644 packages/vue-cli-plugin-uni/lib/h5/index.js create mode 100644 packages/vue-cli-plugin-uni/lib/mp-alipay/index.js create mode 100644 packages/vue-cli-plugin-uni/lib/mp-baidu/index.js create mode 100644 packages/vue-cli-plugin-uni/lib/mp-compiler-options.js create mode 100644 packages/vue-cli-plugin-uni/lib/mp-qq/index.js create mode 100644 packages/vue-cli-plugin-uni/lib/mp-toutiao/index.js create mode 100644 packages/vue-cli-plugin-uni/lib/mp-weixin/index.js create mode 100644 packages/vue-cli-plugin-uni/lib/mp.js create mode 100644 packages/vue-cli-plugin-uni/lib/options.js create mode 100644 packages/vue-cli-plugin-uni/lib/scoped.js create mode 100644 packages/vue-cli-plugin-uni/lib/split-chunks.js create mode 100755 packages/vue-cli-plugin-uni/logo.png create mode 100644 packages/vue-cli-plugin-uni/package.json create mode 100644 packages/vue-cli-plugin-uni/packages/@megalo/template-compiler/build.js create mode 100644 packages/vue-cli-plugin-uni/packages/@megalo/template-compiler/demo/index.js create mode 100644 packages/vue-cli-plugin-uni/packages/@megalo/template-compiler/index.js create mode 100644 packages/vue-cli-plugin-uni/packages/@megalo/template-compiler/package.json create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-router/LICENSE create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-router/README.md create mode 100755 packages/vue-cli-plugin-uni/packages/h5-vue-router/dist/vue-router.common.js create mode 100755 packages/vue-cli-plugin-uni/packages/h5-vue-router/dist/vue-router.esm.js create mode 100755 packages/vue-cli-plugin-uni/packages/h5-vue-router/dist/vue-router.js create mode 100755 packages/vue-cli-plugin-uni/packages/h5-vue-router/dist/vue-router.min.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-router/package.json create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-router/types/index.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-router/types/router.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-router/types/vue.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/CHANGELOG.md create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/LICENSE create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/README.md create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/index.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/lib/addStylesClient.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/lib/addStylesServer.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/lib/addStylesShadow.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/lib/listToStyles.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/package.json create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/test/test.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/yarn.lock create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/LICENSE create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/README.md create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/README.md create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.common.dev.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.common.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.common.prod.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.esm.browser.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.esm.browser.min.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.esm.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.min.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.runtime.common.dev.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.runtime.common.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.runtime.common.prod.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.runtime.esm.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.runtime.esm.min.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.runtime.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.runtime.min.js create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/package.json create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/types/index.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/types/options.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/types/plugin.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/types/vnode.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/h5-vue/types/vue.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/LICENSE create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/README.md create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/dist/README.md create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/dist/megalo.mp.esm.js create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/dist/vue.common.js create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/dist/vue.esm.browser.js create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/dist/vue.esm.js create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/dist/vue.js create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/dist/vue.min.js create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/dist/vue.runtime.common.js create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/dist/vue.runtime.esm.js create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/dist/vue.runtime.js create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/dist/vue.runtime.min.js create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/package.json create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/types/index.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/types/options.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/types/plugin.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/types/vnode.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/megalo/types/vue.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/mp-vue/LICENSE create mode 100644 packages/vue-cli-plugin-uni/packages/mp-vue/README.md create mode 100644 packages/vue-cli-plugin-uni/packages/mp-vue/dist/mp.runtime.esm.js create mode 100644 packages/vue-cli-plugin-uni/packages/mp-vue/package.json create mode 100644 packages/vue-cli-plugin-uni/packages/mp-vue/types/index.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/mp-vue/types/options.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/mp-vue/types/plugin.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/mp-vue/types/vnode.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/mp-vue/types/vue.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/mpvue-page-factory/LICENSE create mode 100644 packages/vue-cli-plugin-uni/packages/mpvue-page-factory/README.md create mode 100644 packages/vue-cli-plugin-uni/packages/mpvue-page-factory/index.d.ts create mode 100644 packages/vue-cli-plugin-uni/packages/mpvue-page-factory/index.js create mode 100644 packages/vue-cli-plugin-uni/packages/mpvue-page-factory/package.json create mode 100644 packages/vue-cli-plugin-uni/packages/mpvue-template-compiler/MODIFY.md create mode 100644 packages/vue-cli-plugin-uni/packages/mpvue-template-compiler/README.md create mode 100644 packages/vue-cli-plugin-uni/packages/mpvue-template-compiler/build.js create mode 100644 packages/vue-cli-plugin-uni/packages/mpvue-template-compiler/index.js create mode 100644 packages/vue-cli-plugin-uni/packages/mpvue-template-compiler/package.json create mode 100644 packages/vue-cli-plugin-uni/packages/mpvue/README.md create mode 100644 packages/vue-cli-plugin-uni/packages/mpvue/index.js create mode 100644 packages/vue-cli-plugin-uni/packages/postcss/index.js create mode 100644 packages/vue-cli-plugin-uni/packages/postcss/tags.js create mode 100644 packages/vue-cli-plugin-uni/packages/webpack-errors-plugin/index.js create mode 100644 packages/vue-cli-plugin-uni/packages/webpack-errors-plugin/utils.js create mode 100644 packages/vue-cli-plugin-uni/packages/webpack-errors-plugin/webpack-errors-plugin.js create mode 100644 packages/vue-cli-plugin-uni/packages/webpack-html-append-plugin/index.js create mode 100644 packages/vue-cli-plugin-uni/packages/webpack-preprocess-loader/index.js create mode 100755 packages/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess/LICENSE create mode 100755 packages/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess/README.md create mode 100755 packages/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess/lib/preprocess.js create mode 100755 packages/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess/lib/regexrules.js create mode 100755 packages/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess/package.json create mode 100644 packages/vue-cli-plugin-uni/packages/webpack-scoped-loader/index.js create mode 100644 packages/vue-cli-plugin-uni/ui-public/h5.png create mode 100755 packages/vue-cli-plugin-uni/ui-public/logo.png create mode 100644 packages/vue-cli-plugin-uni/ui.js create mode 100644 packages/vue-cli-plugin-uni/util/format-errors.js create mode 100644 packages/vue-cli-plugin-uni/util/on-errors.js create mode 100755 packages/webpack-uni-mp-loader/LICENSE create mode 100644 packages/webpack-uni-mp-loader/__tests__/components.spec.js create mode 100644 packages/webpack-uni-mp-loader/lib/babel-plugin-global-component.js create mode 100644 packages/webpack-uni-mp-loader/lib/babel-plugin-scoped-component.js create mode 100644 packages/webpack-uni-mp-loader/lib/babel/global-component-traverse.js create mode 100644 packages/webpack-uni-mp-loader/lib/babel/plugin-create-app.js create mode 100644 packages/webpack-uni-mp-loader/lib/babel/plugin-dynamic-import.js create mode 100644 packages/webpack-uni-mp-loader/lib/babel/scoped-component-traverse.js create mode 100644 packages/webpack-uni-mp-loader/lib/babel/util.js create mode 100644 packages/webpack-uni-mp-loader/lib/main-new.js create mode 100644 packages/webpack-uni-mp-loader/lib/main.js create mode 100644 packages/webpack-uni-mp-loader/lib/plugin/compile-to-template.js create mode 100644 packages/webpack-uni-mp-loader/lib/plugin/generate-app.js create mode 100644 packages/webpack-uni-mp-loader/lib/plugin/generate-component.js create mode 100644 packages/webpack-uni-mp-loader/lib/plugin/generate-components-wxml.js create mode 100644 packages/webpack-uni-mp-loader/lib/plugin/generate-json.js create mode 100644 packages/webpack-uni-mp-loader/lib/plugin/generate-pages-wxml.js create mode 100644 packages/webpack-uni-mp-loader/lib/plugin/index-new.js create mode 100644 packages/webpack-uni-mp-loader/lib/plugin/index.js create mode 100644 packages/webpack-uni-mp-loader/lib/plugin/util.js create mode 100644 packages/webpack-uni-mp-loader/lib/script-new.js create mode 100644 packages/webpack-uni-mp-loader/lib/script.js create mode 100644 packages/webpack-uni-mp-loader/lib/shared.js create mode 100644 packages/webpack-uni-mp-loader/lib/style.js create mode 100644 packages/webpack-uni-mp-loader/lib/template-new.js create mode 100644 packages/webpack-uni-mp-loader/lib/template.js create mode 100644 packages/webpack-uni-mp-loader/package.json create mode 100755 packages/webpack-uni-pages-loader/LICENSE create mode 100644 packages/webpack-uni-pages-loader/lib/index-new.js create mode 100644 packages/webpack-uni-pages-loader/lib/index.js create mode 100644 packages/webpack-uni-pages-loader/lib/platforms/app-plus/index.js create mode 100644 packages/webpack-uni-pages-loader/lib/platforms/app-plus/manifest.json create mode 100644 packages/webpack-uni-pages-loader/lib/platforms/app-plus/tabbar.js create mode 100644 packages/webpack-uni-pages-loader/lib/platforms/h5.js create mode 100644 packages/webpack-uni-pages-loader/lib/platforms/mp-alipay.js create mode 100644 packages/webpack-uni-pages-loader/lib/platforms/mp-baidu/index.js create mode 100644 packages/webpack-uni-pages-loader/lib/platforms/mp-baidu/project.swan.json create mode 100644 packages/webpack-uni-pages-loader/lib/platforms/mp-qq/index.js create mode 100644 packages/webpack-uni-pages-loader/lib/platforms/mp-qq/project.config.json create mode 100644 packages/webpack-uni-pages-loader/lib/platforms/mp-toutiao/index.js create mode 100644 packages/webpack-uni-pages-loader/lib/platforms/mp-toutiao/project.config.json create mode 100644 packages/webpack-uni-pages-loader/lib/platforms/mp-weixin/index.js create mode 100644 packages/webpack-uni-pages-loader/lib/platforms/mp-weixin/project.config.json create mode 100644 packages/webpack-uni-pages-loader/lib/platforms/mp.js create mode 100644 packages/webpack-uni-pages-loader/lib/platforms/quickapp.js create mode 100644 packages/webpack-uni-pages-loader/lib/util.js create mode 100644 packages/webpack-uni-pages-loader/package.json diff --git a/.eslintignore b/.eslintignore index 69aec5f64..638e7368b 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,4 @@ src/core/helpers/html-parser.js src/platforms/app-plus-nvue/runtime build/rollup-plugin-require-context +packages/*/packages diff --git a/lerna.json b/lerna.json new file mode 100644 index 000000000..ca5132b76 --- /dev/null +++ b/lerna.json @@ -0,0 +1,8 @@ +{ + "npmClient": "yarn", + "useWorkspaces": false, + "packages": [ + "packages/*" + ], + "version": "0.9.50" +} diff --git a/package.json b/package.json index 42f26eb60..7fb385e34 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "0.0.1", "scripts": { "lint": "eslint --fix --config package.json --ext .js --ext .vue --ignore-path .eslintignore build src", + "lint:cli": "eslint --fix --config package.json --ignore-path .eslintignore packages/uni-cli-shared packages/uni-template-compiler \"packages/vue-cli-*/**/*.js\" \"packages/webpack-uni-*/**/*.js\"", "dev:h5": "npm run lint && cross-env NODE_ENV=production UNI_WATCH=true UNI_PLATFORM=h5 node build/build.js", "build:h5": "npm run lint && cross-env NODE_ENV=production UNI_WATCH=false UNI_PLATFORM=h5 node build/build.js", "build:app-plus": "cross-env UNI_PLATFORM=app-plus rollup -c build/rollup.config.mp.js", @@ -81,8 +82,8 @@ "Vue": true, "wx": true, "my": true, - "swan": true, - "weex": true, + "swan": true, + "weex": true, "__id__": true, "__uniConfig": true, "__uniRoutes": true, @@ -93,7 +94,10 @@ "__VERSION__": true, "__GLOBAL__": true, "__PLATFORM_TITLE__": true, - "__PLATFORM_PREFIX__": true + "__PLATFORM_PREFIX__": true, + "it": true, + "describe": true, + "expect": true }, "rules": { "no-tabs": 0, diff --git a/packages/uni-cli-shared/LICENSE b/packages/uni-cli-shared/LICENSE new file mode 100755 index 000000000..7a4a3ea24 --- /dev/null +++ b/packages/uni-cli-shared/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/packages/uni-cli-shared/__tests__/cache.spec.js b/packages/uni-cli-shared/__tests__/cache.spec.js new file mode 100644 index 000000000..66d9950e5 --- /dev/null +++ b/packages/uni-cli-shared/__tests__/cache.spec.js @@ -0,0 +1,81 @@ +const { + updateAppJson, + updatePageJson, + updateUsingComponents, + getChangedJsonFileMap +} = require('../lib/cache') + +describe('shared:cache', () => { + it('generate app.json', () => { + const name = 'app' + const appJson = { + debug: true + } + updateAppJson(name, appJson) + let appJsonStr = getChangedJsonFileMap().get(name + '.json') + expect(appJsonStr).toBe(JSON.stringify(appJson, null, 2)) + expect(0).toBe(getChangedJsonFileMap().size) + + appJson.resizable = true + updateAppJson(name, appJson) + appJsonStr = getChangedJsonFileMap().get(name + '.json') + expect(appJsonStr).toBe(JSON.stringify(appJson, null, 2)) + expect(0).toBe(getChangedJsonFileMap().size) + + const usingComponents = { + 'my-component': '/components/component-tag-name' + } + updateUsingComponents('app', usingComponents) + appJsonStr = getChangedJsonFileMap().get(name + '.json') + appJson.usingComponents = usingComponents + expect(appJsonStr).toBe(JSON.stringify(appJson, null, 2)) + }) + + it('generate page.json', () => { + const name = 'page/index/index' + const pageJson = { + navigationBarBackgroundColor: '#ffffff' + } + updatePageJson(name, pageJson) + let pageJsonStr = getChangedJsonFileMap().get(name + '.json') + expect(pageJsonStr).toBe(JSON.stringify(pageJson, null, 2)) + expect(0).toBe(getChangedJsonFileMap().size) + + pageJson.navigationBarTextStyle = 'black' + updatePageJson(name, pageJson) + pageJsonStr = getChangedJsonFileMap().get(name + '.json') + expect(pageJsonStr).toBe(JSON.stringify(pageJson, null, 2)) + expect(0).toBe(getChangedJsonFileMap().size) + + const usingComponents = { + 'my-component1': '/components/component-tag-name1' + } + updateUsingComponents(name, usingComponents) + pageJsonStr = getChangedJsonFileMap().get(name + '.json') + pageJson.usingComponents = usingComponents + expect(pageJsonStr).toBe(JSON.stringify(pageJson, null, 2)) + }) + + it('generate component.json', () => { + const name = 'components/component-tag-name' + let usingComponents = { + 'my-component': '/components/component-tag-name' + } + updateUsingComponents(name, usingComponents, 'Component') + let componentJsonStr = getChangedJsonFileMap().get(name + '.json') + expect(componentJsonStr).toBe(JSON.stringify({ + usingComponents, + component: true + }, null, 2)) + expect(0).toBe(getChangedJsonFileMap().size) + + usingComponents = {} + updateUsingComponents(name, usingComponents, 'Component') + componentJsonStr = getChangedJsonFileMap().get(name + '.json') + expect(componentJsonStr).toBe(JSON.stringify({ + usingComponents, + component: true + }, null, 2)) + expect(0).toBe(getChangedJsonFileMap().size) + }) +}) diff --git a/packages/uni-cli-shared/lib/api.js b/packages/uni-cli-shared/lib/api.js new file mode 100644 index 000000000..4c77fd565 --- /dev/null +++ b/packages/uni-cli-shared/lib/api.js @@ -0,0 +1,23 @@ +function parseApis (modules, test) { + return modules.reduce(function (apis, module) { + const apiList = module.apiList + apiList && Object.keys(apiList).forEach(name => { + if (test(name, apiList[name])) { + apis.add(name.replace('uni.', '')) + } + }) + return apis + }, new Set()) +} + +module.exports = { + parseUserApis (configModules = [], allModules = []) { + const blackboxApis = parseApis(configModules, function (name, value) { + return value === false + }) + const allApis = parseApis(allModules, function () { + return true + }) + return [...allApis].filter(name => !blackboxApis.has(name)) + } +} diff --git a/packages/uni-cli-shared/lib/cache.js b/packages/uni-cli-shared/lib/cache.js new file mode 100644 index 000000000..531e13239 --- /dev/null +++ b/packages/uni-cli-shared/lib/cache.js @@ -0,0 +1,242 @@ +/** + * 1.page-loader 缓存基础的 app.json page.json project.config.json + * 2.main-loader 缓存 app.json 中的 usingComponents 节点 + * 3.script-loader 修改缓存 usingComponents 节点 + * 5.webpack plugin 中获取被修改的 page.json,component.json 并 emitFile + */ +const jsonFileMap = new Map() +const changedJsonFileSet = new Set() +const componentSet = new Set() + +const pageSet = new Set() + +let globalUsingComponents = Object.create(null) +let appJsonUsingComponents = Object.create(null) +let componentSpecialMethods = Object.create(null) + +function getPagesJson () { + if (process.env.UNI_PLATFORM === 'h5') { + return process.UNI_H5_PAGES_JSON + } + const pagesJson = { + pages: {} + } + for (let name of pageSet.values()) { + const style = JSON.parse(getJsonFile(name) || '{}') + delete style.customUsingComponents + pagesJson.pages[name] = style + } + const appJson = JSON.parse(getJsonFile('app') || '{}') + pagesJson.globalStyle = appJson['window'] || {} + return pagesJson +} + +function updateJsonFile (name, jsonStr) { + changedJsonFileSet.add(name) + if (typeof jsonStr !== 'string') { + jsonStr = JSON.stringify(jsonStr, null, 2) + } + jsonFileMap.set(name, jsonStr) +} + +function getJsonFile (name) { + return jsonFileMap.get(name) +} + +function getChangedJsonFileMap (clear = true) { + const changedJsonFileMap = new Map() + for (let name of changedJsonFileSet.values()) { + changedJsonFileMap.set(name + '.json', jsonFileMap.get(name)) + } + clear && changedJsonFileSet.clear() + return changedJsonFileMap +} + +function updateAppJson (name, jsonObj) { + updateComponentJson(name, jsonObj) +} + +function updatePageJson (name, jsonObj) { + pageSet.add(name) + updateComponentJson(name, jsonObj) +} + +function updateProjectJson (name, jsonObj) { + updateComponentJson(name, jsonObj, false) +} + +const supportGlobalUsingComponents = process.env.UNI_PLATFORM === 'mp-weixin' || process.env.UNI_PLATFORM === 'mp-qq' + +function updateComponentJson (name, jsonObj, usingComponents = true) { + const oldJsonStr = getJsonFile(name) + if (oldJsonStr) { // update + if (usingComponents) { // merge usingComponents + jsonObj.usingComponents = JSON.parse(oldJsonStr).usingComponents || {} + } + const newJsonStr = JSON.stringify(jsonObj, null, 2) + if (newJsonStr !== oldJsonStr) { + updateJsonFile(name, newJsonStr) + } + } else { // add + updateJsonFile(name, jsonObj) + } +} + +function updateUsingGlobalComponents (name, usingGlobalComponents) { + if (supportGlobalUsingComponents) { + return + } + const oldJsonStr = getJsonFile(name) + if (oldJsonStr) { // update + const jsonObj = JSON.parse(oldJsonStr) + jsonObj.usingGlobalComponents = usingGlobalComponents + const newJsonStr = JSON.stringify(jsonObj, null, 2) + if (newJsonStr !== oldJsonStr) { + updateJsonFile(name, newJsonStr) + } + } else { // add + const jsonObj = { + usingGlobalComponents + } + updateJsonFile(name, jsonObj) + } +} + +function updateUsingComponents (name, usingComponents, type) { + if (type === 'Component') { + componentSet.add(name) + } + if (type === 'App') { // 记录全局组件 + globalUsingComponents = usingComponents + } + + const oldJsonStr = getJsonFile(name) + if (oldJsonStr) { // update + const jsonObj = JSON.parse(oldJsonStr) + if (type === 'Component') { + jsonObj.component = true + } else if (type === 'Page') { + if (process.env.UNI_PLATFORM === 'mp-baidu') { + jsonObj.component = true + } + } + + jsonObj.usingComponents = usingComponents + const newJsonStr = JSON.stringify(jsonObj, null, 2) + if (newJsonStr !== oldJsonStr) { + updateJsonFile(name, newJsonStr) + } + } else { // add + const jsonObj = { + usingComponents + } + if (type === 'Component') { + jsonObj.component = true + } else if (type === 'Page') { + if (process.env.UNI_PLATFORM === 'mp-baidu') { + jsonObj.component = true + } + } + + updateJsonFile(name, jsonObj) + } +} + +function updateComponentGenerics (name, componentGenerics) { + const oldJsonStr = getJsonFile(name) + if (oldJsonStr) { // update + const jsonObj = JSON.parse(oldJsonStr) + jsonObj.componentGenerics = componentGenerics + const newJsonStr = JSON.stringify(jsonObj, null, 2) + if (newJsonStr !== oldJsonStr) { + updateJsonFile(name, newJsonStr) + } + } else { // add + const jsonObj = { + componentGenerics + } + updateJsonFile(name, jsonObj) + } +} + +function updateGenericComponents (name, genericComponents) { + const oldJsonStr = getJsonFile(name) + if (oldJsonStr) { // update + const jsonObj = JSON.parse(oldJsonStr) + jsonObj.genericComponents = genericComponents + const newJsonStr = JSON.stringify(jsonObj, null, 2) + if (newJsonStr !== oldJsonStr) { + updateJsonFile(name, newJsonStr) + } + } else { // add + const jsonObj = { + genericComponents + } + updateJsonFile(name, jsonObj) + } +} + +function updateAppJsonUsingComponents (usingComponents) { + appJsonUsingComponents = usingComponents +} + +function getComponentSet () { + return componentSet +} + +function getGlobalUsingComponents () { + // 合并 app.json ,main.js 全局组件 + return Object.assign({}, appJsonUsingComponents, globalUsingComponents) +} + +function getWXComponents (name) { + const oldJsonStr = getJsonFile(name) + if (oldJsonStr) { + const jsonObj = JSON.parse(oldJsonStr) + if (jsonObj.customUsingComponents) { + return Object.assign({}, appJsonUsingComponents, jsonObj.customUsingComponents) + } + } + return Object.assign({}, appJsonUsingComponents) +} + +function updateSpecialMethods (name, specialMethods) { + if (specialMethods.length) { + componentSpecialMethods[name] = specialMethods + } else { + delete componentSpecialMethods[name] + } +} + +function getSpecialMethods (name) { + if (!name) { + return componentSpecialMethods + } + return componentSpecialMethods[name] || [] +} + +module.exports = { + getPageSet () { + return pageSet + }, + getJsonFileMap () { + return jsonFileMap + }, + getJsonFile, + getPagesJson, + getComponentSet, + getWXComponents, + getGlobalUsingComponents, + updateAppJson, + updatePageJson, + updateProjectJson, + updateComponentJson, + updateSpecialMethods, + updateUsingComponents, + updateUsingGlobalComponents, + updateAppJsonUsingComponents, + updateComponentGenerics, + updateGenericComponents, + getChangedJsonFileMap, + getSpecialMethods +} diff --git a/packages/uni-cli-shared/lib/index.js b/packages/uni-cli-shared/lib/index.js new file mode 100644 index 000000000..09a392e1f --- /dev/null +++ b/packages/uni-cli-shared/lib/index.js @@ -0,0 +1,112 @@ +const tags = require('./tags') + +const { + getJson, + parseJson +} = require('./json') + +const { + getH5Options, + getManifestJson, + getNetworkTimeout, + parseManifestJson +} = require('./manifest.js') + +const { + getMainEntry, + getNVueMainEntry, + parseEntry, + parsePages, + getPagesJson, + parsePagesJson +} = require('./pages') + +const { + md5, + hasModule, + hashify, + camelize, + hyphenate, + removeExt, + normalizePath, + getComponentName, + convertStaticStyle +} = require('./util') + +const { + getFlexDirection, + getPlatformProject, + isSupportSubPackages, + getPlatforms, + getPlatformGlobal, + getPlatformScss, + getPlatformSass, + runByHBuilderX, + isInHBuilderX, + isInHBuilderXAlpha, + getPlatformExts, + getPlatformTarget, + getPlatformVue, + getPlatformCompiler, + getShadowCss, + getPlatformCssVars, + getPlatformCssnano, + getShadowTemplate, + jsPreprocessOptions, + cssPreprocessOptions, + htmlPreprocessOptions, + nvueJsPreprocessOptions, + nvueCssPreprocessOptions, + nvueHtmlPreprocessOptions, + devtoolModuleFilenameTemplate +} = require('./platform') + +module.exports = { + md5, + tags, + getJson, + parseJson, + hashify, + hasModule, + camelize, + hyphenate, + removeExt, + normalizePath, + parseEntry, + parsePages, + getH5Options, + getMainEntry, + getNVueMainEntry, + getPagesJson, + getManifestJson, + getNetworkTimeout, + runByHBuilderX, + isInHBuilderX, + isInHBuilderXAlpha, + isSupportSubPackages, + getPlatforms, + getFlexDirection, + getPlatformScss, + getPlatformSass, + getPlatformExts, + getPlatformTarget, + getPlatformProject, + getPlatformVue, + getPlatformGlobal, + getShadowCss, + getPlatformCssVars, + getPlatformCssnano, + getPlatformCompiler, + getShadowTemplate, + parsePagesJson, + parseManifestJson, + getComponentName, + convertStaticStyle, + jsPreprocessOptions, + cssPreprocessOptions, + htmlPreprocessOptions, + nvueJsPreprocessOptions, + nvueCssPreprocessOptions, + nvueHtmlPreprocessOptions, + devtoolModuleFilenameTemplate +} diff --git a/packages/uni-cli-shared/lib/json.js b/packages/uni-cli-shared/lib/json.js new file mode 100644 index 000000000..d59ad3e1a --- /dev/null +++ b/packages/uni-cli-shared/lib/json.js @@ -0,0 +1,42 @@ +const fs = require('fs') +const path = require('path') +const stripJsonComments = require('strip-json-comments') +const preprocessor = require('@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess') +const { + jsPreprocessOptions +} = require('./platform') + +function parseJson (content, preprocess = false) { + if (typeof content === 'string') { + if (preprocess) { + content = preprocessor.preprocess(content, jsPreprocessOptions.context, { + type: jsPreprocessOptions.type + }) + } + + content = JSON.parse(stripJsonComments(content)) + } + + content = JSON.stringify(content) + .replace(/\u2028/g, '\\u2028') + .replace(/\u2029/g, '\\u2029') + + return JSON.parse(content) +} + +function getJson (jsonFileName, preprocess = false) { + const jsonFilePath = path.resolve(process.env.UNI_INPUT_DIR, jsonFileName) + if (!fs.existsSync(jsonFilePath)) { + throw new Error(jsonFilePath + ' 不存在') + } + try { + return parseJson(fs.readFileSync(jsonFilePath, 'utf8'), preprocess) + } catch (e) { + console.error(jsonFileName + ' 解析失败') + } +} + +module.exports = { + getJson, + parseJson +} diff --git a/packages/uni-cli-shared/lib/manifest.js b/packages/uni-cli-shared/lib/manifest.js new file mode 100644 index 000000000..2d193c797 --- /dev/null +++ b/packages/uni-cli-shared/lib/manifest.js @@ -0,0 +1,93 @@ +const path = require('path') + +const { + getJson, + parseJson +} = require('./json') + +const defaultRouter = { + mode: 'hash', + base: '/' +} + +const defaultAsync = { + loading: 'AsyncLoading', + error: 'AsyncError', + delay: 200, + timeout: 3000 +} + +const networkTimeout = { + request: 6000, + connectSocket: 6000, + uploadFile: 6000, + downloadFile: 6000 +} + +function getManifestJson () { + return getJson('manifest.json') +} + +function parseManifestJson (content) { + return parseJson(content) +} + +function getNetworkTimeout (manifestJson) { + if (!manifestJson) { + manifestJson = getManifestJson() + } + return Object.assign({}, networkTimeout, manifestJson.networkTimeout || {}) +} + +function getH5Options (manifestJson) { + if (!manifestJson) { + manifestJson = getManifestJson() + } + + const h5 = manifestJson.h5 || {} + + h5.appid = (manifestJson.appid || '').replace('__UNI__', '') + + h5.title = h5.title || manifestJson.name || '' + + h5.router = Object.assign({}, defaultRouter, h5.router || {}) + + h5['async'] = Object.assign({}, defaultAsync, h5['async'] || {}) + + let base = h5.router.base + + if (base.indexOf('/') !== 0) { + base = '/' + base + } + + if (base.substr(-1) !== '/') { + base = base + '/' + } + + h5.router.base = base + + if (process.env.NODE_ENV === 'production') { // 生产模式,启用 publicPath + h5.publicPath = h5.publicPath || base + + if (h5.publicPath.substr(-1) !== '/') { + h5.publicPath = h5.publicPath + '/' + } + } else { // 其他模式,启用 base + h5.publicPath = base + } + + /* eslint-disable no-mixed-operators */ + h5.template = h5.template && path.resolve(process.env.UNI_INPUT_DIR, h5.template) || path.resolve(__dirname, + '../../../../public/index.html') + + h5.devServer = h5.devServer || {} + + return h5 +} + +module.exports = { + getManifestJson, + parseManifestJson, + getNetworkTimeout, + getH5Options +} diff --git a/packages/uni-cli-shared/lib/package.js b/packages/uni-cli-shared/lib/package.js new file mode 100644 index 000000000..b5ba64a79 --- /dev/null +++ b/packages/uni-cli-shared/lib/package.js @@ -0,0 +1,44 @@ +const PLATFORMS = [ + 'h5', + 'app-plus', + 'mp-weixin', + 'mp-qq', + 'mp-baidu', + 'mp-alipay', + 'mp-toutiao' +] + +module.exports = { + initCustomScript (name, pkgPath) { + const pkg = require(pkgPath) + const uniAppOptions = pkg['uni-app'] + + let scriptOptions = false + + if (uniAppOptions && uniAppOptions['scripts']) { + scriptOptions = uniAppOptions['scripts'][name] + } + + if (!scriptOptions) { + console.error(`package.json->uni-app->scripts->${name} 不存在`) + process.exit(0) + } + + if (!scriptOptions.env || !scriptOptions.env.UNI_PLATFORM) { + console.error(`package.json->uni-app->scripts->${name}->env 不存在,必须配置 env->UNI_PLATFORM 基础平台`) + process.exit(0) + } + + if (PLATFORMS.indexOf(scriptOptions.env.UNI_PLATFORM) === -1) { + console.error(`UNI_PLATFORM 支持一下平台 ${JSON.stringify(PLATFORMS)}`) + process.exit(0) + } + + process.env.UNI_PLATFORM = scriptOptions.env.UNI_PLATFORM + + process.UNI_SCRIPT_ENV = scriptOptions.env || {} + process.UNI_SCRIPT_DEFINE = scriptOptions.define || {} + + return scriptOptions + } +} diff --git a/packages/uni-cli-shared/lib/pages.js b/packages/uni-cli-shared/lib/pages.js new file mode 100644 index 000000000..29d1f284f --- /dev/null +++ b/packages/uni-cli-shared/lib/pages.js @@ -0,0 +1,235 @@ +const fs = require('fs') +const path = require('path') + +const { + removeExt, + normalizePath +} = require('./util') + +const { + getJson, + parseJson +} = require('./json') + +let mainEntry = '' +let nvueMainEntry = '' + +function getMainEntry () { + if (!mainEntry) { + mainEntry = fs.existsSync(path.resolve(process.env.UNI_INPUT_DIR, 'main.ts')) ? 'main.ts' : 'main.js' + } + return mainEntry +} + +function getNVueMainEntry () { + if (!nvueMainEntry) { + nvueMainEntry = fs.existsSync(path.resolve(process.env.UNI_INPUT_DIR, 'main.js')) ? 'main.js' : '.main.js' + if (nvueMainEntry === '.main.js') { + fs.writeFileSync(path.resolve(process.env.UNI_INPUT_DIR, '.main.js'), '') + } + } + return nvueMainEntry +} + +function getPagesJson () { + return processPagesJson(getJson('pages.json', true)) +} + +function parsePagesJson (content) { + return processPagesJson(parseJson(content, true)) +} + +function filterPages (pages = [], root) { + for (let i = pages.length - 1; i >= 0; i--) { + const page = pages[i] + if (!isValidPage(page, root)) { + pages.splice(i, 1) + } + } +} + +function processPagesJson (pagesJson) { + let uniNVueEntryPagePath + if (pagesJson.pages && pagesJson.pages.length) { // 如果首页是 nvue + if (isNVuePage(pagesJson.pages[0])) { + uniNVueEntryPagePath = pagesJson.pages[0].path + } + } + // pages + filterPages(pagesJson.pages) + // subPackages + if (Array.isArray(pagesJson.subPackages) && pagesJson.subPackages.length) { + pagesJson.subPackages.forEach(subPackage => { + filterPages(subPackage.pages, subPackage.root) + }) + } + + if (Object.keys(uniNVuePages).length) { // 直接挂在 pagesJson 上 + pagesJson.nvue = { + pages: uniNVuePages + } + if (uniNVueEntryPagePath) { + pagesJson.nvue.entryPagePath = uniNVueEntryPagePath + } + } + return pagesJson +} + +function isNVuePage (page, root = '') { + if (process.env.UNI_PLATFORM === 'app-plus') { + const pagePath = path.join(root, page.path) + if (fs.existsSync(path.resolve(process.env.UNI_INPUT_DIR, pagePath + '.nvue'))) { // cache一下结果?如果文件被删除,cache 就会出现错误 + return true + } + } + return false +} + +function isValidPage (page, root = '') { + if (typeof page === 'string') { // 不合法的配置 + console.warn(`${page} 配置错误, 已被忽略, 查看文档: https://uniapp.dcloud.io/collocation/pages?id=pages`) + return false + } + let pagePath = page.path + + if (pagePath.indexOf('platforms') === 0) { // 平台相关 + if (pagePath.indexOf('platforms/' + process.env.UNI_PLATFORM) === -1) { // 非本平台 + return false + } + } + + if ( + process.env.UNI_PLATFORM === 'app-plus' && + page.style + ) { + const subNVues = page.style.subNVues || (page.style['app-plus'] && page.style['app-plus']['subNVues']) + if (Array.isArray(subNVues)) { + subNVues.forEach(subNVue => { + let subNVuePath = subNVue.path + if (subNVuePath) { + subNVuePath = subNVue.path.split('?')[0] + const subNVuePagePath = removeExt(path.join(root, subNVuePath)) + + // if (process.env.UNI_USING_NVUE_COMPILER) { + process.UNI_NVUE_ENTRY[subNVuePagePath] = getNVueMainJsPath(subNVuePagePath) + // } else { + // process.UNI_NVUE_ENTRY[subNVuePagePath] = path.resolve(process.env.UNI_INPUT_DIR, + // subNVuePagePath + + // '.nvue') + '?entry' + // } + } + }) + } + } else { + page.style && (delete page.style.subNVues) + } + + if (isNVuePage(page, root)) { + // 存储 nvue 相关信息 + pagePath = normalizePath(path.join(root, pagePath)) + + // if (process.env.UNI_USING_NVUE_COMPILER) { + process.UNI_NVUE_ENTRY[pagePath] = getNVueMainJsPath(pagePath) + // } else { + // process.UNI_NVUE_ENTRY[pagePath] = path.resolve(process.env.UNI_INPUT_DIR, pagePath + '.nvue') + '?entry' + // } + + uniNVuePages[pagePath + '.html'] = { + 'window': page.style || {} + } + return false + } + + return true +} + +function getMainJsPath (page) { + return path.resolve(process.env.UNI_INPUT_DIR, getMainEntry() + '?' + JSON.stringify({ + page: encodeURIComponent(page) + })) +} + +function getNVueMainJsPath (page) { + return path.resolve(process.env.UNI_INPUT_DIR, getNVueMainEntry() + '?' + JSON.stringify({ + page: encodeURIComponent(page) + })) +} + +process.UNI_ENTRY = {} +process.UNI_NVUE_ENTRY = {} + +let uniNVuePages = {} + +function parsePages (pagesJson, pageCallback, subPageCallback) { + if (!pagesJson) { + pagesJson = getPagesJson() + } + + // pages + pagesJson.pages.forEach(page => { + pageCallback && pageCallback(page) + }) + // subPackages + if (Array.isArray(pagesJson.subPackages) && pagesJson.subPackages.length) { + pagesJson.subPackages.forEach((subPackage) => { + const { + root, + pages + } = subPackage + pages.forEach(page => { + root && subPageCallback && subPageCallback(root, page, subPackage) + }) + }) + } +} + +function parseEntry (pagesJson) { + process.UNI_ENTRY = { + 'common/main': path.resolve(process.env.UNI_INPUT_DIR, getMainEntry()) + } + + process.UNI_SUB_PACKAGES_ROOT = {} + + process.UNI_NVUE_ENTRY = {} + + if (process.env.UNI_USING_NATIVE) { + // TODO 考虑 pages.json.js + process.UNI_NVUE_ENTRY['app-config'] = path.resolve(process.env.UNI_INPUT_DIR, 'pages.json') + process.UNI_NVUE_ENTRY['app-service'] = path.resolve(process.env.UNI_INPUT_DIR, getMainEntry()) + } + + uniNVuePages = {} + + if (!pagesJson) { + pagesJson = getPagesJson() // 会检测修改 nvue entry + } + + // pages + pagesJson.pages.forEach(page => { + process.UNI_ENTRY[page.path] = getMainJsPath(page.path) + }) + // subPackages + if (Array.isArray(pagesJson.subPackages) && pagesJson.subPackages.length) { + pagesJson.subPackages.forEach(({ + root, + pages + }) => { + Array.isArray(pages) && pages.forEach(page => { + if (root) { + const pagePath = normalizePath(path.join(root, page.path)) + process.UNI_ENTRY[pagePath] = getMainJsPath(pagePath) + process.UNI_SUB_PACKAGES_ROOT[pagePath] = root + } + }) + }) + } +} + +module.exports = { + getMainEntry, + getNVueMainEntry, + parsePages, + parseEntry, + getPagesJson, + parsePagesJson +} diff --git a/packages/uni-cli-shared/lib/platform.js b/packages/uni-cli-shared/lib/platform.js new file mode 100644 index 000000000..378da5902 --- /dev/null +++ b/packages/uni-cli-shared/lib/platform.js @@ -0,0 +1,493 @@ +const fs = require('fs') +const path = require('path') + +const { + normalizePath +} = require('./util') + +const { + SCSS, + SASS +} = require('./scss') + +const uniRuntime = '@dcloudio/vue-cli-plugin-uni/packages/mp-vue' +const mpvueRuntime = '@dcloudio/vue-cli-plugin-uni/packages/mpvue' +const megaloRuntime = '@dcloudio/vue-cli-plugin-uni/packages/megalo' + +const uniCompiler = '@dcloudio/uni-template-compiler' +const mpvueCompiler = '@dcloudio/vue-cli-plugin-uni/packages/mpvue-template-compiler' +const megaloCompiler = '@megalo/template-compiler' + +function getShadowCss () { + let tagName = 'page' + if (process.env.UNI_PLATFORM === 'h5') { + tagName = 'body' + } + return `${tagName}::after{position:fixed;content:'';left:-1000px;top:-1000px;-webkit-animation:shadow-preload .1s;-webkit-animation-delay:3s;animation:shadow-preload .1s;animation-delay:3s}@-webkit-keyframes shadow-preload{0%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}100%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}}@keyframes shadow-preload{0%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}100%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}}` +} + +function getCopyOption (file, options) { + const from = path.resolve(process.env.UNI_INPUT_DIR, file) + if (fs.existsSync(from)) { + return Object.assign({ + from, + to: path.resolve(process.env.UNI_OUTPUT_DIR, file) + }, options) + } +} + +function getCopyOptions (files, options = {}, subPackages = true) { + const copyOptions = [] + files.forEach(file => { + // 主包 + const copyOption = getCopyOption(file, options) + if (copyOption) { + copyOptions.push(copyOption) + } + if (subPackages) { + // 分包 + Object.keys(process.UNI_SUBPACKAGES).forEach(root => { // 分包静态资源 + const subCopyOption = getCopyOption(path.join(root, file), options) + if (subCopyOption) { + copyOptions.push(subCopyOption) + } + }) + } + }) + return copyOptions +} + +function getStaticCopyOptions (assetsDir) { + const ignore = [] + + Object.keys(PLATFORMS).forEach(platform => { + if (process.env.UNI_PLATFORM !== platform) { + ignore.push(platform + '/**/*') + } + }) + + return getCopyOptions( + [assetsDir], { + ignore + } + ) +} + +const PLATFORMS = { + 'h5': { + global: '', + exts: false, + vue: '@dcloudio/vue-cli-plugin-uni/packages/h5-vue', + compiler: false, + megalo: false, + subPackages: false, + cssVars: { + '--status-bar-height': '0px' + }, + copyWebpackOptions ({ + assetsDir + }) { + return [ + ...getStaticCopyOptions(assetsDir), + { + from: require.resolve('@dcloudio/uni-h5/dist/index.css'), + to: assetsDir, + transform (content) { + if (process.env.NODE_ENV === 'production') { + return content + getShadowCss() + } + return content + } + }, + ...getCopyOptions(['hybrid/html']) + ] + } + }, + 'app-plus': { + global: 'wx', + exts: { + style: '.wxss', + template: '.wxml' + }, + vue: mpvueRuntime, + compiler: mpvueCompiler, + megalo: false, + subPackages: false, + cssVars: { + '--window-top': '0px', + '--window-bottom': '0px' + }, + copyWebpackOptions ({ + assetsDir + }) { + const files = ['hybrid/html'] + if (!process.env.UNI_USING_NATIVE) { + files.push('wxcomponents') + } + return [ + ...getStaticCopyOptions(assetsDir), + ...getCopyOptions(files) + ] + } + }, + 'mp-qq': { + global: 'wx', + exts: { + style: '.qss', + template: '.qml' + }, + vue: mpvueRuntime, + compiler: mpvueCompiler, + megalo: false, + subPackages: true, + cssVars: { + '--status-bar-height': '25px', + '--window-top': '0px', + '--window-bottom': '0px' + }, + project: 'project.config.json', + copyWebpackOptions ({ + assetsDir + }) { + return [ + ...getStaticCopyOptions(assetsDir), + ...getCopyOptions(['wxcomponents']) + ] + } + }, + 'mp-weixin': { + global: 'wx', + exts: { + style: '.wxss', + template: '.wxml' + }, + vue: mpvueRuntime, + compiler: mpvueCompiler, + megalo: false, + subPackages: true, + cssVars: { + '--status-bar-height': '25px', + '--window-top': '0px', + '--window-bottom': '0px' + }, + project: 'project.config.json', + copyWebpackOptions ({ + assetsDir, + manifestPlatformOptions + }) { + const files = [ + 'sitemap.json', + 'ext.json', + 'custom-tab-bar' + ] + if (manifestPlatformOptions.workers) { + files.push(manifestPlatformOptions.workers) + } + return [ + ...getStaticCopyOptions(assetsDir), + ...getCopyOptions(['wxcomponents']), + ...getCopyOptions(files, {}, false) + ] + } + }, + 'mp-baidu': { + global: 'swan', + exts: { + style: '.css', + template: '.swan' + }, + vue: megaloRuntime, + compiler: megaloCompiler, + megalo: 'swan', + subPackages: true, + cssVars: { + '--status-bar-height': '25px', + '--window-top': '0px', + '--window-bottom': '0px' + }, + project: 'project.swan.json', + copyWebpackOptions ({ + assetsDir + }) { + return [ + ...getStaticCopyOptions(assetsDir), + ...getCopyOptions(['swancomponents']) + ] + } + }, + 'mp-alipay': { + global: 'my', + exts: { + style: '.acss', + template: '.axml' + }, + vue: megaloRuntime, + compiler: megaloCompiler, + megalo: 'alipay', + subPackages: false, + cssVars: { + '--status-bar-height': '25px', + '--window-top': '0px', + '--window-bottom': '0px' + }, + copyWebpackOptions ({ + assetsDir + }) { + return [ + ...getStaticCopyOptions(assetsDir), + ...getCopyOptions(['mycomponents']) + ] + } + }, + 'mp-toutiao': { + global: 'tt', + exts: { + style: '.ttss', + template: '.ttml' + }, + vue: megaloRuntime, + compiler: megaloCompiler, + megalo: 'tt', + subPackages: false, + cssVars: { + '--status-bar-height': '25px', + '--window-top': '0px', + '--window-bottom': '0px' + }, + project: 'project.tt.json', + copyWebpackOptions ({ + assetsDir + }) { + return [ + ...getStaticCopyOptions(assetsDir), + ...getCopyOptions(['ttcomponents']) + ] + } + } +} +// 解决 vue-cli-service lint 时 UNI_PLATFORM 不存在 +process.env.UNI_PLATFORM = process.env.UNI_PLATFORM || 'h5' + +const platform = PLATFORMS[process.env.UNI_PLATFORM] + +const preprocessContext = {} + +Object.keys(PLATFORMS).forEach(platform => { + preprocessContext[platform.toUpperCase()] = false +}) + +preprocessContext[process.env.UNI_PLATFORM.toUpperCase()] = true + +preprocessContext['MP'] = false +preprocessContext['APP'] = false +preprocessContext['APP-PLUS-NVUE'] = false +preprocessContext['APP_PLUS_NVUE'] = false + +preprocessContext['APP-VUE'] = false +preprocessContext['APP_VUE'] = false +preprocessContext['APP-NVUE'] = false +preprocessContext['APP_NVUE'] = false + +if (process.env.UNI_PLATFORM === 'app-plus') { + preprocessContext['APP-VUE'] = true + preprocessContext['APP_VUE'] = true +} + +if (process.env.UNI_PLATFORM.indexOf('mp-') === 0) { + preprocessContext['MP'] = true +} + +if (process.env.UNI_PLATFORM.indexOf('app-') === 0) { + preprocessContext['APP'] = true +} + +if (process.UNI_SCRIPT_DEFINE && Object.keys(process.UNI_SCRIPT_DEFINE).length) { + Object.keys(process.UNI_SCRIPT_DEFINE).forEach(name => { + preprocessContext[name] = process.UNI_SCRIPT_DEFINE[name] + }) +} + +Object.keys(preprocessContext).forEach(platform => { + if (platform.indexOf('-') !== -1) { + preprocessContext[platform.replace(/-/g, '_')] = preprocessContext[platform] + } +}) + +const nvuePreprocessContext = Object.assign({}, preprocessContext, { + 'APP-VUE': false, + 'APP_VUE': false, + 'APP-NVUE': true, + 'APP_NVUE': true, + 'APP-PLUS-NVUE': true, + 'APP_PLUS_NVUE': true +}) + +const isInHBuilderX = fs.existsSync(path.resolve(process.env.UNI_CLI_CONTEXT, 'bin/uniapp-cli.js')) + +let isInHBuilderXAlpha = false + +if (isInHBuilderX) { + try { + if (require(path.resolve(process.env.UNI_CLI_CONTEXT, '../about/package.json')).alpha) { + isInHBuilderXAlpha = true + } + } catch (e) { + + } +} + +let sourceRoot = false + +function devtoolModuleFilenameTemplate (info) { + if (!sourceRoot) { + if (isInHBuilderX) { + sourceRoot = normalizePath(process.env.UNI_INPUT_DIR) + } else { + sourceRoot = normalizePath(process.env.UNI_CLI_CONTEXT) + } + } + let filePath = false + const absoluteResourcePath = normalizePath(info.absoluteResourcePath) + if ( + absoluteResourcePath.indexOf(sourceRoot) !== -1 && + ( + absoluteResourcePath.endsWith('.js') || + absoluteResourcePath.endsWith('.ts') + ) + ) { + filePath = normalizePath(path.relative(sourceRoot, absoluteResourcePath)) + if ( + filePath.indexOf('node_modules/@dcloudio') === 0 || + filePath.indexOf('node_modules/vue-loader') === 0 || + filePath.indexOf('node_modules/webpack') === 0 + ) { + filePath = false + } + } else if ( + !info.moduleId && + ( + absoluteResourcePath.endsWith('.vue') || + absoluteResourcePath.endsWith('.nvue') + ) + ) { + if ( + absoluteResourcePath.indexOf('src') !== 0 && + absoluteResourcePath.indexOf('node-modules') !== 0 + ) { + filePath = normalizePath(path.relative(sourceRoot, absoluteResourcePath)) + } else { + filePath = absoluteResourcePath + } + } + if ( + filePath && + filePath !== 'main.js' && + filePath !== 'main.ts' && + filePath !== 'src/main.js' && + filePath !== 'src/main.ts' + ) { + return `uni-app:///${filePath}` + } +} +module.exports = { + isInHBuilderX, + isInHBuilderXAlpha, + runByHBuilderX: isInHBuilderX || !!process.env.UNI_HBUILDERX_PLUGINS, + devtoolModuleFilenameTemplate, + getFlexDirection (json) { + let flexDir = 'column' + if (json && json['nvue'] && json['nvue']['flex-direction']) { + flexDir = json['nvue']['flex-direction'] + const flexDirs = ['row', 'row-reverse', 'column', 'column-reverse'] + if (flexDirs.indexOf(flexDir) === -1) { + flexDir = 'column' + } + } + return flexDir + }, + jsPreprocessOptions: { + type: 'js', + context: preprocessContext + }, + cssPreprocessOptions: { + type: 'css', + context: preprocessContext + }, + htmlPreprocessOptions: { + type: 'html', + context: preprocessContext + }, + nvueCssPreprocessOptions: { + type: 'css', + context: nvuePreprocessContext + }, + nvueJsPreprocessOptions: { + type: 'js', + context: nvuePreprocessContext + }, + nvueHtmlPreprocessOptions: { + type: 'html', + context: nvuePreprocessContext + }, + isSupportSubPackages () { + return platform.subPackages + }, + getPlatforms () { + return Object.keys(PLATFORMS) + }, + getPlatformCopy () { + return platform.copyWebpackOptions + }, + getPlatformGlobal () { + return platform.global + }, + getPlatformExts () { + return platform.exts + }, + getPlatformTarget () { + return platform.megalo + }, + getPlatformProject () { + return platform.project + }, + getPlatformVue () { + if (process.env.UNI_USING_COMPONENTS) { + return uniRuntime + } + return platform.vue + }, + getPlatformCompiler () { + if (process.env.UNI_USING_COMPONENTS || process.env.UNI_PLATFORM === 'h5') { + return require(uniCompiler) + } + return require(platform.compiler) + }, + getPlatformCssVars () { + return platform.cssVars + }, + getPlatformCssnano () { + return { + calc: false, + orderedValues: false, + mergeLonghand: false, + mergeRules: false, + cssDeclarationSorter: false, + discardComments: false, + discardDuplicates: false // 条件编译会导致重复 + } + }, + getShadowCss, + getShadowTemplate (colorType = 'grey') { + let tagName = 'cover-image' + if (process.env.UNI_PLATFORM === 'mp-toutiao') { + tagName = 'image' + } + return `<${tagName} src="https://cdn.dcloud.net.cn/img/shadow-${colorType}.png" style="z-index:998;position:fixed;left:0;top:0;width:100%;height:3px;"/>` + }, + getPlatformScss () { + return SCSS + }, + getPlatformSass () { + return SASS + } +} diff --git a/packages/uni-cli-shared/lib/scss.js b/packages/uni-cli-shared/lib/scss.js new file mode 100644 index 000000000..162fa7437 --- /dev/null +++ b/packages/uni-cli-shared/lib/scss.js @@ -0,0 +1,106 @@ +const SCSS = + ` +$uni-color-primary: #007aff; +$uni-color-success: #4cd964; +$uni-color-warning: #f0ad4e; +$uni-color-error: #dd524d; + +$uni-text-color: #333;//基本色 +$uni-text-color-inverse: #fff;//反色 +$uni-text-color-grey: #999;//辅助灰色,如加载更多的提示信息 +$uni-text-color-placeholder: #808080; +$uni-text-color-disable: #c0c0c0; + +$uni-bg-color: #ffffff; +$uni-bg-color-grey: #f8f8f8; +$uni-bg-color-hover: #f1f1f1;//点击状态颜色 +$uni-bg-color-mask: rgba(0, 0, 0, 0.4);//遮罩颜色 + +$uni-border-color: #c8c7cc; + + +$uni-font-size-sm: 24rpx; +$uni-font-size-base: 28rpx; +$uni-font-size-lg: 32rpx; + +$uni-img-size-sm: 40rpx; +$uni-img-size-base: 52rpx; +$uni-img-size-lg: 80rpx; + +$uni-border-radius-sm: 4rpx; +$uni-border-radius-base: 6rpx; +$uni-border-radius-lg: 12rpx; +$uni-border-radius-circle: 50%; + +$uni-spacing-row-sm: 10px; +$uni-spacing-row-base: 20rpx; +$uni-spacing-row-lg: 30rpx; + +$uni-spacing-col-sm: 8rpx; +$uni-spacing-col-base: 16rpx; +$uni-spacing-col-lg: 24rpx; + +$uni-opacity-disabled: 0.3; // 组件禁用态的透明度 + +$uni-color-title: #2C405A; // 文章标题颜色 +$uni-font-size-title: 40rpx; +$uni-color-subtitle: #555555; // 二级标题颜色 +$uni-font-size-subtitle: 36rpx; +$uni-color-paragraph: #3F536E; // 文章段落颜色 +$uni-font-size-paragraph: 30rpx; +` +const SASS = + ` +$uni-color-primary: #007aff +$uni-color-success: #4cd964 +$uni-color-warning: #f0ad4e +$uni-color-error: #dd524d + +$uni-text-color: #333//基本色 +$uni-text-color-inverse: #fff//反色 +$uni-text-color-grey: #999//辅助灰色,如加载更多的提示信息 +$uni-text-color-placeholder: #808080 +$uni-text-color-disable: #c0c0c0 + +$uni-bg-color: #ffffff +$uni-bg-color-grey: #f8f8f8 +$uni-bg-color-hover: #f1f1f1//点击状态颜色 +$uni-bg-color-mask: rgba(0, 0, 0, 0.4)//遮罩颜色 + +$uni-border-color: #c8c7cc + + +$uni-font-size-sm: 24rpx +$uni-font-size-base: 28rpx +$uni-font-size-lg: 32rpx + +$uni-img-size-sm: 40rpx +$uni-img-size-base: 52rpx +$uni-img-size-lg: 80rpx + +$uni-border-radius-sm: 4rpx +$uni-border-radius-base: 6rpx +$uni-border-radius-lg: 12rpx +$uni-border-radius-circle: 50% + +$uni-spacing-row-sm: 10px +$uni-spacing-row-base: 20rpx +$uni-spacing-row-lg: 30rpx + +$uni-spacing-col-sm: 8rpx +$uni-spacing-col-base: 16rpx +$uni-spacing-col-lg: 24rpx + +$uni-opacity-disabled: 0.3 // 组件禁用态的透明度 + +$uni-color-title: #2C405A // 文章标题颜色 +$uni-font-size-title: 40rpx +$uni-color-subtitle: #555555 // 二级标题颜色 +$uni-font-size-subtitle: 36rpx +$uni-color-paragraph: #3F536E // 文章段落颜色 +$uni-font-size-paragraph: 30rpx +` +module.exports = { + SCSS, + SASS +} diff --git a/packages/uni-cli-shared/lib/tags.js b/packages/uni-cli-shared/lib/tags.js new file mode 100644 index 000000000..6b5c51f36 --- /dev/null +++ b/packages/uni-cli-shared/lib/tags.js @@ -0,0 +1,43 @@ +module.exports = { + 'resize-sensor': ['h5'], + 'ad': ['mp-weixin'], + 'audio': ['app-plus', 'mp-weixin', 'h5'], + 'button': ['app-plus', 'mp-weixin', 'h5'], + 'camera': ['mp-weixin'], + 'canvas': ['app-plus', 'mp-weixin'], + 'checkbox': ['app-plus', 'mp-weixin', 'h5'], + 'checkbox-group': ['app-plus', 'mp-weixin', 'h5'], + 'cover-image': ['app-plus', 'mp-weixin'], + 'cover-view': ['app-plus', 'mp-weixin'], + 'form': ['app-plus', 'mp-weixin', 'h5'], + 'functional-page-navigator': ['mp-weixin'], + 'icon': ['app-plus', 'mp-weixin'], + 'image': ['app-plus', 'mp-weixin', 'h5'], + 'input': ['app-plus', 'mp-weixin', 'h5'], + 'label': ['app-plus', 'mp-weixin', 'h5'], + 'live-player': ['mp-weixin'], + 'live-pusher': ['mp-weixin'], + 'map': ['app-plus', 'mp-weixin', 'h5'], + 'movable-area': ['app-plus', 'mp-weixin'], + 'movable-view': ['app-plus', 'mp-weixin'], + 'navigator': ['app-plus', 'mp-weixin', 'h5'], + 'official-account': ['mp-weixin'], + 'open-data': ['mp-weixin'], + 'picker': ['app-plus', 'mp-weixin', 'h5'], + 'picker-view': ['app-plus', 'mp-weixin', 'h5'], + 'picker-view-column': ['app-plus', 'mp-weixin', 'h5'], + 'progress': ['app-plus', 'mp-weixin', 'h5'], + 'radio': ['app-plus', 'mp-weixin', 'h5'], + 'radio-group': ['app-plus', 'mp-weixin', 'h5'], + 'rich-text': ['app-plus', 'mp-weixin', 'h5'], + 'scroll-view': ['app-plus', 'mp-weixin', 'h5'], + 'slider': ['app-plus', 'mp-weixin', 'h5'], + 'swiper': ['app-plus', 'mp-weixin', 'h5'], + 'swiper-item': ['app-plus', 'mp-weixin', 'h5'], + 'switch': ['app-plus', 'mp-weixin', 'h5'], + 'text': ['app-plus', 'mp-weixin', 'h5'], + 'textarea': ['app-plus', 'mp-weixin', 'h5'], + 'video': ['app-plus', 'mp-weixin', 'h5'], + 'view': ['app-plus', 'mp-weixin', 'h5'], + 'web-view': ['app-plus', 'mp-weixin'] +} diff --git a/packages/uni-cli-shared/lib/util.js b/packages/uni-cli-shared/lib/util.js new file mode 100644 index 000000000..67af52099 --- /dev/null +++ b/packages/uni-cli-shared/lib/util.js @@ -0,0 +1,119 @@ +const path = require('path') +const hash = require('hash-sum') +const crypto = require('crypto') + +const PLATFORMS = [ + 'h5', + 'app-plus', + 'mp-qq', + 'mp-weixin', + 'mp-baidu', + 'mp-alipay', + 'mp-toutiao', + 'quickapp' +] + +const isWin = /^win/.test(process.platform) + +const normalizePath = path => (isWin ? path.replace(/\\/g, '/') : path) + +function removeExt (str, ext) { + if (ext) { + const reg = new RegExp(ext.replace(/\./, '\\.') + '$') + return normalizePath(str.replace(reg, '')) + } + return normalizePath(str.replace(/\.\w+$/g, '')) +} + +function hashify (filepath) { + const relativePath = removeExt(path.relative(process.env.UNI_INPUT_DIR, filepath)) + return hash(relativePath) +} + +function md5 (str) { + const hash = crypto.createHash('md5') + hash.update(str) + return hash.digest('hex') +} + +function cached (fn) { + const cache = Object.create(null) + return function cachedFn (str) { + const hit = cache[str] + return hit || (cache[str] = fn(str)) + } +} + +const camelizeRE = /-(\w)/g + +const camelize = cached((str) => { + return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '') +}) + +const hyphenateRE = /\B([A-Z])/g + +const hyphenate = cached((str) => { + return str.replace(hyphenateRE, '-$1').toLowerCase() +}) + +const REGEX_PX = /(:|\s|\(|\/)[+-]?\d+(\.\d+)?u?px/g +const REGEX_UPX = /(:|\s|\(|\/)[+-]?\d+(\.\d+)?upx/g + +function convertStaticStyle (styleStr) { + if (typeof styleStr === 'string') { + let matches = styleStr.match(REGEX_UPX) + if (matches && matches.length) { + matches.forEach(function (match) { + styleStr = styleStr.replace(match, match.substr(0, match.length - 3) + 'rpx') + }) + } + // TODO 不应该再支持 px 转 rpx + if (process.UNI_TRANSFORM_PX) { // 需要转换 px + matches = styleStr.match(REGEX_PX) + if (matches && matches.length) { + matches.forEach(function (match) { + styleStr = styleStr.replace(match, match.substr(0, match.length - 2) + 'rpx') + }) + } + } + } + return styleStr +} + +function hasModule (name) { + try { + return !!require.resolve(name) + } catch (e) {} + return false +} + +module.exports = { + md5, + hasOwn (obj, key) { + return hasOwnProperty.call(obj, key) + }, + hasModule, + parseStyle (style = {}) { + Object.keys(style).forEach(name => { + if (PLATFORMS.includes(name)) { + if (name === process.env.UNI_PLATFORM) { + Object.assign(style, style[name] || {}) + } + delete style[name] + } + }) + return style + }, + hashify, + removeExt, + camelize, + hyphenate, + normalizePath, + convertStaticStyle, + getComponentName: cached((str) => { + if (str.indexOf('wx-') === 0) { + return str.replace('wx-', 'weixin-') + } + return str + }) +} diff --git a/packages/uni-cli-shared/package.json b/packages/uni-cli-shared/package.json new file mode 100644 index 000000000..360927451 --- /dev/null +++ b/packages/uni-cli-shared/package.json @@ -0,0 +1,18 @@ +{ + "name": "@dcloudio/uni-cli-shared", + "version": "0.2.986", + "description": "uni-cli-shared", + "main": "lib/index.js", + "files": [ + "lib" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "fxy060608", + "license": "Apache-2.0", + "dependencies": { + "hash-sum": "^1.0.2", + "strip-json-comments": "^2.0.1" + } +} diff --git a/packages/uni-template-compiler/LICENSE b/packages/uni-template-compiler/LICENSE new file mode 100755 index 000000000..7a4a3ea24 --- /dev/null +++ b/packages/uni-template-compiler/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/packages/uni-template-compiler/__tests__/compiler-extra.spec.js b/packages/uni-template-compiler/__tests__/compiler-extra.spec.js new file mode 100644 index 000000000..f204b4720 --- /dev/null +++ b/packages/uni-template-compiler/__tests__/compiler-extra.spec.js @@ -0,0 +1,619 @@ +const compiler = require('../lib') + +function assertCodegen (template, templateCode, renderCode = `with(this){}`, options = {}, mpOptions = {}) { + const res = compiler.compile(template, Object.assign({ + resourcePath: 'test.wxml', + mp: Object.assign({ + minified: true, + isTest: true, + platform: 'mp-weixin' + }, mpOptions) + }, options)) + + expect(res.template).toBe(templateCode) + expect(res.render).toBe(renderCode) +} + +describe('mp:compiler-extra', () => { + it('generate scopeId', () => { + assertCodegen( + '', + ``, + undefined, { + scopeId: 'data-v-1' + } + ) + assertCodegen( + '', + ``, + undefined, { + scopeId: 'data-v-2' + } + ) + assertCodegen( + '', + ``, + undefined, { + scopeId: 'data-v-3' + } + ) + assertCodegen( + '', + ``, + undefined, { + scopeId: 'data-v-4' + } + ) + assertCodegen( + '', + ``, + undefined, { + scopeId: 'data-v-5' + } + ) + assertCodegen( + '', + ``, + undefined, { + scopeId: 'data-v-6' + } + ) + // assertCodegen( + // '', + // ``, + // `with(this){var c0=__get_class(view,"data-v-6");$mp.data=Object.assign({},{$root:{c0:c0}})}`, { + // scopeId: 'data-v-6' + // } + // ) + assertCodegen( + '', + ``, + undefined, { + scopeId: 'data-v-7' + } + ) + // assertCodegen( + // '', + // ``, + // `with(this){var c0=__get_class(view,"view data-v-7");$mp.data=Object.assign({},{$root:{c0:c0}})}`, { + // scopeId: 'data-v-7' + // } + // ) + }) + + it('generate staticStyle upx and px', () => { + assertCodegen( + 'text', + `text` + ) + assertCodegen( + 'text', + `text` + ) + assertCodegen( + 'text', + `text` + ) + assertCodegen( + 'text', + `text`, + undefined, + undefined, { + transformPx: true + } + ) + }) + + it('generate text trim', () => { + assertCodegen( + 'text', + `text` + ) + + assertCodegen( + ' text ', + `text` + ) + + assertCodegen( + `{{line_one_cn+' '}}`, + `{{line_one_cn+' '}}` + ) + + assertCodegen( + `{{" "+line_one_cn}}`, + `{{" "+line_one_cn}}` + ) + + assertCodegen( + '\nN: {{title}}\n′', + `{{'N: '+title+"\\n′"}}` + ) + assertCodegen( + '我是第一行\n我的第二行', + `我是第一行\n我的第二行` + ) + assertCodegen( + '我是第一行\n我的第二行1{{title}}', + `{{"我是第一行\\n我的第二行1"+title}}` + ) + assertCodegen( + `我是第一行 +我的第二行2{{title}}`, + `{{"我是第一行\\n我的第二行2"+title}}` + ) + + assertCodegen( + ' text text ', + `text text` + ) + assertCodegen( + 'text {{text}} text', + `{{"text "+text+" text"}}` + ) + // assertCodegen( + // 'text {{text}} \ntext', + // `{{"text " + text + " \ntext"}}` + // ) + assertCodegen( + ' text {{text}} 文本 ', + `{{'text '+text+' 文本'}}` + ) + assertCodegen( + '{{text}} text text ', + `{{text+' text text'}}` + ) + assertCodegen( + ' {{text}} text text ', + `{{''+text+' text text'}}` + ) + assertCodegen( + '{{text}} text text {{text}}', + `{{text+" text text "+text}}` + ) + assertCodegen( + ' {{text}} text text {{text}} ', + `{{''+text+" text text "+text+''}}` + ) + }) + + it('generate default slot', () => { + assertCodegen( + 'text', + `text` + ) + assertCodegen( + 'text123213', + `text123213` + ) + assertCodegen( + 'text', + `text` + ) + }) + + it('generate input value', () => { + assertCodegen( + '', + `` + ) + }) + + it('generate v-slot', () => { + assertCodegen( + '', + `` + ) + + assertCodegen( + '默认', + `fc默认` + ) + + assertCodegen( + 'text', + `text` + ) + + assertCodegen( + 'text123213', + `text123213` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + ` + +

A paragraph for the main content.

+ +
`, + `Here might be a page titleHere's some contact infoA paragraph for the main content.` + ) + }) + + it('generate events inside v-for', () => { + // TODO vue的数字 item 是从1,小程序是从0,后续考虑抹平差异 + assertCodegen( + `1`, + `1`, + `with(this){if(!_isMounted){e0=e=>count++}}` + ) + assertCodegen( + `2`, + `2`, + `with(this){if(!_isMounted){e0=e=>count++}}` + ) + assertCodegen( + `3`, + `3` + ) + assertCodegen( + `33`, + `33` + ) + assertCodegen( + `4`, + `4` + ) + assertCodegen( + `5`, + `5` + ) + assertCodegen( + `6`, + `6` + ) + assertCodegen( + `7`, + `7` + ) + assertCodegen( + ` + , + + + `, + `,` + ) + assertCodegen( + `9`, + `9` + ) + assertCodegen( + ``, + `` + ) + assertCodegen( + ``, + `` + ) + }) + + it('generate class binding', () => { + assertCodegen( + `

1

`, + `1` + ) + assertCodegen( + '
1
', + `1` + ) + assertCodegen( + `

2

`, + `2` + ) + assertCodegen( + '

3

', + `3` + ) + assertCodegen( + `

4

`, + `4` + ) + assertCodegen( + `

5

`, + `5` + ) + assertCodegen( + `
6
`, + `6` + ) + // assertCodegen( + // `
6
`, + // `6`, + // `with(this){var c0=__get_class(computedClassObject,"container");$mp.data=Object.assign({},{$root:{c0:c0}})}` + // ) + assertCodegen( + `

7

`, + `7` + ) + assertCodegen( + `

8

`, + `8` + ) + assertCodegen( + `

9

`, + `9` + ) + }) + + it('generate style binding', () => { + assertCodegen( + `

1

`, + `1` + ) + assertCodegen( + `

1

`, + `1` + ) + assertCodegen( + `

1

`, + `1` + ) + assertCodegen( + `

2

`, + `2` + ) + assertCodegen( + `

3

`, + `3` + ) + assertCodegen( + `

4

`, + `4` + ) + assertCodegen( + `

5

`, + `5` + ) + assertCodegen( + `
6
`, + `6`, + `with(this){var s0=__get_style([baseStyles,overridingStyles]);$mp.data=Object.assign({},{$root:{s0:s0}})}` + ) + assertCodegen( + `
7
`, + `7` + ) + // assertCodegen( + // `
7
`, + // `7`, + // `with(this){var s0=__get_style(styleObject);$mp.data=Object.assign({},{$root:{s0:s0}})}` + // ) + assertCodegen( + `

8

`, + `8` + ) + assertCodegen( + `

9

`, + `9` + ) + assertCodegen( + `

10

`, + `10` + ) + }) + + it('generate events with v-on directive on custom component', () => { + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + }) + + it('generate v-model directive on custom component', () => { + assertCodegen( + '1', + `1` + ) + assertCodegen( + '2', + `2` + ) + assertCodegen( + '3', + `3` + ) + assertCodegen( + '4', + `4` + ) + assertCodegen( + '4', + `4` + ) + }) + + it('generate object property on custom component', () => { + assertCodegen( + '', + `` + ) + }) + it('generate v-text directive', () => { + assertCodegen( + '', + `{{aaa1}}` + ) + assertCodegen( + '', + `{{aaa1+1}}` + ) + assertCodegen( + ``, + `aaa2` + ) + }) + it('generate v-html directive', () => { + assertCodegen( + '', + `` + ) + }) + + it('generate v-bind directive with sync modifier', () => { + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + }) + + it('generate v-model directive with generic modifiers', () => { + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + }) + + it('generate v-for', () => { + assertCodegen( + `{{handle(item)}}`, + `{{item.m0}}`, + `with(this){var l0=__map(list,function(item,index){var m0=handle(item);return{$orig:__get_orig(item),m0:m0}});$mp.data=Object.assign({},{$root:{l0:l0}})}` + ) + assertCodegen( + `{{handle(item)}}{{item.title}}`, + `{{item.m0+item.$orig.title}}`, + `with(this){var l0=__map(list,function(item,index){var m0=handle(item);return{$orig:__get_orig(item),m0:m0}});$mp.data=Object.assign({},{$root:{l0:l0}})}` + ) + assertCodegen( + `{{handle(item1)}}{{item1.title}}`, + `{{item1.m0+item1.$orig.title}}`, + `with(this){var l1=__map(list,function(item,index){var l0=__map(list1,function(item1,index1){var m0=handle(item1);return{$orig:__get_orig(item1),m0:m0}});return{$orig:__get_orig(item),l0:l0}});$mp.data=Object.assign({},{$root:{l1:l1}})}` + ) + assertCodegen( + `title: {{ section.title|prefix }}{{ sub_titles|prefix }}`, + `{{"title: "+section.f0}}{{sub_titles.f1}}`, + `with(this){var l1=__map(sections,function(section,index){var f0=_f("prefix")(section.title);var l0=__map(section.sub_titles,function(sub_titles,_index){var f1=_f("prefix")(sub_titles);return{$orig:__get_orig(sub_titles),f1:f1}});return{$orig:__get_orig(section),f0:f0,l0:l0}});$mp.data=Object.assign({},{$root:{l1:l1}})}` + ) + + assertCodegen( + `{{aaa.item.id | test | test1}}`, + `{{$root.f0}}`, + `with(this){var f0=_f("test1")(_f("test")(aaa.item.id));$mp.data=Object.assign({},{$root:{f0:f0}})}` + ) + assertCodegen( + `{{item.item.id | test | test1}}`, + `{{item.f0}}`, + `with(this){var l0=__map(list,function(item,index){var f0=_f("test1")(_f("test")(item.item.id));return{$orig:__get_orig(item),f0:f0}});$mp.data=Object.assign({},{$root:{l0:l0}})}` + ) + assertCodegen( + `{{ item.split('').join(' ') }}`, + `{{item.g0}}`, + `with(this){var l0=__map(list,function(item,i){var g0=item.split("").join(" ");return{$orig:__get_orig(item),g0:g0}});$mp.data=Object.assign({},{$root:{l0:l0}})}` + ) + }) + + it('generate TemplateLiteral ', () => { + assertCodegen( + /* eslint-disable no-template-curly-in-string */ + '', + `` + ) + assertCodegen( + /* eslint-disable no-template-curly-in-string */ + '', + `` + ) + }) + it('generate event ', () => { + assertCodegen( + `{{item.title}}`, + `{{item.title}}` + ) + assertCodegen( + `1`, + `1` + ) + assertCodegen( + `2`, + `2` + ) + assertCodegen( + `3`, + `3` + ) + assertCodegen( + ``, + `` + ) + assertCodegen( + ``, + `` + ) + assertCodegen( + `{{item.title}}`, + `{{item.title}}` + ) + assertCodegen( + `{{item.title}}`, + `{{item.title}}` + ) + assertCodegen( + ``, + `` + ) + assertCodegen( + ``, + `` + ) + assertCodegen( + ``, + `` + ) + assertCodegen( + `{{ item }}`, + `{{item}}` + ) + }) +}) diff --git a/packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js b/packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js new file mode 100644 index 000000000..269743aea --- /dev/null +++ b/packages/uni-template-compiler/__tests__/compiler-mp-alipay.spec.js @@ -0,0 +1,144 @@ +const compiler = require('../lib') + +function assertCodegen (template, templateCode, renderCode = `with(this){}`, options = {}) { + const res = compiler.compile(template, { + resourcePath: 'test.wxml', + mp: Object.assign({ + minified: true, + isTest: true, + platform: 'mp-alipay' + }, options) + }) + + expect(res.template).toBe(templateCode) + expect(res.render).toBe(renderCode) +} + +describe('mp:compiler-mp-alipay', () => { + it('generate v-for directive', () => { + assertCodegen( + '', + `` + ) + }) + + it('generate v-else-if with v-else directive', () => { + assertCodegen( + 'helloworldbye', + `helloworldbye` + ) + }) + it('generate ref', () => { + assertCodegen( + 'text', + `text` + ) + assertCodegen( + 'text123213', + `text123213` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + }) + it('generate default slot', () => { + assertCodegen( + 'text', + `text` + ) + assertCodegen( + 'text123213', + `text123213` + ) + assertCodegen( + 'text', + `text` + ) + }) + it('generate class binding', () => { + assertCodegen( + '
1
', + `1` + ) + assertCodegen( + `

2

`, + `2` + ) + assertCodegen( + '

3

', + `3` + ) + assertCodegen( + `

4

`, + `4` + ) + assertCodegen( + `

5

`, + `5` + ) + assertCodegen( + `
6
`, + `6` + ) + // assertCodegen( + // `
6
`, + // `6`, + // `with(this){var c0=__get_class(computedClassObject,"container");$mp.data=Object.assign({},{$root:{c0:c0}})}` + // ) + assertCodegen( + `

7

`, + `7` + ) + assertCodegen( + `

8

`, + `8` + ) + assertCodegen( + `

9

`, + `9` + ) + }) + + it('generate events with v-on directive', () => { + assertCodegen( + ``, + ``, + `with(this){var a0={color:"#4cd964",size:"22",type:"spinner"};$mp.data=Object.assign({},{$root:{a0:a0}})}` + ) + + assertCodegen( + ``, + `` + ) + + assertCodegen( + `
`, + `
` + ) + + assertCodegen( + ``, + `` + ) + + assertCodegen( + ``, + `` + ) + + assertCodegen( + ``, + `` + ) + + assertCodegen( + ``, + `` + ) + }) +}) diff --git a/packages/uni-template-compiler/__tests__/compiler-mp-baidu.spec.js b/packages/uni-template-compiler/__tests__/compiler-mp-baidu.spec.js new file mode 100644 index 000000000..d3e06222c --- /dev/null +++ b/packages/uni-template-compiler/__tests__/compiler-mp-baidu.spec.js @@ -0,0 +1,110 @@ +const compiler = require('../lib') + +function assertCodegen (template, templateCode, renderCode = `with(this){}`, options = {}) { + const res = compiler.compile(template, { + resourcePath: 'test.wxml', + mp: Object.assign({ + minified: true, + isTest: true, + platform: 'mp-baidu' + }, options) + }) + + expect(res.template).toBe(templateCode) + expect(res.render).toBe(renderCode) +} + +describe('mp:compiler-mp-baidu', () => { + it('generate v-for directive', () => { + assertCodegen( + '', + `` + ) + }) + it('generate scoped slot', () => { + assertCodegen( + '', + `{{foo}}` + ) + assertCodegen( + '{{ bar.foo }}', + `{{foo}}` + ) + }) + + it('generate named scoped slot', () => { + assertCodegen( + '', + `{{foo}}` + ) + assertCodegen( + '{{ bar.foo }}', + `{{foo}}` + ) + }) + + it('generate scoped slot with multiline v-if', () => { + assertCodegen( + '', + `{{foo}}` + ) + assertCodegen( + '{{ bar.foo }}', + `{{foo}}` + ) + }) + + it('generate scoped slot', () => { + assertCodegen( + '{{ user.lastName }}', + `` + ) + assertCodegen( + '{{ user.lastName }}', + `` + ) + }) + + it('generate vue id', () => { + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + }) + + it('generate text trim', () => { + assertCodegen( + '\nN: {{title}}\n′', + `{{'N: '+title+"\\\\n′"}}` + ) + assertCodegen( + '我是第一行1\n我的第二行', + `我是第一行1\n我的第二行` + ) + assertCodegen( + '我是第一行2\n我的第二行1{{title}}', + `{{"我是第一行2\\\\n我的第二行1"+title}}` + ) + assertCodegen( + `我是第一行3 + 我的第二行2{{title}}`, + `{{"我是第一行3\\\\n 我的第二行2"+title}}` + ) + }) +}) diff --git a/packages/uni-template-compiler/__tests__/compiler-mp-qq.spec.js b/packages/uni-template-compiler/__tests__/compiler-mp-qq.spec.js new file mode 100644 index 000000000..ab22dcb02 --- /dev/null +++ b/packages/uni-template-compiler/__tests__/compiler-mp-qq.spec.js @@ -0,0 +1,37 @@ +const compiler = require('../lib') + +function assertCodegen (template, templateCode, renderCode = `with(this){}`, options = {}) { + const res = compiler.compile(template, { + resourcePath: 'test.wxml', + mp: Object.assign({ + minified: true, + isTest: true, + platform: 'mp-qq' + }, options) + }) + + expect(res.template).toBe(templateCode) + expect(res.render).toBe(renderCode) +} + +describe('mp:compiler-mp-qq', () => { + it('generate text trim', () => { + assertCodegen( + '\nN: {{title}}\n′', + `{{'N: '+title+"\\\\n′"}}` + ) + assertCodegen( + '我是第一行1\n我的第二行', + `我是第一行1\n我的第二行` + ) + assertCodegen( + '我是第一行2\n我的第二行1{{title}}', + `{{"我是第一行2\\\\n我的第二行1"+title}}` + ) + assertCodegen( + `我是第一行3 + 我的第二行2{{title}}`, + `{{"我是第一行3\\\\n 我的第二行2"+title}}` + ) + }) +}) diff --git a/packages/uni-template-compiler/__tests__/compiler-mp-toutiao.spec.js b/packages/uni-template-compiler/__tests__/compiler-mp-toutiao.spec.js new file mode 100644 index 000000000..0a22563b4 --- /dev/null +++ b/packages/uni-template-compiler/__tests__/compiler-mp-toutiao.spec.js @@ -0,0 +1,75 @@ +const compiler = require('../lib') + +function assertCodegen (template, templateCode, renderCode = `with(this){}`, options = {}) { + const res = compiler.compile(template, { + resourcePath: 'test.wxml', + mp: Object.assign({ + minified: true, + isTest: true, + platform: 'mp-toutiao' + }, options) + }) + + expect(res.template).toBe(templateCode) + expect(res.render).toBe(renderCode) +} + +describe('mp:compiler-mp-toutiao', () => { + it('generate v-for directive', () => { + assertCodegen( + '', + `` + ) + }) + + it('generate ref', () => { + assertCodegen( + '', + `` + ) + }) + + it('generate class binding', () => { + assertCodegen( + '
1
', + `1` + ) + assertCodegen( + `

2

`, + `2` + ) + assertCodegen( + '

3

', + `3` + ) + assertCodegen( + `

4

`, + `4` + ) + assertCodegen( + `

5

`, + `5` + ) + assertCodegen( + `
6
`, + `6` + ) + // assertCodegen( + // `
6
`, + // `6`, + // `with(this){var c0=__get_class(computedClassObject,"container");$mp.data=Object.assign({},{$root:{c0:c0}})}` + // ) + assertCodegen( + `

7

`, + `7` + ) + assertCodegen( + `

8

`, + `8` + ) + assertCodegen( + `

9

`, + `9` + ) + }) +}) diff --git a/packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js b/packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js new file mode 100644 index 000000000..3a2da1b2c --- /dev/null +++ b/packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js @@ -0,0 +1,90 @@ +const compiler = require('../lib') + +function assertCodegen (template, templateCode, renderCode = `with(this){}`, options = {}) { + const res = compiler.compile(template, { + resourcePath: 'test.wxml', + mp: Object.assign({ + minified: true, + isTest: true, + platform: 'mp-weixin' + }, options) + }) + + expect(res.template).toBe(templateCode) + + if (typeof renderCode === 'function') { + renderCode(res) + } else { + expect(res.render).toBe(renderCode) + } +} + +describe('mp:compiler-mp-weixin', () => { + it('generate scoped slot', () => { + assertCodegen( + '', + ``, + function (res) { + expect(res.generic[0]).toBe('test-foo-default') + } + ) + assertCodegen( + '{{ bar.foo }}', + ``, + function (res) { + expect(res.generic[0]).toBe('test-foo-default') + } + ) + }) + + it('generate named scoped slot', () => { + assertCodegen( + '', + ``, + function (res) { + expect(res.generic[0]).toBe('test-foo-foo') + } + ) + assertCodegen( + '{{ bar.foo }}', + ``, + function (res) { + expect(res.generic[0]).toBe('test-foo-foo') + } + ) + }) + + it('generate scoped slot with multiline v-if', () => { + assertCodegen( + '', + ``, + function (res) { + expect(res.generic[0]).toBe('test-foo-default') + } + ) + assertCodegen( + '{{ bar.foo }}', + ``, + function (res) { + expect(res.generic[0]).toBe('test-foo-foo') + } + ) + }) + + it('generate scoped slot', () => { + assertCodegen(// TODO vue-id + '{{ user.lastName }}', + ``, + function (res) { + expect(res.componentGenerics['scoped-slots-default']).toBe(true) + } + ) + assertCodegen( + '{{ user.lastName }}', + ``, + function (res) { + expect(res.componentGenerics['scoped-slots-header']).toBe(true) + } + ) + }) +}) diff --git a/packages/uni-template-compiler/__tests__/compiler.spec.js b/packages/uni-template-compiler/__tests__/compiler.spec.js new file mode 100644 index 000000000..2c9312311 --- /dev/null +++ b/packages/uni-template-compiler/__tests__/compiler.spec.js @@ -0,0 +1,668 @@ +const compiler = require('../lib') + +function assertCodegen (template, templateCode, renderCode = `with(this){}`) { + const res = compiler.compile(template, { + resourcePath: 'test.wxml', + mp: { + minified: true, + isTest: true, + platform: 'mp-weixin' + } + }) + + expect(res.template).toBe(templateCode) + expect(res.render).toBe(renderCode) +} + +describe('mp:compiler', () => { + // TODO + // it('generate directive', () => { + // assertCodegen( + // '', + // `with(this){return _c('view',{directives:[{name:"custom1",rawName:"v-custom1:arg1.modifier",value:(value1),expression:"value1",arg:"arg1",modifiers:{"modifier":true}},{name:"custom2",rawName:"v-custom2"}]})}` + // ) + // }) + + it('generate filters', () => { + assertCodegen( + 'text {{ d | e | f }} text', + `{{"text "+$root.f1+" text"}}`, + `with(this){var f0=_f("c")(_f("b")(a));var f1=_f("f")(_f("e")(d));$mp.data=Object.assign({},{$root:{f0:f0,f1:f1}})}` + ) + }) + + it('generate filters with no arguments', () => { + assertCodegen( + '{{ d | e() }}', + `{{$root.f0}}`, + `with(this){var f0=_f("e")(d);$mp.data=Object.assign({},{$root:{f0:f0}})}` + ) + }) + + it('generate v-for directive', () => { + assertCodegen( + '', + `` + ) + // iterator syntax + assertCodegen( + '', + `` + ) + // TODO + // assertCodegen( + // '', + // `with(this){return _c('view',_l((items),function(item,key,index){return _c('view')}),0)}` + // ) + // destructuring + // TODO + // assertCodegen( + // '', + // `` + // ) + // TODO + // assertCodegen( + // '', + // `with(this){return _c('view',_l((items),function({ a, b },key,index){return _c('view')}),0)}` + // ) + // v-for with extra element + assertCodegen( + '', + `` + ) + }) + + it('generate v-if directive', () => { + assertCodegen( + 'hello', + `hello` + ) + }) + + it('generate v-else directive', () => { + assertCodegen( + 'helloworld', + `helloworld` + ) + }) + + it('generate v-else-if directive', () => { + assertCodegen( + 'helloworld', + `helloworld` + ) + }) + + it('generate v-else-if with v-else directive', () => { + assertCodegen( + 'helloworldbye', + `helloworldbye` + ) + }) + + it('generate multi v-else-if with v-else directive', () => { + assertCodegen( + 'helloworldelseifbye', + `helloworldelseifbye` + ) + }) + + it('generate ref', () => { + assertCodegen( + '', + '' + ) + }) + + it('generate ref on v-for', () => { + assertCodegen( + '
', + `` + ) + }) + + // it('generate v-bind directive', () => { + // assertCodegen( + // '', + // `` + // ) + // }) + + // it('generate v-bind with prop directive', () => { + // assertCodegen( + // '', + // `with(this){return _c('view',_b({},'view',test,true))}` + // ) + // }) + + // it('generate v-bind directive with sync modifier', () => { + // assertCodegen( + // '', + // `with(this){return _c('view',_b({},'view',test,false,true))}` + // ) + // }) + + it('generate v-model directive', () => { + assertCodegen( + '', + `` + ) + }) + + it('generate multiline v-model directive', () => { + assertCodegen( + '', + `` + ) + }) + + it('generate multiline v-model directive on custom component', () => { + assertCodegen( + '', + `` + ) + }) + + it('generate template tag', () => { + assertCodegen( + '', + `{{hello}}` + ) + }) + + it('generate single slot', () => { + assertCodegen('', ``) + }) + + it('generate named slot', () => { + assertCodegen( + '', + `` + ) + }) + + // it('generate slot fallback content', () => { + // assertCodegen( + // 'hi', + // `with(this){return _c('view',[_t("default",[_c('view',[_v("hi")])])],2)}` + // ) + // }) + + it('generate slot target', () => { + assertCodegen( + 'hello world', + `hello world` + ) + }) + + // it('generate scoped slot', () => { + // assertCodegen( + // '', + // `with(this){return _c('foo',{scopedSlots:_u([{key:"default",fn:function(bar){return [_v(_s(bar))]}}])})}` + // ) + // assertCodegen( + // '{{ bar }}', + // `with(this){return _c('foo',{scopedSlots:_u([{key:"default",fn:function(bar){return _c('view',{},[_v(_s(bar))])}}])})}` + // ) + // }) + + // it('generate named scoped slot', () => { + // assertCodegen( + // '', + // `with(this){return _c('foo',{scopedSlots:_u([{key:"foo",fn:function(bar){return [_v(_s(bar))]}}])})}` + // ) + // assertCodegen( + // '{{ bar }}', + // `with(this){return _c('foo',{scopedSlots:_u([{key:"foo",fn:function(bar){return _c('view',{},[_v(_s(bar))])}}])})}` + // ) + // }) + + // it('generate scoped slot with multiline v-if', () => { + // assertCodegen( + // '', + // `with(this){return _c('foo',{scopedSlots:_u([{key:"default",fn:function(bar){return (\nshow\n)?[_v(_s(bar))]:undefined}}])})}` + // ) + // assertCodegen( + // '{{ bar }}', + // `with(this){return _c(\'foo\',{scopedSlots:_u([{key:"foo",fn:function(bar){return (\nshow\n)?_c(\'view\',{},[_v(_s(bar))]):_e()}}])})}` + // ) + // }) + + it('generate class binding', () => { + // static + assertCodegen( + 'hello world', + `hello world` + ) + // dynamic + assertCodegen( + 'hello world', + `hello world` + ) + // assertCodegen( + // 'hello world', + // `hello world`, + // `with(this){var c0=__get_class(class1);$mp.data=Object.assign({},{$root:{c0:c0}})}` + // ) + }) + + it('generate staticStyle', () => { + assertCodegen( + 'hello world', + `hello world` + ) + }) + + it('generate style binding', () => { + assertCodegen( + 'hello world', + `hello world` + ) + // assertCodegen( + // 'hello world', + // `hello world`, + // `with(this){var s0=__get_style(error);$mp.data=Object.assign({},{$root:{s0:s0}})}` + // ) + }) + + it('generate v-show directive', () => { + assertCodegen( + 'hello world', + `` + ) + }) + + it('generate DOM props with v-bind directive', () => { + // input + value + assertCodegen('', ``) + // non input + assertCodegen('', ``) + }) + + it('generate attrs with v-bind directive', () => { + assertCodegen('', ``) + }) + + it('generate static attrs', () => { + assertCodegen('', ``) + }) + + it('generate events with v-on directive', () => { + assertCodegen( + '', + `` + ) + }) + + it('generate events with method call', () => { + assertCodegen( + '', + `` + ) + // empty arguments + assertCodegen( + '', + `` + ) + // without semicolon + assertCodegen( + '', + `` + ) + // multiple args + assertCodegen( + '', + `` + ) + // expression in args + assertCodegen( + '', + `` + ) + // tricky symbols in args + // assertCodegen( + // ``, + // ``, + // `with(this){if(!$mp.events){$mp.events=__get_event({"e0":{on:{"input":function($event){onInput(");['());")}}}})}}` + // ) + }) + + // it('generate events with multiple statements', () => { + // // normal function + // assertCodegen( + // '', + // ``, + // `with(this){if(!$mp.events){$mp.events=__get_event({"e0":{on:{"input":function($event){onInput1();onInput2()}}}})}}` + // ) + // // function with multiple args + // assertCodegen( + // '', + // ``, + // `with(this){if(!$mp.events){$mp.events=__get_event({"e0":{on:{"input":function($event){onInput1($event,"text");onInput2("text2",$event)}}}})}}` + // ) + // }) + + // it('generate events with keycode', () => { + // assertCodegen( + // '', + // `with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13,$event.key,"Enter"))return null;return onInput($event)}}})}` + // ) + // // multiple keycodes (delete) + // assertCodegen( + // '', + // `with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"delete",[8,46],$event.key,["Backspace","Delete","Del"]))return null;return onInput($event)}}})}` + // ) + // // multiple keycodes (esc) + // assertCodegen( + // '', + // `with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"esc",27,$event.key,["Esc","Escape"]))return null;return onInput($event)}}})}` + // ) + // // multiple keycodes (space) + // assertCodegen( + // '', + // `with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"space",32,$event.key,[" ","Spacebar"]))return null;return onInput($event)}}})}` + // ) + // // multiple keycodes (chained) + // assertCodegen( + // '', + // `with(this){return _c('input',{on:{"keydown":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13,$event.key,"Enter")&&_k($event.keyCode,"delete",[8,46],$event.key,["Backspace","Delete","Del"]))return null;return onInput($event)}}})}` + // ) + // // number keycode + // assertCodegen( + // '', + // `with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&$event.keyCode!==13)return null;return onInput($event)}}})}` + // ) + // // custom keycode + // assertCodegen( + // '', + // `with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"custom",undefined,$event.key,undefined))return null;return onInput($event)}}})}` + // ) + // }) + + it('generate events with generic modifiers', () => { + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + }) + + // GitHub Issues #5146 + it('generate events with generic modifiers and keycode correct order', () => { + assertCodegen( + '', + `` + ) + + assertCodegen( + '', + `` + ) + }) + + it('generate events with mouse event modifiers', () => { + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + assertCodegen( + '', + `` + ) + }) + + it('generate events with multiple modifiers', () => { + assertCodegen( + '', + `` + ) + }) + + it('generate events with capture modifier', () => { + assertCodegen( + '', + `` + ) + }) + + it('generate events with once modifier', () => { + assertCodegen( + '', + `` + ) + }) + + it('generate events with capture and once modifier', () => { + assertCodegen( + '', + `` + ) + }) + + it('generate events with once and capture modifier', () => { + assertCodegen( + '', + `` + ) + }) + + it('generate events with inline statement', () => { + assertCodegen( + '', + ``, + `with(this){if(!_isMounted){e0=function($event){current++}}}` + ) + }) + + it('generate events with inline function expression', () => { + // normal function + assertCodegen( + '', + ``, + `with(this){if(!_isMounted){e0=function(){current++}}}` + ) + // normal named function + assertCodegen( + '', + ``, + `with(this){if(!_isMounted){e0=function fn(){current++}}}` + ) + + // arrow with no args + assertCodegen( + '', + ``, + `with(this){if(!_isMounted){e0=()=>current++}}` + ) + // arrow with parens, single arg + assertCodegen( + '', + ``, + `with(this){if(!_isMounted){e0=e=>current++}}` + ) + // arrow with parens, multi args + assertCodegen( + '', + ``, + `with(this){if(!_isMounted){e0=(a,b,c)=>current++}}` + ) + // arrow with destructuring + assertCodegen( + '', + ``, + `with(this){if(!_isMounted){e0=({a,b})=>current++}}` + ) + // arrow single arg no parens + assertCodegen( + '', + ``, + `with(this){if(!_isMounted){e0=e=>current++}}` + ) + // with modifiers + assertCodegen( + ``, + ``, + `with(this){if(!_isMounted){e0=function($event){$event.stopPropagation();return(e=>current++)($event)}}}` + ) + }) + + // #3893 + it('should not treat handler with unexpected whitespace as inline statement', () => { + assertCodegen( + '', + `` + ) + }) + + // it('generate unhandled events', () => { + // assertCodegen( + // '', + // `with(this){return _c('input',{on:{"input":function(){}}})}`, + // ast => { + // ast.events.input = undefined + // } + // ) + // }) + + // it('generate multiple event handlers', () => { + // assertCodegen( + // '', + // ``, + // `with(this){if(!$mp.events){$mp.events=__get_event({"e0":{on:{"input":[function($event){current++},function($event){$event.stopPropagation();return onInput($event)}]}}})}}` + // ) + // }) + + it('generate component', () => { + assertCodegen( + '
hi
', + `hi` + // `with(this){if(!$mp.events){$mp.events=__get_event({"e0":{on:{"notify":onNotify},component:true}})}}` + ) + }) + + // it('generate svg component with children', () => { + // assertCodegen( + // '', + // `` + // ) + // }) + + it('generate is attribute', () => { + assertCodegen( + '
', + '' + ) + // assertCodegen( + // '
', + // '' + // ) + // maybe a component and normalize type should be 1 + assertCodegen( + '
', + '' + ) + }) + + // it('generate component with inline-template', () => { + // // have "inline-template'" + // assertCodegen( + // '

hello world

', + // `with(this){return _c('my-component',{inlineTemplate:{render:function(){with(this){return _m(0)}},staticRenderFns:[function(){with(this){return _c('p',[_c('span',[_v("hello world")])])}}]}})}` + // ) + // // "have inline-template attrs, but not having exactly one child element + // assertCodegen( + // '

', + // `with(this){return _c('my-component',{inlineTemplate:{render:function(){with(this){return _c('hr')}},staticRenderFns:[]}})}` + // ) + // try { + // assertCodegen( + // '', + // '' + // ) + // } catch (e) {} + // expect('Inline-template components must have exactly one child element.').toHaveBeenWarned() + // expect(console.error.calls.count()).toBe(2) + // }) + + it('generate static trees inside v-for', () => { + // TODO vue的数字 item 是从1,小程序是从0,后续考虑抹平差异 + assertCodegen( + `

`, + `` + ) + }) + + it('generate component with v-for', () => { + // normalize type: 2 + assertCodegen( + '
', + `{{item}}` + ) + }) + + it('generate component with comment', () => { + assertCodegen( + '
', + `` + ) + }) + // #6150 + it('generate comments with special characters', () => { + assertCodegen( + '
', + `` + ) + }) + // #8041 + it('does not squash templates inside v-pre', () => { + assertCodegen( + '
', + `{{msg}}` + ) + }) + + it('not specified ast type', () => { + assertCodegen( + '', + `` + ) + }) + + it('not specified directives option', () => { + assertCodegen( + '

hello world

', + `hello world` + ) + }) + + // #9142 + it('should compile single v-for component inside template', () => { + assertCodegen( + `
`, + `` + ) + }) +}) diff --git a/packages/uni-template-compiler/lib/codeframe.js b/packages/uni-template-compiler/lib/codeframe.js new file mode 100644 index 000000000..1ae0759eb --- /dev/null +++ b/packages/uni-template-compiler/lib/codeframe.js @@ -0,0 +1,60 @@ +var range = 2 + +function generateCodeFrame ( + source, + start, + end +) { + source = source.replace(/\r\n/g, '\n') // 替换\r\n 为 \n + if (start === void 0) start = 0 + if (end === void 0) end = source.length + + var lines = source.split(/\n/) // 替换\r?\n 为 \n,不然 length 对不上,导致死循环 + var count = 0 + var res = [] + for (var i = 0; i < lines.length; i++) { + count += lines[i].length + 1 + if (count >= start) { + for (var j = i - range; j <= i + range || end > count; j++) { + if (j < 0 || j >= lines.length) { + continue + } + res.push(('' + (j + 1) + (repeat$1(' ', 3 - String(j + 1).length)) + '| ' + (lines[j]))) + var lineLength = lines[j].length + if (j === i) { + // push underline + var pad = start - (count - lineLength) + 1 + var length = end > count ? lineLength - pad : end - start + res.push(' | ' + repeat$1(' ', pad) + repeat$1('^', length)) + } else if (j > i) { + if (end > count) { + var length$1 = Math.min(end - count, lineLength) + res.push(' | ' + repeat$1('^', length$1)) + } + count += lineLength + 1 + } + } + break + } + } + return res.join('\n') +} + +function repeat$1 (str, n) { + var result = '' + if (n > 0) { + while (true) { // eslint-disable-line + if (n & 1) { + result += str + } + n >>>= 1 + if (n <= 0) { + break + } + str += str + } + } + return result +} + +module.exports = generateCodeFrame diff --git a/packages/uni-template-compiler/lib/constants.js b/packages/uni-template-compiler/lib/constants.js new file mode 100644 index 000000000..4597c3a33 --- /dev/null +++ b/packages/uni-template-compiler/lib/constants.js @@ -0,0 +1,123 @@ +const METHOD_CREATE_ELEMENT = '_c' // createElement +const METHOD_MARK_ONCE = '_o' // markOnce +const METHOD_TO_NUMBER = '_n' // toNumber +const METHOD_TO_STRING = '_s' // toString +const METHOD_RENDER_LIST = '_l' // renderList +const METHOD_RENDER_SLOT = '_t' // renderSlot +const METHOD_LOOSE_EQUAL = '_q' // looseEqual +const METHOD_LOOSE_INDEX_OF = '_i' // looseIndexOf +const METHOD_RENDER_STATIC = '_m' // renderStatic +const METHOD_RESOLVE_FILTER = '_f' // resolveFilter +const METHOD_CHECK_KEY_CODES = '_k' // checkKeyCodes +const METHOD_BIND_OBJECT_PROPS = '_b' // bindObjectProps +const METHOD_CREATE_TEXT_VNODE = '_v' // createTextVNode +const METHOD_CREATE_EMPTY_VNODE = '_e' // createEmptyVNode +const METHOD_RESOLVE_SCOPED_SLOTS = '_u' // resolveScopedSlots +const METHOD_BIND_OBJECT_LISTENERS = '_g' // bindObjectListeners +const METHOD_BIND_DYNAMIC_KEYS = '_d' // bindDynamicKeys +const METHOD_PREPEND_MODIFIER = '_p' // prependModifier + +const METHOD_SET = '$set' // $set + +const INTERNAL_SET_MODEL = '__set_model' +const INTERNAL_SET_SYNC = '__set_sync' +const INTERNAL_GET_ORIG = '__get_orig' +const INTERNAL_GET_CLASS = '__get_class' +const INTERNAL_GET_STYLE = '__get_style' +const INTERNAL_GET_EVENT = '__get_event' +const INTERNAL_GET_REFS = '__get_refs' +const INTERNAL_EVENT_PROXY = '__e' +const INTERNAL_EVENT_LINK = '__l' + +const ALLOWED_GLOBAL_OBJECT = [ + 'Math', + 'Number', + 'Date', + 'Array', + 'Object', + 'Boolean', + 'String', + 'RegExp', + 'Map', + 'Set', + 'JSON', + 'Intl', + 'console' +] + +module.exports = { + SELF_CLOSING_TAGS: ['input'], // 百度需要自闭合 + VUE_EVENT_MODIFIERS: { + capture: '!', + once: '~', + passive: '&', + custom: '^' + }, + ALLOWED_GLOBAL_OBJECT, + CLASS_REF: 'vue-ref', + CLASS_REF_IN_FOR: 'vue-ref-in-for', + VAR_MP: '$mp', + VAR_ROOT: '$root', + VAR_ORIGINAL: '$orig', + VAR_FILTER: 'F', + ATTR_DATA_EVENT_OPTS: 'data-event-opts', + ATTR_DATA_COM_TYPE: 'data-com-type', + INTERNAL_GET_ORIG, + INTERNAL_GET_CLASS, + INTERNAL_GET_STYLE, + INTERNAL_GET_EVENT, + INTERNAL_GET_REFS, + INTERNAL_EVENT_PROXY, + INTERNAL_EVENT_LINK, + INTERNAL_SET_MODEL, + INTERNAL_SET_SYNC, + METHOD_BUILT_IN: [ + METHOD_SET, + INTERNAL_SET_MODEL, + INTERNAL_SET_SYNC, + INTERNAL_GET_ORIG, + INTERNAL_GET_CLASS, + INTERNAL_GET_STYLE, + INTERNAL_GET_EVENT, + INTERNAL_GET_REFS, + INTERNAL_EVENT_PROXY, + METHOD_CREATE_ELEMENT, // createElement + METHOD_MARK_ONCE, // markOnce + METHOD_TO_NUMBER, // toNumber + METHOD_TO_STRING, // toString + METHOD_RENDER_LIST, // renderList + METHOD_RENDER_SLOT, // renderSlot + METHOD_LOOSE_EQUAL, // looseEqual + METHOD_LOOSE_INDEX_OF, // looseIndexOf + METHOD_RENDER_STATIC, // renderStatic + METHOD_RESOLVE_FILTER, // resolveFilter + METHOD_CHECK_KEY_CODES, // checkKeyCodes + METHOD_BIND_OBJECT_PROPS, // bindObjectProps + METHOD_CREATE_TEXT_VNODE, // createTextVNode + METHOD_CREATE_EMPTY_VNODE, // createEmptyVNode + METHOD_RESOLVE_SCOPED_SLOTS, // resolveScopedSlots + METHOD_BIND_OBJECT_LISTENERS, // bindObjectListeners + METHOD_BIND_DYNAMIC_KEYS, // bindDynamicKeys + METHOD_PREPEND_MODIFIER // prependModifier + ], + METHOD_CREATE_ELEMENT, + METHOD_TO_STRING, + METHOD_RENDER_LIST, + METHOD_RESOLVE_FILTER, + PREFIX_GLOBAL: 'g', + PREFIX_ATTR: 'a', + PREFIX_METHOD: 'm', + PREFIX_FILTER: 'f', + PREFIX_FOR: 'l', + PREFIX_CLASS: 'c', + PREFIX_STYLE: 's', + PREFIX_EVENT: 'e', + IDENTIFIER_FOR: '__$$for$$__', + IDENTIFIER_ATTR: '__$$attr$$__', + IDENTIFIER_METHOD: '__$$method$$__', + IDENTIFIER_FILTER: '__$$filter$$__', + IDENTIFIER_CLASS: '__$$class$$__', + IDENTIFIER_STYLE: '__$$style$$__', + IDENTIFIER_EVENT: '__$$event$$__', + IDENTIFIER_GLOBAL: '__$$global$$__' +} diff --git a/packages/uni-template-compiler/lib/data/traverse.js b/packages/uni-template-compiler/lib/data/traverse.js new file mode 100644 index 000000000..9d4472d71 --- /dev/null +++ b/packages/uni-template-compiler/lib/data/traverse.js @@ -0,0 +1,66 @@ +const t = require('@babel/types') + +const babelTraverse = require('@babel/traverse').default + +const { + METHOD_RENDER_LIST +} = require('../constants') + +function getDataPath (identifier, parent, scope) { + if ( + !(t.isCallExpression(parent)) && + // not id of a Declaration + !(t.isDeclaration(parent) && parent.id === identifier) && + // not a params of a function + !(t.isFunction(parent) && parent.params.indexOf(identifier) > -1) && + // not a key of Property + !(parent.type === 'ObjectProperty' && parent.key === identifier && !parent.computed) && + // not in an Array destructure pattern + !(parent.type === 'ArrayPattern') && + // not in an Object destructure pattern + !(parent.parent && parent.parent.type === 'ObjectPattern') && + // not already in scope + !scope.hasBinding(identifier.name) + ) { + return identifier.name + } +} + +function getDataPathByMemberExpression (node, ret) { + if (t.isMemberExpression(node.object)) { + getDataPathByMemberExpression(node.object, ret) + } else if (t.isIdentifier(node.object)) { + ret.push(node.object.name) + } + ret.push(node.property.name || node.property.value) +} + +const visitor = { + Identifier (path) { + const dataPath = getDataPath(path.node, path.parent, path.scope) + if (dataPath) { + console.log('....identifier', dataPath) + } else { + // console.log('....ignore', path.node.name) + } + }, + MemberExpression (path) { + const dataPathArray = [] + getDataPathByMemberExpression(path.node, dataPathArray) + path.skip() + }, + CallExpression (path) { + const callee = path.node.callee + if (callee.name === METHOD_RENDER_LIST) { + // for + // path.skip() + } + } +} + +module.exports = function traverse (ast, state) { + const data = Object.create(null) + babelTraverse(ast, visitor, undefined, { + data + }) +} diff --git a/packages/uni-template-compiler/lib/h5.js b/packages/uni-template-compiler/lib/h5.js new file mode 100644 index 000000000..5e8c34899 --- /dev/null +++ b/packages/uni-template-compiler/lib/h5.js @@ -0,0 +1,127 @@ +const TAGS = { + br: 'view', + hr: 'view', + + p: 'view', + h1: 'view', + h2: 'view', + h3: 'view', + h4: 'view', + h5: 'view', + h6: 'view', + abbr: 'view', + address: 'view', + b: 'view', + bdi: 'view', + bdo: 'view', + blockquote: 'view', + cite: 'view', + code: 'view', + del: 'view', + ins: 'view', + dfn: 'view', + em: 'view', + strong: 'view', + samp: 'view', + kbd: 'view', + var: 'view', + i: 'view', + mark: 'view', + pre: 'view', + q: 'view', + ruby: 'view', + rp: 'view', + rt: 'view', + s: 'view', + small: 'view', + sub: 'view', + sup: 'view', + time: 'view', + u: 'view', + wbr: 'view', + + // 表单元素 + // form: 'form', + // input: 'input', + // textarea: 'textarea', + // button: 'button', + select: 'picker', + option: 'view', + optgroup: 'view', + // label: 'label', + fieldset: 'view', + datalist: 'picker', + legend: 'view', + output: 'view', + + // 框架 + iframe: 'view', + // 图像 + img: 'image', + // canvas: 'canvas', + figure: 'view', + figcaption: 'view', + + // 音视频 + // audio: 'audio', + source: 'audio', + // video: 'video', + track: 'video', + // 链接 + a: 'navigator', + nav: 'view', + link: 'navigator', + // 列表 + ul: 'view', + ol: 'view', + li: 'view', + dl: 'view', + dt: 'view', + dd: 'view', + menu: 'view', + command: 'view', + + // 表格table + table: 'view', + caption: 'view', + th: 'view', + td: 'view', + tr: 'view', + thead: 'view', + tbody: 'view', + tfoot: 'view', + col: 'view', + colgroup: 'view', + + // 样式 节 + div: 'view', + main: 'view', + span: 'label', + header: 'view', + footer: 'view', + section: 'view', + article: 'view', + aside: 'view', + details: 'view', + dialog: 'view', + summary: 'view', + + // progress: 'progress', + meter: 'progress', // todo + head: 'view', // todo + meta: 'view', // todo + base: 'text', // todo + // 'map': 'image', // TODO不是很恰当 + area: 'navigator', // j结合map使用 + + script: 'view', + noscript: 'view', + embed: 'view', + object: 'view', + param: 'view' +} +module.exports = { + getTagName (tagName) { + return TAGS[tagName] || tagName + } +} diff --git a/packages/uni-template-compiler/lib/index.js b/packages/uni-template-compiler/lib/index.js new file mode 100644 index 000000000..07365a9c8 --- /dev/null +++ b/packages/uni-template-compiler/lib/index.js @@ -0,0 +1,171 @@ +const path = require('path') + +const parser = require('@babel/parser') + +const { + parseComponent, + compile, + compileToFunctions, + ssrCompile, + ssrCompileToFunctions +} = require('vue-template-compiler') + +const platforms = require('./platforms') +const traverseScript = require('./script/traverse') +const generateScript = require('./script/generate') +const traverseTemplate = require('./template/traverse') +const generateTemplate = require('./template/generate') + +const compilerModule = require('./module') + +const generateCodeFrame = require('./codeframe') + +module.exports = { + compile (source, options = {}) { + if (!options.mp) { // h5 + return compile(source, options) + } + + (options.modules || (options.modules = [])).push(compilerModule) + + const res = compile(source, Object.assign(options, { + optimize: false + })) + + options.mp.platform = platforms[options.mp.platform] + + options.mp.scopeId = options.scopeId + + options.mp.resourcePath = options.resourcePath + + options.mp.globalUsingComponents = options.globalUsingComponents || Object.create(null) + + // (可用的原生微信小程序组件,global+scoped) + options.mp.wxComponents = options.wxComponents || Object.create(null) + + const state = { + ast: {}, + script: '', + template: '', + errors: new Set(), + tips: new Set(), + options: options.mp + } + // console.log(`function render(){${res.render}}`) + const ast = parser.parse(`function render(){${res.render}}`) + + res.render = generateScript(traverseScript(ast, state), state) + + let template = generateTemplate(traverseTemplate(ast, state), state) + + res.specialMethods = state.options.specialMethods || new Set() + delete state.options.specialMethods + + res.files = state.files || {} + delete state.files + + // resolve scoped slots + res.generic = state.generic || [] + delete state.generic + + // define scoped slots + res.componentGenerics = state.componentGenerics || {} + delete state.componentGenerics + + state.errors.forEach(msg => { + res.errors.push({ + msg + }) + }) + + const resourcePath = options.resourcePath.replace(path.extname(options.resourcePath), '') + + state.tips.forEach(msg => { + console.log(`提示:${msg} +at ${resourcePath}.vue:1`) + }) + + /** + * TODO + * 方案0.最佳方案是在 loader 中直接 emitFile,但目前 vue template-loader 不好介入,自定义的 compiler 结果又无法顺利返回给 loader + * 方案1.通过 loader 传递 emitFile 来提交生成 wxml,需要一个 template loader 来给自定义 compier 增加 emitFile + * 方案2.缓存 wxml 内容,由 plugin 生成 assets 来提交生成 wxml + * ...暂时使用方案1 + */ + if (options.emitFile) { + if (options.updateSpecialMethods) { + options.updateSpecialMethods(resourcePath, [...res.specialMethods]) + } + + if ( + process.UNI_ENTRY[resourcePath] && + process.env.UNI_PLATFORM !== 'app-plus' && + process.env.UNI_PLATFORM !== 'h5' + ) { + // 检查是否启用 shadow + let colorType = false + const pageJsonStr = options.getJsonFile(resourcePath) + if (pageJsonStr) { + try { + const windowJson = JSON.parse(pageJsonStr) + if (process.env.UNI_PLATFORM === 'mp-alipay') { + colorType = windowJson.allowsBounceVertical === 'NO' && + windowJson.navigationBarShadow && + windowJson.navigationBarShadow.colorType + } else { + colorType = windowJson.disableScroll && + windowJson.navigationBarShadow && + windowJson.navigationBarShadow.colorType + } + } catch (e) {} + } + if (colorType) { + template = options.getShadowTemplate(colorType) + template + } + } + + options.emitFile(options.resourcePath, template) + if (res.files) { + Object.keys(res.files).forEach(name => { + options.emitFile(name, res.files[name]) + }) + } + + if (state.options.usingGlobalComponents) { + options.updateUsingGlobalComponents( + resourcePath, + state.options.usingGlobalComponents + ) + } + + if ( + res.generic && + res.generic.length && + options.updateGenericComponents + ) { + options.updateGenericComponents( + resourcePath, + res.generic + ) + } + if ( + res.componentGenerics && + Object.keys(res.componentGenerics).length && + options.updateComponentGenerics + ) { + options.updateComponentGenerics( + resourcePath, + res.componentGenerics + ) + } + } else { + res.template = template + } + return res + }, + parseComponent, + compileToFunctions, + ssrCompile, + ssrCompileToFunctions, + generateCodeFrame +} diff --git a/packages/uni-template-compiler/lib/module.js b/packages/uni-template-compiler/lib/module.js new file mode 100644 index 000000000..9dd9d44f9 --- /dev/null +++ b/packages/uni-template-compiler/lib/module.js @@ -0,0 +1,47 @@ +const onRE = /^@|^v-on:/ + +function removeAttr (el, name) { + if (el.attrsMap.hasOwnProperty(name)) { + delete el.attrsMap[name] + el.attrsList.splice(el.attrsList.findIndex(attr => attr.name === name), 1) + return true + } +} +module.exports = { + preTransformNode (el, { + warn + }) { + if (el.tag === 'slot' && !el.attrsMap['name']) { + el.attrsList.push({ + name: 'SLOT_DEFAULT', + value: true + }) + el.attrsMap['SLOT_DEFAULT'] = true + } + // 处理 attr + el.attrsList.forEach(attr => { + if ( + attr.name.indexOf('v-model') === 0 && + attr.name.indexOf('.lazy') !== -1 + ) { + const origName = attr.name + const newName = origName.replace('.lazy', '') + attr.name = newName + el.attrsMap[newName] = attr.value + delete el.attrsMap[origName] + } else if (onRE.test(attr.name) && !attr.value.trim()) { // 事件为空 + attr.value = '__HOLDER__' + el.attrsMap[attr.name] = attr.value + } + }) + // 暂不支持的指令 + const dirs = ['v-once', 'v-pre', 'v-cloak'] + dirs.forEach(dir => { + if (removeAttr(el, dir)) { + warn(`unsupported directive ${dir}`, false, true) + } + }) + + // + } +} diff --git a/packages/uni-template-compiler/lib/platforms/index.js b/packages/uni-template-compiler/lib/platforms/index.js new file mode 100644 index 000000000..15df9cab3 --- /dev/null +++ b/packages/uni-template-compiler/lib/platforms/index.js @@ -0,0 +1,26 @@ +const mpBase = require('./mp-base') +const mpWeixin = require('./mp-weixin') +const mpBaidu = require('./mp-baidu') +const mpAlipay = require('./mp-alipay') +const mpToutiao = require('./mp-toutiao') + +module.exports = { + 'app-plus': Object.assign({ + name: 'app-plus' + }, mpBase, mpWeixin), + 'mp-weixin': Object.assign({ + name: 'mp-weixin' + }, mpBase, mpWeixin), + 'mp-qq': Object.assign({ + name: 'mp-qq' + }, mpBase, mpWeixin), + 'mp-baidu': Object.assign({ + name: 'mp-baidu' + }, mpBase, mpBaidu), + 'mp-alipay': Object.assign({ + name: 'mp-alipay' + }, mpBase, mpAlipay), + 'mp-toutiao': Object.assign({ + name: 'mp-toutiao' + }, mpBase, mpToutiao) +} diff --git a/packages/uni-template-compiler/lib/platforms/mp-alipay.js b/packages/uni-template-compiler/lib/platforms/mp-alipay.js new file mode 100644 index 000000000..7ef7d8c6d --- /dev/null +++ b/packages/uni-template-compiler/lib/platforms/mp-alipay.js @@ -0,0 +1,82 @@ +const t = require('@babel/types') + +const { + capitalize +} = require('../util') + +const EVENTS = { + 'click': 'tap', + 'touchstart': 'touchStart', + 'touchmove': 'touchMove', + 'touchend': 'touchEnd', + 'touchcancel': 'touchCancel', + 'longtap': 'longTap', + 'longpress': 'longTap', + 'transitionend': 'transitionEnd', + 'animationstart': 'animationStart', + 'animationiteration': 'animationIteration', + 'animationend': 'animationEnd', + 'firstappear': 'firstAppear', + // map + 'markertap': 'markerTap', + 'callouttap': 'calloutTap', + 'controltap': 'controlTap', + 'regionchange': 'regionChange', + // scroll-view + 'scrolltoupper': 'scrollToUpper', + 'scrolltolower': 'scrollToLower', + // movable-view + 'changeend': 'changeEnd' +} + +module.exports = { + prefix: 'a:', + specialEvents: { + 'form': { + 'reset': 'onReset' + }, + 'map': { + 'markertap': 'onMarkerTap', + 'controltap': 'onControlTap', + 'callouttap': 'onCalloutTap', + 'regionchange': 'onRegionChange' + } + }, + getEventType (eventType) { + return EVENTS[eventType] || eventType + }, + formatEventType: function (eventName, isCatch) { + return `${isCatch ? 'catch' : 'on'}${capitalize(eventName)}` + }, + createScopedSlots (slotName, props, state) { + const node = { + type: 'slot', + attr: { + name: slotName + }, + children: [] + } + Object.keys(props).forEach(name => { + node.attr[name] = props[name] + }) + return node + }, + resolveScopedSlots (slotName, { + paramExprNode, + returnExprNodes, + traverseExpr, + normalizeChildren + }, state) { + const node = { + type: 'view', + attr: { + slot: slotName + }, + children: normalizeChildren(traverseExpr(returnExprNodes, state)) + } + if (t.isIdentifier(paramExprNode)) { + node.scoped = paramExprNode.name + } + return node + } +} diff --git a/packages/uni-template-compiler/lib/platforms/mp-baidu.js b/packages/uni-template-compiler/lib/platforms/mp-baidu.js new file mode 100644 index 000000000..07079e619 --- /dev/null +++ b/packages/uni-template-compiler/lib/platforms/mp-baidu.js @@ -0,0 +1,36 @@ +const t = require('@babel/types') + +module.exports = { + prefix: 's-', + createScopedSlots (slotName, props, state) { + const node = { + type: 'slot', + attr: { + name: slotName + }, + children: [] + } + Object.keys(props).forEach(name => { + node.attr['var-' + name] = props[name].replace('{{', '').replace('}}', '') + }) + return node + }, + resolveScopedSlots (slotName, { + paramExprNode, + returnExprNodes, + traverseExpr, + normalizeChildren + }, state) { + const node = { + type: 'view', + attr: { + slot: slotName + }, + children: normalizeChildren(traverseExpr(returnExprNodes, state)) + } + if (t.isIdentifier(paramExprNode)) { + node.scoped = paramExprNode.name + } + return node + } +} diff --git a/packages/uni-template-compiler/lib/platforms/mp-base.js b/packages/uni-template-compiler/lib/platforms/mp-base.js new file mode 100644 index 000000000..a17835913 --- /dev/null +++ b/packages/uni-template-compiler/lib/platforms/mp-base.js @@ -0,0 +1,104 @@ +const EVENTS = { + click: 'tap' +} +const tags = [ + 'slot', + 'block', + 'component', + 'template', + + 'ad', + 'audio', + 'button', + 'camera', + 'canvas', + 'checkbox', + 'checkbox-group', + 'cover-image', + 'cover-view', + 'form', + 'functional-page-navigator', + 'icon', + 'image', + 'input', + 'label', + 'live-player', + 'live-pusher', + 'map', + 'movable-area', + 'movable-view', + 'navigator', + 'official-account', + 'open-data', + 'picker', + 'picker-view', + 'picker-view-column', + 'progress', + 'radio', + 'radio-group', + 'rich-text', + 'scroll-view', + 'slider', + 'swiper', + 'swiper-item', + 'switch', + 'text', + 'textarea', + 'video', + 'view', + 'web-view', + 'editor' +] + +module.exports = { + ref: 'data-ref', + refInFor: 'data-ref-in-for', + specialEvents: {}, + /** + * TODO 暂时先简单判断是不是自定义组件, + * 如果要依赖真实导入的组件识别,需要 template-loader 与 script-loader 结合, + * 目前 template 在前,script 在后,要做的话,就需要把 wxml 的生成机制放到 plugin 中才可以拿到真实的组件列表 + */ + isComponent (tagName) { + return !tags.includes(tagName) + }, + getEventType (eventType) { + return EVENTS[eventType] || eventType + }, + formatEventType (eventName, isCatch, isCapture, isCustom) { + let eventType = 'bind' + if (isCatch) { + eventType = 'catch' + } + if (isCapture) { + return `capture-${eventType}:${eventName}` + } + if (isCustom) { + return `${eventType}:${eventName}` + } + return `${eventType}${eventName}` // 原生组件不支持 bind:input 等写法,统一使用 bindinput + }, + createScopedSlots (slotName, props, state) { + state.errors.add('暂不支持 scoped slot [' + slotName + ']') + return { + type: 'slot', + attr: { + name: slotName + }, + children: [] + } + }, + resolveScopedSlots (slotName, componentName, paramExprNode, returnExprNodes, { + traverseExpr, + normalizeChildren + }, state) { + state.errors.add('暂不支持 scoped slot [' + slotName + ']') + return { + type: 'view', + attr: { + slot: slotName + }, + children: [] + } + } +} diff --git a/packages/uni-template-compiler/lib/platforms/mp-toutiao.js b/packages/uni-template-compiler/lib/platforms/mp-toutiao.js new file mode 100644 index 000000000..2f954b5fc --- /dev/null +++ b/packages/uni-template-compiler/lib/platforms/mp-toutiao.js @@ -0,0 +1,5 @@ +const mpWeixin = require('./mp-weixin') +module.exports = Object.assign({}, mpWeixin, { + prefix: 'tt:' + // ref: 'vue-ref' +}) diff --git a/packages/uni-template-compiler/lib/platforms/mp-weixin.js b/packages/uni-template-compiler/lib/platforms/mp-weixin.js new file mode 100644 index 000000000..fe2489eae --- /dev/null +++ b/packages/uni-template-compiler/lib/platforms/mp-weixin.js @@ -0,0 +1,106 @@ +const path = require('path') + +const t = require('@babel/types') + +function generateJsCode (properties = '{}') { + return ` +wx.createComponent({ + generic:true, + props: ${properties}, + render: function(){} +}) +` +} + +module.exports = { + prefix: 'wx:', + createScopedSlots (slotName, props, state) { + const componentName = 'scoped-slots-' + slotName + if (!state.componentGenerics) { + state.componentGenerics = Object.create(null) + } + + state.componentGenerics[componentName] = true + + return { + type: componentName, + attr: props || {}, + children: [] + } + }, + resolveScopedSlots (slotName, { + genCode, + generate, + ownerName, + parentName, + parentNode, + resourcePath, + paramExprNode, + returnExprNodes, + traverseExpr + }, state) { + if (!state.scopedSlots) { + state.scopedSlots = {} + } + let componentName = `${ownerName}-${parentName}-${slotName}` + if (!state.scopedSlots.hasOwnProperty(componentName)) { + state.scopedSlots[componentName] = 0 + } + if (state.scopedSlots[componentName]) { + componentName = componentName + state.scopedSlots[componentName] + } + state.scopedSlots[componentName]++ + parentNode.attr['generic:scoped-slots-' + slotName] = componentName + if (!parentNode.attr.generic) { + parentNode.attr.generic = {} + } + parentNode.attr.generic[slotName] = true + + // 生成 scopedSlots 文件,包括 json,js,wxml,还需要更新 owner 的 usingComponents + if (!state.files) { + state.files = {} + } + const extname = path.extname(resourcePath) + + // TODO 需要存储 resourcePath 相关 json + + const templateFile = resourcePath.replace(ownerName + extname, componentName + extname) + const templateContent = generate(traverseExpr(returnExprNodes, state), state) + + state.files[templateFile] = templateContent + + const jsFile = resourcePath.replace(ownerName + extname, componentName + '.js') + + const objectProperties = [] + + if (t.isObjectPattern(paramExprNode)) { + paramExprNode.properties.forEach(property => { + const key = property.key + const value = property.value + const valueObjectProperties = [ + t.objectProperty(t.identifier('type'), t.nullLiteral()) + ] + if (t.isIdentifier(value)) { + if (value.name !== key.name) { + state.errors.add(`解构插槽 Prop 时,不支持将${key.name}重命名为${value.name},重命名后会影响性能`) + } + } else if (t.isAssignmentPattern(value)) { + valueObjectProperties.push(t.objectProperty(t.identifier('default'), value.right)) + } + objectProperties.push(t.objectProperty(key, t.objectExpression(valueObjectProperties))) + }) + } else { + state.errors.add(`目前仅支持解构插槽 ${paramExprNode.name},如 v-slot="{ user }"`) + } + const jsContent = generateJsCode(genCode(t.objectExpression(objectProperties), true)) + state.files[jsFile] = jsContent + + if (!state.generic) { + state.generic = [] + } + // 存储,方便后续生成 json + state.generic.push(componentName) + + return '' + } +} diff --git a/packages/uni-template-compiler/lib/script/generate.js b/packages/uni-template-compiler/lib/script/generate.js new file mode 100644 index 000000000..06fd41214 --- /dev/null +++ b/packages/uni-template-compiler/lib/script/generate.js @@ -0,0 +1,5 @@ +const babelGenerate = require('@babel/generator').default + +module.exports = function generate (ast, state) { + return babelGenerate(ast, state.options).code +} diff --git a/packages/uni-template-compiler/lib/script/traverse/data/attrs.js b/packages/uni-template-compiler/lib/script/traverse/data/attrs.js new file mode 100644 index 000000000..f993cd5cd --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/data/attrs.js @@ -0,0 +1,18 @@ +const { + IDENTIFIER_ATTR +} = require('../../../constants') + +const getMemberExpr = require('../member-expr') + +module.exports = function processAttrs (paths, path, state, isComponent, tagName) { + const attrsPath = paths['attrs'] + if (attrsPath) { + attrsPath.get('value.properties').forEach(propertyPath => { + const valuePath = propertyPath.get('value') + if (valuePath.isObjectExpression()) { + valuePath.replaceWith(getMemberExpr(null, IDENTIFIER_ATTR, valuePath.node, state)) + } + }) + } + return [] +} diff --git a/packages/uni-template-compiler/lib/script/traverse/data/class.js b/packages/uni-template-compiler/lib/script/traverse/data/class.js new file mode 100644 index 000000000..32f97b5f7 --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/data/class.js @@ -0,0 +1,135 @@ +const t = require('@babel/types') + +const { + getCode +} = require('../../../util') + +function processClassArrayExpressionElements (classArrayExpression) { + let binaryExpression + + classArrayExpression.elements.forEach(expr => { + if (!binaryExpression) { + binaryExpression = t.parenthesizedExpression(expr) + } else { + binaryExpression = t.parenthesizedExpression(t.binaryExpression( + '+', + t.binaryExpression( + '+', + binaryExpression, + t.stringLiteral(' ') + ), + expr + )) + } + }) + + return binaryExpression +} + +function processStaticClass (classArrayExpression, staticClassPath, state) { + if (staticClassPath) { + classArrayExpression.elements.unshift( + t.stringLiteral(staticClassPath.node.value.value) + ) + staticClassPath.remove() + } + if ( + state.options.platform.name === 'mp-toutiao' || + state.options.platform.name === 'mp-alipay' + ) { + // classArrayExpression => binaryExpression + return processClassArrayExpressionElements(classArrayExpression) + } + return classArrayExpression +} + +function processClassObjectExpression (classValuePath) { + const elements = [] + const propertyPaths = classValuePath.get('properties') + propertyPaths.forEach(propertyPath => { + const key = propertyPath.node.key + elements.push( + t.conditionalExpression( + t.parenthesizedExpression(propertyPath.node.value), + t.stringLiteral(key.name || key.value), + t.stringLiteral('') + ) + ) + }) + return t.arrayExpression(elements) +} + +function processClassArrayExpression (classValuePath) { + const elementPaths = classValuePath.get('elements') + elementPaths.forEach(elementPath => { + if (elementPath.isObjectExpression()) { + elementPath.replaceWith(processClassObjectExpression(elementPath)) + } + }) + return classValuePath.node +} + +module.exports = function processClass (paths, path, state) { + const classPath = paths['class'] + const staticClassPath = paths['staticClass'] + if (classPath) { + const classValuePath = classPath.get('value') + if (classValuePath.isObjectExpression()) { // object + classValuePath.replaceWith( + processStaticClass( + processClassObjectExpression(classValuePath), + staticClassPath, + state + ) + ) + } else if (classValuePath.isArrayExpression()) { // array + classValuePath.replaceWith( + processStaticClass( + processClassArrayExpression(classValuePath), + staticClassPath, + state + ) + ) + } else if ( + classValuePath.isStringLiteral() || // :class="'a'" + classValuePath.isIdentifier() || // TODO 需要优化到下一个条件,:class="classObject" + classValuePath.isMemberExpression() || // 需要优化到下一个条件,:class="item.classObject" + classValuePath.isConditionalExpression() || + classValuePath.isLogicalExpression() || + classValuePath.isBinaryExpression() + ) { + // 理论上 ConditionalExpression,LogicalExpression 可能存在 classObject,应该__get_class,还是先不考虑这种情况吧 + // ConditionalExpression :class="index === currentIndex ? activeStyle : itemStyle" + // BinaryExpression :class="'m-content-head-'+message.user" + classValuePath.replaceWith( + processStaticClass( + t.arrayExpression([classValuePath.node]), + staticClassPath, + state + ) + ) + } else if ( + classValuePath.isIdentifier() || + classValuePath.isMemberExpression() + ) { // classObject :class="classObject" :class="vm.classObject" + // TODO 目前先不考虑 classObject,styleObject + + // const args = [classPath.node.value] + // if (staticClassPath) { + // args.push(staticClassPath.node.value) + // staticClassPath.remove() + // } + // classValuePath.replaceWith( + // getMemberExpr( + // classPath, + // IDENTIFIER_CLASS, + // t.callExpression(t.identifier(INTERNAL_GET_CLASS), args), + // state + // ) + // ) + } else { + state.errors.add(`:class 不支持 ${getCode(classValuePath.node)} 语法`) + } + } + return [] +} diff --git a/packages/uni-template-compiler/lib/script/traverse/data/directives.js b/packages/uni-template-compiler/lib/script/traverse/data/directives.js new file mode 100644 index 000000000..73c5f6f98 --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/data/directives.js @@ -0,0 +1,71 @@ +const t = require('@babel/types') + +const { + getModelEventFunctionExpr +} = require('./util') + +module.exports = function processDir (paths, path, state) { + const directivesPath = paths['directives'] + if (directivesPath) { + /** + * directives: [{ + * name: "model", + * rawName: "v-model", + * value: (aaa.cart_amount), + * expression: "aaa.cart_amount" + *}], + */ + const modelObjectExpr = directivesPath.node.value.elements.find( + objectExpression => { + return objectExpression.properties.find(property => { + return property.key.name === 'name' && property.value.value === 'model' + }) + } + ) + if (modelObjectExpr) { + const exprProperty = modelObjectExpr.properties.find(property => { + return property.key.name === 'expression' + }) + const modifiersProperty = modelObjectExpr.properties.find(property => { + return property.key.name === 'modifiers' + }) + if (exprProperty) { + const onPath = paths['on'] + + const existingInput = onPath.node.value.properties.find( + property => property.key.value === 'input' + ) + if (existingInput) { + let existingInputFuncExpr + // remove old model input event + if (!t.isArrayExpression(existingInput.value)) { + existingInputFuncExpr = existingInput.value + existingInput.value = t.arrayExpression([]) + } else { + existingInputFuncExpr = existingInput.value.elements.shift() + } + if (existingInputFuncExpr) { + const modifiers = [] + if (modifiersProperty) { + const properties = modifiersProperty.value.properties + if (properties.find(property => property.key.value === 'number')) { + modifiers.push(t.stringLiteral('number')) + } + if (properties.find(property => property.key.value === 'trim')) { + modifiers.push(t.stringLiteral('trim')) + } + } + existingInput.value.elements.unshift( + getModelEventFunctionExpr( + existingInputFuncExpr, + exprProperty.value.value.trim(), + modifiers + ) + ) + } + } + } + } + } + return [] +} diff --git a/packages/uni-template-compiler/lib/script/traverse/data/event.js b/packages/uni-template-compiler/lib/script/traverse/data/event.js new file mode 100644 index 000000000..4500b3023 --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/data/event.js @@ -0,0 +1,408 @@ +const t = require('@babel/types') + +const { + IDENTIFIER_EVENT, + VUE_EVENT_MODIFIERS, + INTERNAL_EVENT_PROXY, + ATTR_DATA_EVENT_OPTS, + INTERNAL_SET_SYNC +} = require('../../../constants') + +const { + getCode, + customize, + processMemberExpression +} = require('../../../util') + +const { + getEventExpressionStatement +} = require('../statements') + +const defaultArgs = t.arrayExpression([t.stringLiteral('$event')]) + +function addEventExpressionStatement (funcPath, state, isCustom) { + const identifier = t.identifier(IDENTIFIER_EVENT) + const stringLiteral = t.stringLiteral(IDENTIFIER_EVENT) + state.identifierArray.push([identifier, stringLiteral]) + state.initExpressionStatementArray.push(getEventExpressionStatement(identifier, funcPath.node)) + + const arrayExpression = [ + stringLiteral + ] + + const args = [] + if (!isCustom) { // native events + args.push(t.stringLiteral('$event')) + arrayExpression.push(t.arrayExpression(args)) + } else { // custom events + + } + // if (state.scoped) { // add forItem,forIndex + // const scopedArgs = [] + // state.scoped.forEach(scoped => { + // if (scoped.forIndex && scoped.forIndex !== scoped.forItem) { + // scopedArgs.push(t.identifier(scoped.forIndex)) + // } + // scopedArgs.push(t.identifier(scoped.forItem)) + // }) + // scopedArgs.reverse().forEach(arg => { + // args.push(arg) + // }) + // } + return t.arrayExpression(arrayExpression) +} + +function getIdentifierName (element) { + if (t.isMemberExpression(element)) { + return getIdentifierName(element.object) + } + return element.name.split('.')[0] +} + +function getScoped (scopedArray, element, methodName, state) { + const identifierName = getIdentifierName(element) + const scoped = scopedArray.find(scoped => { + if (scoped.forItem === identifierName) { + return true + } + }) + if (scoped) { + const forExtra = t.cloneDeep(t.arrayExpression(scoped.forExtra)) + if (t.isMemberExpression(element)) { + // 简单处理 + // item['order']=>item.order + element = processMemberExpression(element, state) + // v-for="item in data.items" :key="item.data.id" + // v-for="meta in item.metas" :key="meta.id" @tap="change(meta,meta.b,true)" + // ['data.items','data.id',item.data.id] + // ['metas','id',meta.id]=>['metas','id',meta.id,'b'] + forExtra.elements[forExtra.elements.length - 1].elements.push( + t.stringLiteral( + getExtraDataPath( + getCode(element).replace(scoped.forItem + '.', ''), methodName + ) + ) + ) + } + return forExtra + } +} + +function isForIndex (scopedArray, element) { + if (t.isIdentifier(element)) { + return scopedArray.find(scoped => { + if (scoped.forIndex === element.name) { + return true + } + }) + } + return false +} + +function getExtraDataPath (dataPath, methodName) { + if (methodName === INTERNAL_SET_SYNC) { + const dataPaths = dataPath.split('.') + dataPaths.pop() + return dataPaths.join('.') + } + return dataPath +} + +function parseMethod (method, state) { + const elements = method.elements + const methodName = elements[0].value + const argsArrayExpr = elements[1] + if (argsArrayExpr) { + const extraArrayElements = [] + argsArrayExpr.elements = argsArrayExpr.elements.map((element) => { + if (t.isIdentifier(element) || t.isMemberExpression(element)) { // item or item.b + if (state.scoped.length) { + const forExtra = getScoped(state.scoped, element, methodName, state) + if (!forExtra) { + if (isForIndex(state.scoped, element)) { + return element + } else { + extraArrayElements.push(t.stringLiteral( + getExtraDataPath(getCode(processMemberExpression(element, state)), + methodName) + )) + } + } else { + extraArrayElements.push(forExtra) + } + } else { + extraArrayElements.push(t.stringLiteral( + getExtraDataPath(getCode(processMemberExpression(element, state)), methodName) + )) + } + return t.stringLiteral('$' + (extraArrayElements.length - 1)) + } else if ( // +1=>1 + t.isUnaryExpression(element) && + element.operator === '+' && + t.isNumericLiteral(element.argument) + ) { + element = t.numericLiteral(element.argument.value) + } else if (t.isObjectExpression(element)) { + // {name:'a',b:'c',d:123}=>[['name','a'],['b','c'],['d',123]] + const objectExprElements = [ + t.stringLiteral('o') + ] + element.properties.forEach(property => { + objectExprElements.push(t.arrayExpression([ + t.stringLiteral(property.key.name || property.key.value), + t.cloneDeep(property.value) + ])) + }) + element = t.arrayExpression(objectExprElements) + } + return element + }) + if (extraArrayElements.length) { + elements.push(t.arrayExpression(extraArrayElements)) + } + } +} + +function getMethodName (methodName) { + return methodName === '__HOLDER__' ? '' : methodName +} + +function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false, tagName, ret) { + const key = keyPath.node + let type = key.value || key.name + + const isCustom = isComponent && !isNativeOn + + let isCatch = false + let isCapture = false + let isPassive = false + let isOnce = false + + isPassive = type.charAt(0) === VUE_EVENT_MODIFIERS.passive + type = isPassive ? type.slice(1) : type + + isOnce = type.charAt(0) === VUE_EVENT_MODIFIERS.once // Prefixed last, checked first + type = isOnce ? type.slice(1) : type + + isCapture = type.charAt(0) === VUE_EVENT_MODIFIERS.capture + type = isCapture ? type.slice(1) : type + + const specialEvents = state.options.platform.specialEvents + const isSpecialEvent = specialEvents[tagName] && Object.keys(specialEvents[tagName]).includes(type) + + let methods = [] + + if (!valuePath.isArrayExpression()) { + valuePath = [valuePath] + } else { + valuePath = valuePath.get('elements') + } + + valuePath.forEach(funcPath => { + if (funcPath.isIdentifier()) { // on:{click:handle} + if (!isSpecialEvent) { + const arrayExpression = [t.stringLiteral(getMethodName(funcPath.node.name))] + if (!isCustom) { // native events + arrayExpression.push(defaultArgs) + } + methods.push(t.arrayExpression(arrayExpression)) + } else { + if (!state.options.specialMethods) { + state.options.specialMethods = new Set() + } + state.options.specialMethods.add(funcPath.node.name) + } + } else if (isSpecialEvent) { + state.errors.add( + `${tagName} 组件 ${type} 事件仅支持 @${type}="methodName" 方式绑定` + ) + } else if (funcPath.isArrowFunctionExpression()) { // e=>count++ + methods.push(addEventExpressionStatement(funcPath, state, isCustom)) + } else { + let anonymous = true + funcPath.traverse({ + noScope: true, + MemberExpression (path) { + if (path.node.object.name === '$event' && path.node.property.name === + 'stopPropagation') { + isCatch = true + path.stop() + } + }, + AssignmentExpression (path) { // "update:title": function($event) {title = $event} + const left = path.node.left + const right = path.node.right + // v-bind:title.sync="title" + if (t.isIdentifier(left) && + t.isIdentifier(right) && + right.name === '$event' && + type.indexOf('update:') === 0) { + methods.push(t.arrayExpression( // ['$set',['title','$event']] + [ + t.stringLiteral(INTERNAL_SET_SYNC), + t.arrayExpression([ + t.identifier(left.name), + t.stringLiteral(left.name), + t.stringLiteral('$event') + ]) + ] + )) + anonymous = false + path.stop() + } + }, + ReturnStatement (path) { + const argument = path.node.argument + if (t.isCallExpression(argument)) { + if (t.isIdentifier(argument.callee)) { + anonymous = false + let methodName = argument.callee.name + if (methodName === '$set') { + methodName = INTERNAL_SET_SYNC + } + const arrayExpression = [t.stringLiteral(getMethodName(methodName))] + const args = argument.arguments + if (methodName === INTERNAL_SET_SYNC) { + // v-bind:title.sync="doc.title" + // ['$set',['doc.a','title','$event']] + const argsExpression = [] + argsExpression.push( + t.memberExpression(args[0], t.identifier(args[1].value)) + ) + argsExpression.push(t.stringLiteral(args[1].value)) + argsExpression.push(t.stringLiteral('$event')) + arrayExpression.push(t.arrayExpression(argsExpression)) + } else { + if (args.length) { + const argsExpression = [] + args.forEach(arg => { + if (t.isIdentifier(arg) && arg.name === '$event') { + argsExpression.push(t.stringLiteral('$event')) + } else { + argsExpression.push(arg) + } + }) + arrayExpression.push(t.arrayExpression(argsExpression)) + } + } + methods.push(t.arrayExpression(arrayExpression)) + } + } + } + }) + if (anonymous) { + methods.push(addEventExpressionStatement(funcPath, state, isComponent, isNativeOn)) + } + } + }) + + return { + type, + methods, + modifiers: { + isCatch, + isCapture, + isPassive, + isOnce, + isCustom + } + } +} + +function _processEvent (path, state, isComponent, isNativeOn = false, tagName, ret) { + const opts = [] + const len = path.node.value.properties.length + for (let i = 0; i < len; i++) { + const propertyPath = path.get(`value.properties.${i}`) + const keyPath = propertyPath.get('key') + const valuePath = propertyPath.get('value') + const { + type, + methods, + modifiers: { + isCatch, + isCapture, + isOnce, + isCustom + } + } = parseEvent( + keyPath, + valuePath, + state, + isComponent, + isNativeOn, + tagName, + ret + ) + + if (!methods.length) { + continue + } + + methods.forEach(method => { + parseMethod(method, state) // 解析参数 + }) + + const getEventType = state.options.platform.getEventType + + let optType = isCustom ? customize(type) : getEventType(type) // 比如自定义组件使用了 click 自定义事件 + + if (isOnce) { + optType = VUE_EVENT_MODIFIERS.once + optType + } + if (isCustom) { + optType = VUE_EVENT_MODIFIERS.custom + optType + } + opts.push( + t.arrayExpression([ + t.stringLiteral(optType), + t.arrayExpression(methods) + ]) + ) + + keyPath.replaceWith( + t.stringLiteral( + state.options.platform.formatEventType( + isCustom ? customize(type) : getEventType(type), // 比如自定义组件使用了 click 自定义事件 + isCatch, + isCapture, + isCustom + ) + ) + ) + + valuePath.replaceWith(t.stringLiteral(INTERNAL_EVENT_PROXY)) + } + return opts +} +module.exports = function processEvent (paths, path, state, isComponent, tagName) { + const onPath = paths['on'] + const nativeOnPath = paths['nativeOn'] + + const ret = [] + + const opts = [] + + if (onPath) { + _processEvent(onPath, state, isComponent, false, tagName, ret).forEach(opt => { + opts.push(opt) + }) + } + if (nativeOnPath) { + _processEvent(nativeOnPath, state, isComponent, true, tagName, ret).forEach(opt => { + opts.push(opt) + }) + } + if (!opts.length) { + return ret + } + + ret.push( + t.objectProperty( + t.stringLiteral(ATTR_DATA_EVENT_OPTS), + t.arrayExpression(opts) + ) + ) + + return ret +} diff --git a/packages/uni-template-compiler/lib/script/traverse/data/index.js b/packages/uni-template-compiler/lib/script/traverse/data/index.js new file mode 100644 index 000000000..c4d34c28c --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/data/index.js @@ -0,0 +1,59 @@ +const t = require('@babel/types') + +const { + ATTR_DATA_COM_TYPE +} = require('../../../constants') + +const processRef = require('./ref') +const processAttrs = require('./attrs') +const processClass = require('./class') +const processEvent = require('./event') +const processStyle = require('./style') +const processModel = require('./model') +const processDir = require('./directives') + +module.exports = function traverseData (path, state, tagName) { + if (path.node.$mpProcessed) { + return + } + path.node.$mpProcessed = true + + const paths = {} + + const propertyPaths = path.get('properties') + + propertyPaths.forEach((propertyPath, index) => { + paths[propertyPath.node.key.name] = propertyPath + }) + + const addAttrProperties = [] + const isComponent = state.options.platform.isComponent(tagName) + const processes = [processAttrs, processRef, processClass, processModel, processDir, processEvent, processStyle] + // ref(add staticClass) > class,model,dir(add input event)>event + processes.forEach(process => { + process(paths, path, state, isComponent, tagName).forEach((property) => { + addAttrProperties.push(property) + }) + }) + + // 该组件是引入的小程序组件 + if (state.options.wxComponents[tagName]) { + addAttrProperties.push( + t.objectProperty( + t.stringLiteral(ATTR_DATA_COM_TYPE), + t.stringLiteral('wx') + ) + ) + } + + if (addAttrProperties.length) { + const attrsPath = paths['attrs'] + if (attrsPath) { + attrsPath.node.value.properties = attrsPath.node.value.properties.concat(addAttrProperties) + } else { + path.node.properties.unshift( + t.objectProperty(t.identifier('attrs'), t.objectExpression(addAttrProperties)) + ) + } + } +} diff --git a/packages/uni-template-compiler/lib/script/traverse/data/model.js b/packages/uni-template-compiler/lib/script/traverse/data/model.js new file mode 100644 index 000000000..bbf647ca3 --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/data/model.js @@ -0,0 +1,71 @@ +const t = require('@babel/types') + +const { + getModelEventFunctionExpr +} = require('./util') + +module.exports = function processRef (paths, path, state) { + const modelPath = paths['model'] + if (modelPath) { + const callbackProperty = modelPath.node.value.properties.find(property => { + return property.key.name === 'callback' + }) + + const exprProperty = modelPath.node.value.properties.find( + property => property.key.name === 'expression' + ) + + const prop = exprProperty.value.value.trim() + + const onPath = paths['on'] + + // on:{'input':__m('msg',$event)} + if (!onPath) { + path.node.properties.unshift( + t.objectProperty(t.identifier('on'), t.objectExpression([ + t.objectProperty( + t.stringLiteral('input'), + getModelEventFunctionExpr( + callbackProperty.value, + prop + ) + ) + ])) + ) + paths['on'] = path.get('properties').find( + propertyPath => propertyPath.node.key.name === 'on' + ) + } else { + const existingInput = onPath.node.value.properties.find( + property => property.key.value === 'input' + ) + if (existingInput) { + if (!t.isArrayExpression(existingInput.value)) { + existingInput.value = t.arrayExpression([existingInput.value]) + } + existingInput.value.elements.unshift(getModelEventFunctionExpr( + callbackProperty.value, + prop + )) + } else { + onPath.node.value.properties.push( + t.objectProperty( + t.stringLiteral('input'), + getModelEventFunctionExpr( + callbackProperty.value, + prop + ) + ) + ) + } + } + + return [ // attrs:{value:value} + t.objectProperty( + t.stringLiteral('value'), + t.identifier(prop) + ) + ] + } + return [] +} diff --git a/packages/uni-template-compiler/lib/script/traverse/data/ref.js b/packages/uni-template-compiler/lib/script/traverse/data/ref.js new file mode 100644 index 000000000..6ba77046e --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/data/ref.js @@ -0,0 +1,43 @@ +const t = require('@babel/types') + +const { + CLASS_REF, + CLASS_REF_IN_FOR +} = require('../../../constants') + +module.exports = function processRef (paths, path, state) { + const refPath = paths['ref'] + if (refPath) { + if (state.options.platform.name === 'mp-alipay') { + return [ + t.objectProperty( // data-ref="" ,data-ref-in-for="" + t.stringLiteral('ref'), + t.stringLiteral('__r') + ), + t.objectProperty( // data-ref="" ,data-ref-in-for="" + t.stringLiteral(state.inFor ? state.options.platform.refInFor : state.options.platform.ref), + refPath.node.value + ) + ] + } + const refClass = state.inFor ? CLASS_REF_IN_FOR : CLASS_REF + const staticClassPath = paths['staticClass'] + if (staticClassPath) { // append + staticClassPath.node.value.value = staticClassPath.node.value.value + ' ' + refClass + } else { // add staticClass + path.node.properties.unshift( + t.objectProperty(t.identifier('staticClass'), t.stringLiteral(refClass)) + ) + paths['staticClass'] = path.get('properties').find( + propertyPath => propertyPath.node.key.name === 'staticClass' + ) + } + return [ + t.objectProperty( // data-ref="" ,头条 vue-ref + t.stringLiteral(state.options.platform.ref), + refPath.node.value + ) + ] + } + return [] +} diff --git a/packages/uni-template-compiler/lib/script/traverse/data/style.js b/packages/uni-template-compiler/lib/script/traverse/data/style.js new file mode 100644 index 000000000..f112fd09f --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/data/style.js @@ -0,0 +1,177 @@ +const t = require('@babel/types') + +const { + IDENTIFIER_STYLE, + INTERNAL_GET_STYLE +} = require('../../../constants') + +const { + getCode, + hyphenate +} = require('../../../util') + +const getMemberExpr = require('../member-expr') + +const REGEX_PX = /(:|\s|\(|\/)[+-]?\d+(\.\d+)?u?px/g +const REGEX_UPX = /(:|\s|\(|\/)[+-]?\d+(\.\d+)?upx/g + +function processStaticStyleUnit (styleStr, state) { + if (typeof styleStr === 'string') { + let matches = styleStr.match(REGEX_UPX) + if (matches && matches.length) { + matches.forEach(function (match) { + styleStr = styleStr.replace(match, match.substr(0, match.length - 3) + 'rpx') + }) + } + // TODO 不应该再支持 px 转 rpx + if (state.options.transformPx) { // 需要转换 px + matches = styleStr.match(REGEX_PX) + if (matches && matches.length) { + matches.forEach(function (match) { + styleStr = styleStr.replace(match, match.substr(0, match.length - 2) + 'rpx') + }) + } + } + } + return styleStr +} + +function getStaticStyleStringLiteral (staticStylePath, state) { + const staticStyle = staticStylePath.node.value.properties + .map(property => { + return `${property.key.value}:${property.value.value}` + }) + .join(';') + const staticStyleStr = processStaticStyleUnit(staticStyle, state).trim() + return t.stringLiteral(staticStyleStr + (!staticStyleStr.endsWith(';') ? ';' : '')) +} + +function processStaticStyle (binaryExpressions, staticStylePath, state) { + let binaryExpression + + binaryExpressions.forEach(binaryExpr => { + if (!binaryExpression) { + if (staticStylePath) { + binaryExpression = t.binaryExpression( + '+', + getStaticStyleStringLiteral(staticStylePath, state), + binaryExpr + ) + staticStylePath.remove() + } else { + binaryExpression = binaryExpr + } + } else { + binaryExpression = t.binaryExpression( + '+', + binaryExpression, + binaryExpr + ) + } + }) + + return binaryExpression +} + +function processStyleObjectExpression (styleValuePath) { + const binaryExpressions = [] + const propertyPaths = styleValuePath.get('properties') + propertyPaths.forEach(propertyPath => { + const key = propertyPath.node.key + binaryExpressions.push( + t.binaryExpression( + '+', + t.binaryExpression( + '+', + t.stringLiteral(hyphenate(key.name || key.value) + ':'), + t.parenthesizedExpression(propertyPath.node.value) + ), + t.stringLiteral(';') + ) + ) + }) + return binaryExpressions +} + +function processStyleArrayExpression (elementPaths) { + let binaryExpressions = [] + elementPaths.forEach(elementPath => { + binaryExpressions = binaryExpressions.concat(processStyleObjectExpression(elementPath)) + }) + return binaryExpressions +} + +function generateGetStyle (stylePath, styleValuePath, staticStylePath, state) { + const args = [stylePath.node.value] + if (staticStylePath) { + args.push(staticStylePath.node.value) + staticStylePath.remove() + } + styleValuePath.replaceWith( + getMemberExpr( + stylePath, + IDENTIFIER_STYLE, + t.callExpression(t.identifier(INTERNAL_GET_STYLE), args), + state + ) + ) +} + +module.exports = function processStyle (paths, path, state) { + const stylePath = paths['style'] + const staticStylePath = paths['staticStyle'] + if (stylePath) { + const styleValuePath = stylePath.get('value') + if (styleValuePath.isObjectExpression()) { + styleValuePath.replaceWith( + processStaticStyle( + processStyleObjectExpression(styleValuePath), + staticStylePath, + state + ) + ) + } else if (styleValuePath.isArrayExpression()) { // array + const elementPaths = styleValuePath.get('elements') + const dynamicStyle = elementPaths.find(elementPath => !elementPath.isObjectExpression()) + if (dynamicStyle) { + generateGetStyle(stylePath, styleValuePath, staticStylePath, state) + } else { + styleValuePath.replaceWith( + processStaticStyle( + processStyleArrayExpression(elementPaths), + staticStylePath, + state + ) + ) + } + } else if ( + styleValuePath.isStringLiteral() || // :style="'background:red'" + styleValuePath.isIdentifier() || // TODO 需要优化到下一个条件,:style="styleObject" + styleValuePath.isMemberExpression() || // TODO 需要优化到下一个条件,:style="item.styleObject" + styleValuePath.isConditionalExpression() || + styleValuePath.isLogicalExpression() || + styleValuePath.isBinaryExpression() + ) { + // 理论上 ConditionalExpression,LogicalExpression 可能存在 styleObject,应该__get_style,还是先不考虑这种情况吧 + // ConditionalExpression :style="index === currentIndex ? activeStyle : itemStyle" + // BinaryExpression :style="'m-content-head-'+message.user" + styleValuePath.replaceWith( + processStaticStyle( + [t.parenthesizedExpression(styleValuePath.node)], + staticStylePath, + state + ) + ) + } else if ( + styleValuePath.isIdentifier() || + styleValuePath.isMemberExpression() + ) { // TODO 目前先不考虑 classObject,styleObject + // generateGetStyle(stylePath, styleValuePath, staticStylePath, state) + } else { + state.errors.add(`:style 不支持 ${getCode(styleValuePath.node)} 语法`) + } + } else if (staticStylePath) { + staticStylePath.get('value').replaceWith(getStaticStyleStringLiteral(staticStylePath, state)) + } + return [] +} diff --git a/packages/uni-template-compiler/lib/script/traverse/data/tag.js b/packages/uni-template-compiler/lib/script/traverse/data/tag.js new file mode 100644 index 000000000..182a5adcd --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/data/tag.js @@ -0,0 +1 @@ +// 需要转换 h5 标签至 staticClass 的样式名 diff --git a/packages/uni-template-compiler/lib/script/traverse/data/util.js b/packages/uni-template-compiler/lib/script/traverse/data/util.js new file mode 100644 index 000000000..e4aa7dd77 --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/data/util.js @@ -0,0 +1,47 @@ +const t = require('@babel/types') +const babelTraverse = require('@babel/traverse').default + +const { + INTERNAL_SET_MODEL +} = require('../../../constants') + +module.exports = { + getModelEventFunctionExpr (funcExpr, propPath, modifiers = []) { + let targetExpr + let keyExpr + babelTraverse(funcExpr, { + noScope: true, + CallExpression (path) { + if (path.node.callee.name === '$set') { + targetExpr = path.node.arguments[0] + keyExpr = path.node.arguments[1] + } + } + }) + + if (!targetExpr || !keyExpr) { + targetExpr = t.stringLiteral('') + keyExpr = t.stringLiteral(propPath) + } + + return t.functionExpression( + null, + [t.identifier('$event')], + t.blockStatement( + [ + t.returnStatement( + t.callExpression( + t.identifier(INTERNAL_SET_MODEL), + [ + targetExpr, + keyExpr, + t.identifier('$event'), + t.arrayExpression(modifiers) + ] + ) + ) + ] + ) + ) + } +} diff --git a/packages/uni-template-compiler/lib/script/traverse/filter.js b/packages/uni-template-compiler/lib/script/traverse/filter.js new file mode 100644 index 000000000..6154121fa --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/filter.js @@ -0,0 +1,179 @@ +const t = require('@babel/types') + +const { + VAR_FILTER +} = require('../../constants') + +const GLOBAL_METHODS = [ + 'parseInt', + 'parseFloat', + 'isNaN', + 'isFinite', + 'decodeURI', + 'decodeURIComponent', + 'encodeURI', + 'encodeURIComponent' +] + +const GLOBAL_OBJECTS = { + 'Math': [ + 'abs', + 'acos', + 'asin', + 'atan', + 'atan2', + 'ceil', + 'cos', + 'exp', + 'floor', + 'log', + 'max', + 'min', + 'pow', + 'random', + 'round', + 'sin', + 'sqrt', + 'tan' + ], + 'JSON': [ + 'stringify', + 'parse' + ] +} + +const BUILT_IN_METHODS = [ + // number + 'toString', + 'toLocaleString', + 'valueOf', + 'toFixed', + 'toExponential', + 'toPrecision', + // string + // 'toString', + // 'valueOf', + 'charAt', + 'charCodeAt', + 'concat', + 'indexOf', + 'lastIndexOf', + 'localeCompare', + 'match', + 'replace', + 'search', + 'slice', + 'split', + 'substring', + 'toLowerCase', + 'toLocaleLowerCase', + 'toUpperCase', + 'toLocaleUpperCase', + 'trim', + // boolean + // 'toString', + // 'valueOf', + // object + // 'toString', + // function + // 'toString', + // array + // 'toString', + // 'concat', + 'join', + 'pop', + 'push', + 'reverse', + 'shift', + // 'slice', + 'sort', + 'splice', + 'unshift', + // 'indexOf', + // 'lastIndexOf', + 'every', + 'some', + 'forEach', + 'map', + 'filter', + 'reduce', + 'reduceRight' +] + +function getGlobalMethodFilter (callExpr) { + const callee = callExpr.callee + if (callee) { + const name = callee.name + if (name && GLOBAL_METHODS.includes(name)) { + return t.callExpression( + t.memberExpression( + t.identifier(VAR_FILTER), + t.identifier(name) + ), + callExpr.arguments + ) + } + } + return false +} + +function getGlobalObjectFilter (callExpr) { + const callee = callExpr.callee + if (t.isMemberExpression(callee)) { + const object = callee.object + const property = callee.property + const propertyName = property.name || property.value + const methods = GLOBAL_OBJECTS[object.name] + if (methods && methods.includes(propertyName)) { + return t.callExpression( + t.memberExpression( + t.identifier(VAR_FILTER), + t.identifier(propertyName) + ), + callExpr.arguments + ) + } + } + return false +} + +function getMemberFilter (callExpr) { + const callee = callExpr.callee + if (t.isMemberExpression(callee)) { + const property = callee.property + const propertyName = property.name || property.value + if (BUILT_IN_METHODS.includes(propertyName)) { + return t.callExpression( + t.memberExpression( + t.identifier(VAR_FILTER), + t.identifier(propertyName) + ), + [ + callee.object, + ...callExpr.arguments + ] + ) + } + } +} + +function processFilter (callExpr, path) { + const globalMethodFilter = getGlobalMethodFilter(callExpr) + if (globalMethodFilter) { + path.replaceWith(globalMethodFilter) + return true + } + const globalObjectFilter = getGlobalObjectFilter(callExpr) + if (globalObjectFilter) { + path.replaceWith(globalObjectFilter) + return true + } + const memberFilter = getMemberFilter(callExpr) + if (memberFilter) { + path.replaceWith(memberFilter) + return true + } + return false +} + +module.exports = processFilter diff --git a/packages/uni-template-compiler/lib/script/traverse/index.js b/packages/uni-template-compiler/lib/script/traverse/index.js new file mode 100644 index 000000000..94fa12864 --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/index.js @@ -0,0 +1,120 @@ +const t = require('@babel/types') + +const babelTraverse = require('@babel/traverse').default + +const { + VAR_ROOT, + IDENTIFIER_FOR, + IDENTIFIER_ATTR, + IDENTIFIER_METHOD, + IDENTIFIER_FILTER, + IDENTIFIER_CLASS, + IDENTIFIER_STYLE, + IDENTIFIER_EVENT, + IDENTIFIER_GLOBAL, + PREFIX_ATTR, + PREFIX_GLOBAL, + PREFIX_METHOD, + PREFIX_FILTER, + PREFIX_FOR, + PREFIX_CLASS, + PREFIX_STYLE, + PREFIX_EVENT +} = require('../../constants') + +const { + getInItIfStatement, + getDataExpressionStatement +} = require('./statements') + +const visitor = require('./visitor') + +function reIdentifier (identifierArray) { + const identifierOpts = { + [IDENTIFIER_FOR]: { + prefix: PREFIX_FOR, + id: 0 + }, + [IDENTIFIER_METHOD]: { + prefix: PREFIX_METHOD, + id: 0 + }, + [IDENTIFIER_FILTER]: { + prefix: PREFIX_FILTER, + id: 0 + }, + [IDENTIFIER_CLASS]: { + prefix: PREFIX_CLASS, + id: 0 + }, + [IDENTIFIER_STYLE]: { + prefix: PREFIX_STYLE, + id: 0 + }, + [IDENTIFIER_EVENT]: { + prefix: PREFIX_EVENT, + id: 0 + }, + [IDENTIFIER_GLOBAL]: { + prefix: PREFIX_GLOBAL, + id: 0 + }, + [IDENTIFIER_ATTR]: { + prefix: PREFIX_ATTR, + id: 0 + } + } + // TODO order + identifierArray.forEach(identifier => { + if (Array.isArray(identifier)) { + let opts = false + identifier.forEach(stringLiteral => { + const key = t.isStringLiteral(stringLiteral) ? 'value' : 'name' + if (opts === false) { + opts = identifierOpts[stringLiteral[key]] + stringLiteral[key] = `${opts.prefix + opts.id++}` + } else { + stringLiteral[key] = `${opts.prefix + (opts.id - 1)}` + } + }) + } else { + const key = t.isStringLiteral(identifier) ? 'value' : 'name' + const opts = identifierOpts[identifier[key]] + identifier[key] = `${opts.prefix + opts.id++}` + } + }) +} + +module.exports = function traverse (ast, state) { + const identifierArray = [] + const blockStatementBody = [] + const objectPropertyArray = [] + const initExpressionStatementArray = [] + + babelTraverse(ast, visitor, undefined, { + scoped: [], + context: VAR_ROOT, + options: state.options, + errors: state.errors, + tips: state.tips, + identifierArray: identifierArray, + propertyArray: objectPropertyArray, + declarationArray: blockStatementBody, + initExpressionStatementArray: initExpressionStatementArray + }) + + if (initExpressionStatementArray.length) { + blockStatementBody.push(getInItIfStatement(initExpressionStatementArray)) + } + + if (objectPropertyArray.length) { + blockStatementBody.push(getDataExpressionStatement(objectPropertyArray)) + } + + reIdentifier(identifierArray) + + return t.withStatement( + t.thisExpression(), + t.blockStatement(blockStatementBody) + ) +} diff --git a/packages/uni-template-compiler/lib/script/traverse/member-expr.js b/packages/uni-template-compiler/lib/script/traverse/member-expr.js new file mode 100644 index 000000000..e6cd4b36d --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/member-expr.js @@ -0,0 +1,78 @@ +const t = require('@babel/types') + +function isMatch (name, forItem, forIndex) { + return name === forItem || name === forIndex +} + +function getIdentifierName (element) { + if (t.isMemberExpression(element)) { + return getIdentifierName(element.object) + } else if (t.isCallExpression(element)) { + return getIdentifierName(element.callee) + } + return element.name && element.name.split('.')[0] +} + +function findScoped (path, state) { + if (!path) { + return state + } + const scoped = state.scoped.find(scoped => { + const { + forItem, + forIndex + } = scoped + let match = false + if (path.isIdentifier() || path.isMemberExpression()) { + match = isMatch(getIdentifierName(path.node), forItem, forIndex) + } else { + path.traverse({ + noScope: true, + Identifier (path) { + if (!match) { + match = isMatch(path.node.name, forItem, forIndex) + if (match) { + path.stop() + } + } + }, + MemberExpression (path) { + if (!match) { + match = isMatch(getIdentifierName(path.node), forItem, forIndex) + if (match) { + path.stop() + } + path.skip() + } + } + }) + } + return match + }) + if (!scoped && state.scoped.length > 1) { + return state.scoped[1] // 取父 + } + return scoped || state +} + +module.exports = function getMemberExpr (path, name, init, state, variableDeclaration = true) { + const scoped = findScoped(path, state) + + if (!variableDeclaration) { + scoped.declarationArray.push(t.expressionStatement(init)) + return + } + + const identifier = t.identifier(name) + + scoped.propertyArray.push(t.objectProperty(identifier, identifier)) + scoped.declarationArray.push( + t.variableDeclaration('var', [t.variableDeclarator(identifier, init)]) + ) + + state.identifierArray.push(identifier) + + const contextIdentifier = t.identifier(scoped.context) + contextIdentifier.$mpProcessed = true + return t.memberExpression(contextIdentifier, identifier) +} diff --git a/packages/uni-template-compiler/lib/script/traverse/render-list.js b/packages/uni-template-compiler/lib/script/traverse/render-list.js new file mode 100644 index 000000000..6b5af24bc --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/render-list.js @@ -0,0 +1,177 @@ +const t = require('@babel/types') + +const { + VAR_ORIGINAL, + IDENTIFIER_FOR, + METHOD_RENDER_LIST +} = require('../../constants') + +const { + getMapCallExpression +} = require('./statements') + +const { + genCode, + traverseKey, + processMemberExpression, + getForIndexIdentifier +} = require('../../util') + +const getMemberExpr = require('./member-expr') + +const origVisitor = { + noScope: true, + Identifier (path) { + if ( + !path.node.$mpProcessed && + path.node.name === this.forItem && + path.isReferencedIdentifier() + ) { + const forItemIdentifier = t.identifier(this.forItem) + forItemIdentifier.$mpProcessed = true + path.replaceWith( + t.memberExpression(forItemIdentifier, t.identifier(VAR_ORIGINAL)) + ) + } + }, + FunctionExpression (path) { + const callee = path.parentPath.node.callee + if (t.isIdentifier(callee) && callee.name === METHOD_RENDER_LIST) { + path.traverse(origVisitor, { + forItem: this.forItem + }) + path.skip() + } + } +} + +function isRefrence (forItem, code) { + if (forItem === code) { + return true + } + return code.indexOf(forItem + '.') === 0 +} + +function replaceRefrence (forItem, code) { + if (forItem === code) { + return '' + } + return code.replace(forItem + '.', '') +} + +function getForExtra (forItem, forIndex, path, state) { + let forCode = genCode(processMemberExpression(path.node.arguments[0], state), true) + + const forKey = traverseKey(path.node) + let origForKeyCode = t.isIdentifier(forKey) && forKey.name + let forKeyCode = '' + if (forKey) { + forKeyCode = genCode(processMemberExpression(forKey, state), true) + if (isRefrence(forItem, forKeyCode)) { + forKeyCode = replaceRefrence(forItem, forKeyCode) + } + } + const forExtraElements = [] + if (state.scoped.length) { + const scoped = state.scoped.find(scoped => isRefrence(scoped.forItem, forCode)) + if (scoped) { + forCode = replaceRefrence(scoped.forItem, forCode) + forExtraElements.push(...scoped.forExtra) + } + } + if (forItem === origForKeyCode) { // 以自身为 key,则依据 forIndex 查找 ['list','',__i0__],['list','',index] + forExtraElements.push( + t.arrayExpression( + [ + t.stringLiteral(forCode), + t.stringLiteral(''), + t.identifier(forIndex) + ] + ) + ) + } else { + forExtraElements.push( + t.arrayExpression( + [ + t.stringLiteral(forCode), + t.stringLiteral(forIndex === forKeyCode ? '' : forKeyCode), + forKey || t.identifier(forIndex) + ] + ) + ) + } + return forExtraElements +} + +module.exports = function traverseRenderList (path, state) { + const functionExpression = path.get('arguments.1') + const params = functionExpression.node.params + const forItem = params[0].name + let forIndex = params.length > 1 && params[1].name + + if (!forIndex) { + if (!state.options.hasOwnProperty('$forIndexId')) { + state.options.$forIndexId = 0 + } + forIndex = getForIndexIdentifier(state.options.$forIndexId++) + params.push(t.identifier(forIndex)) + } + + const forStateScoped = { + context: forItem, + forItem, + forIndex, + forExtra: getForExtra(forItem, forIndex, path, state), + propertyArray: [], + declarationArray: [] + } + + const forState = { + inFor: true, + context: state.context, + options: state.options, + errors: state.errors, + tips: state.tips, + scoped: [forStateScoped].concat(state.scoped), + identifierArray: state.identifierArray, + propertyArray: [], + declarationArray: [], + initExpressionStatementArray: state.initExpressionStatementArray + } + + functionExpression.traverse(require('./visitor'), forState) + + const forPath = path.get('arguments.0') + if (forStateScoped.propertyArray.length) { + // for => map + forPath.replaceWith( + getMemberExpr( + forPath, + IDENTIFIER_FOR, + getMapCallExpression( + forPath.node, + forStateScoped.propertyArray, + forStateScoped.declarationArray, + [], // eventPropertyArray + forItem, + forIndex + ), + forState + ) + ) + + functionExpression.traverse(origVisitor, { + forItem + }) + } else { + forPath.traverse(require('./visitor'), forState) + } + + forState.propertyArray.forEach(property => { + state.propertyArray.push(property) + }) + + forState.declarationArray.forEach(declaration => { + state.declarationArray.push(declaration) + }) +} diff --git a/packages/uni-template-compiler/lib/script/traverse/statements.js b/packages/uni-template-compiler/lib/script/traverse/statements.js new file mode 100644 index 000000000..ea53c462e --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/statements.js @@ -0,0 +1,119 @@ +const t = require('@babel/types') + +const { + VAR_MP, + VAR_ROOT, + VAR_ORIGINAL, + INTERNAL_GET_ORIG +} = require('../../constants') +/** + * e0=e=>count++ + */ +function getEventExpressionStatement (left, right) { + return t.expressionStatement( + t.assignmentExpression( + '=', + left, + right + ) + ) +} +/** + * if(!_isMounted){} + */ +function getInItIfStatement (expressionStatementArray) { + return t.ifStatement( + t.unaryExpression( + '!', + t.identifier('_isMounted') + ), + t.blockStatement(expressionStatementArray) + ) +} + +/** + * items.map(function(item,index){return {}}) + */ +function getMapCallExpression ( + object, + objectPropertyArray, + declarationArray, + eventPropertyArray, + forItem, + forIndex +) { + const blockStatement = [] + + if (declarationArray.length) { + declarationArray.forEach(declaration => { + blockStatement.push(declaration) + }) + blockStatement.push(t.returnStatement( + // return {$orgi:__get_orig(forItem)} + t.objectExpression( + [ + t.objectProperty( + t.identifier(VAR_ORIGINAL), + t.callExpression(t.identifier(INTERNAL_GET_ORIG), [ + t.identifier(forItem) + ]) + ) + ].concat(objectPropertyArray) + ) + )) + } + + const params = [t.identifier(forItem)] + if (forIndex) { + params.push(t.identifier(forIndex)) + } + return t.callExpression(t.identifier('__map'), [ + object, + t.functionExpression( + null, + params, + t.blockStatement(blockStatement) + ) + ]) +} + +/** + * $mp.data = Object.assign({},{$root:{}}) + */ +function getDataExpressionStatement (objectPropertyArray) { + return t.expressionStatement( + t.assignmentExpression( + '=', + t.memberExpression( + // left + t.identifier(VAR_MP), + t.identifier('data') + ), + t.callExpression( + // right + t.memberExpression( + // Object.assign + t.identifier('Object'), + t.identifier('assign') + ), + [ + t.objectExpression([]), // {} + t.objectExpression([ + // {$root:{}} + t.objectProperty( + t.identifier(VAR_ROOT), + t.objectExpression(objectPropertyArray) + ) + ]) + ] + ) + ) + ) +} + +module.exports = { + getInItIfStatement, + getMapCallExpression, + getDataExpressionStatement, + getEventExpressionStatement +} diff --git a/packages/uni-template-compiler/lib/script/traverse/visitor.js b/packages/uni-template-compiler/lib/script/traverse/visitor.js new file mode 100644 index 000000000..90035ddd6 --- /dev/null +++ b/packages/uni-template-compiler/lib/script/traverse/visitor.js @@ -0,0 +1,250 @@ +const t = require('@babel/types') + +const { + METHOD_CREATE_ELEMENT, + METHOD_TO_STRING, + METHOD_RENDER_LIST, + METHOD_BUILT_IN, + METHOD_RESOLVE_FILTER, + IDENTIFIER_FILTER, + IDENTIFIER_METHOD, + IDENTIFIER_GLOBAL +} = require('../../constants') + +const { + getTagName +} = require('../../h5') + +const { + hyphenate, + getComponentName +} = require('../../util') + +const traverseData = require('./data') +const traverseRenderList = require('./render-list') + +const getMemberExpr = require('./member-expr') + +function addStaticClass (path, staticClass) { + const dataPath = path.get('arguments.1') + if (dataPath && dataPath.isObjectExpression()) { + const staticClassProperty = dataPath.node.properties.find(property => property.key.name === 'staticClass') + if (staticClassProperty) { // update + staticClassProperty.value.value = staticClassProperty.value.value + ' ' + staticClass + } else { // add + dataPath.node.properties.push( + t.objectProperty(t.identifier('staticClass'), t.stringLiteral(staticClass)) + ) + } + } else { // {staticClass:'data-v-aaa'} + const args = path.node.arguments + args.splice(1, 0, t.objectExpression( + [ + t.objectProperty(t.identifier('staticClass'), t.stringLiteral(staticClass)) + ] + )) + } +} + +function addVueId (path, state) { + // const platformName = state.options.platform.name + // if ( // 暂不对 mp-weixin,app-plus 增加 vueId + // platformName === 'mp-weixin' || + // platformName === 'app-plus' + // ) { + // return + // } + if (!state.options.hasOwnProperty('$vueId')) { + state.options.$vueId = 1 + } + const vueId = String(state.options.$vueId++) + + let value + + if (state.scoped.length) { + let scopeds = state.scoped + let len = scopeds.length + if (len > 1) { // v-for 嵌套,forIndex 不允许重复 + const forIndexSet = new Set() + for (let i = 0; i < len; i++) { + const scoped = scopeds[i] + forIndexSet.add(scoped.forIndex) + if (forIndexSet.size !== i + 1) { + state.errors.add(`v-for 嵌套时,索引名称 ${scoped.forIndex} 不允许重复`) + break + } + } + } + for (let i = len - 1; i >= 0; i--) { + const scoped = scopeds[i] + if (!value) { + value = t.binaryExpression('+', t.stringLiteral(vueId + '-'), t.identifier(scoped.forIndex)) + } else { + value = t.binaryExpression('+', + t.binaryExpression('+', value, t.stringLiteral('-')), + t.identifier(scoped.forIndex) + ) + } + } + } else { + value = t.stringLiteral(vueId) + } + + const objectProperty = t.objectProperty( + t.stringLiteral('vue-id'), + value + ) + + const dataPath = path.get('arguments.1') + if (dataPath && dataPath.isObjectExpression()) { + const attrsProperty = dataPath.node.properties.find(property => property.key.name === 'attrs') + if (attrsProperty) { + attrsProperty.value.properties.unshift(objectProperty) + } else { + dataPath.node.properties.push( + t.objectProperty(t.identifier('attrs'), t.objectExpression([ + objectProperty + ])) + ) + } + } else { // {attrs:{'vue-id':'2'}} + const args = path.node.arguments + args.splice(1, 0, t.objectExpression( + [ + t.objectProperty(t.identifier('attrs'), t.objectExpression([ + objectProperty + ])) + ] + )) + } +} + +function checkUsingGlobalComponents (name, globalUsingComponents, state) { + if (globalUsingComponents && globalUsingComponents[name]) { + if (!state.options.usingGlobalComponents) { + state.options.usingGlobalComponents = Object.create(null) + } + state.options.usingGlobalComponents[name] = globalUsingComponents[name] + } +} + +module.exports = { + noScope: true, + CallExpression (path) { + const callee = path.node.callee + if (t.isIdentifier(callee)) { + const methodName = callee.name + switch (methodName) { + case METHOD_CREATE_ELEMENT: + const tagNode = path.node.arguments[0] + if (t.isStringLiteral(tagNode)) { + // 需要把标签增加到 class 样式中 + const tagName = getTagName(tagNode.value) + if (tagName !== tagNode.value) { + addStaticClass(path, '_' + tagNode.value) + } + tagNode.value = getComponentName(hyphenate(tagName)) + + // 组件增加 vueId + if (this.options.platform.isComponent(tagNode.value)) { + addVueId(path, this) + } + + // 查找全局组件 + checkUsingGlobalComponents( + tagNode.value, + this.options.globalUsingComponents, + this + ) + } + if (this.options.scopeId) { + addStaticClass(path, this.options.scopeId) + } + + const dataPath = path.get('arguments.1') + dataPath && dataPath.isObjectExpression() && traverseData(dataPath, this, tagNode.value) + break + case METHOD_TO_STRING: + const stringNodes = path.node.arguments[0] + stringNodes.$toString = true + path.replaceWith(stringNodes) + break + case METHOD_RENDER_LIST: + traverseRenderList(path, this) + path.skip() + break + default: + if (!METHOD_BUILT_IN.includes(methodName)) { + if ( + path.findParent( + path => + path.isObjectProperty() && ['on', 'nativeOn'].includes(path.node.key.name) + ) + ) { + // event + return path.skip() + } + + path.replaceWith( + getMemberExpr( + path, + methodName === METHOD_RESOLVE_FILTER + ? IDENTIFIER_FILTER + : IDENTIFIER_METHOD, + path.node, + this + ) + ) + } + break + } + } else if ( + t.isCallExpression(callee) && + t.isIdentifier(callee.callee) && + callee.callee.name === METHOD_RESOLVE_FILTER + ) { + // multi filter + path.replaceWith(getMemberExpr(path, IDENTIFIER_FILTER, path.node, this)) + } else if ( + t.isMemberExpression(callee) // message.split('').reverse().join('') + ) { + // Object.assign... + path.replaceWith(getMemberExpr(path, IDENTIFIER_GLOBAL, path.node, this)) + } + }, + TemplateLiteral (path) { + const nodes = [] + const expressions = path.get('expressions') + + let index = 0 + for (const elem of path.node.quasis) { + if (elem.value.cooked) { + nodes.push(t.stringLiteral(elem.value.cooked)) + } + + if (index < expressions.length) { + const expr = expressions[index++] + const node = expr.node + if (!t.isStringLiteral(node, { + value: '' + })) { + nodes.push(node) + } + } + } + + // since `+` is left-to-right associative + // ensure the first node is a string if first/second isn't + const considerSecondNode = !t.isStringLiteral(nodes[1]) + if (!t.isStringLiteral(nodes[0]) && considerSecondNode) { + nodes.unshift(t.stringLiteral('')) + } + let root = nodes[0] + + for (let i = 1; i < nodes.length; i++) { + root = t.binaryExpression('+', root, nodes[i]) + } + + path.replaceWith(root) + } +} diff --git a/packages/uni-template-compiler/lib/template/generate.js b/packages/uni-template-compiler/lib/template/generate.js new file mode 100644 index 000000000..403012a25 --- /dev/null +++ b/packages/uni-template-compiler/lib/template/generate.js @@ -0,0 +1,131 @@ +const { + SELF_CLOSING_TAGS, + INTERNAL_EVENT_LINK +} = require('../constants') + +function processElement (ast, state, isRoot) { + const platformName = state.options.platform.name + // + if (ast.type === 'template' && ast.attr.hasOwnProperty('slot')) { + ast.type = 'view' + } + + if (ast.attr.hasOwnProperty('textContent')) { + ast.children = [ast.attr['textContent']] + delete ast.attr['textContent'] + } + if (ast.attr.hasOwnProperty('innerHTML')) { + ast.children = [{ + type: 'rich-text', + attr: { + nodes: ast.attr['innerHTML'] + }, + children: [] + }] + delete ast.attr['innerHTML'] + } + if (state.options.platform.isComponent(ast.type)) { + if (platformName === 'mp-alipay') { + ast.attr['onVueInit'] = INTERNAL_EVENT_LINK + } else if (platformName !== 'mp-baidu') { + ast.attr['bind:' + INTERNAL_EVENT_LINK] = INTERNAL_EVENT_LINK + } + + const children = ast.children + // default slot + let defaultSlot = false + const slots = [] + for (let i = children.length - 1; i >= 0; i--) { + const childElement = children[i] + // => + if (typeof childElement !== 'string' && childElement.attr.slot) { + if (childElement.type === 'block') { + childElement.type = 'view' + } + slots.push(childElement.attr.slot) + } else { + defaultSlot = true + } + } + if (defaultSlot) { + slots.push('default') + } + if (ast.attr.generic) { + Object.keys(ast.attr.generic).forEach(scopedSlotName => { + slots.push(scopedSlotName) + }) + delete ast.attr.generic + } + if (slots.length && platformName !== 'mp-alipay') { // 标记 slots + ast.attr['vue-slots'] = '{{[' + slots.reverse().map(slotName => `'${slotName}'`).join(',') + ']}}' + } + if (ast.attr['id'] && ast.attr['id'].indexOf('{{') === 0) { + state.tips.add(`id 作为属性保留名,不允许在自定义组件 ${ast.type} 中定义为 props`) + } + if (ast.attr.hasOwnProperty('data')) { // 百度中会出现异常情况 + state.tips.add(`data 作为属性保留名,不允许在自定义组件 ${ast.type} 中定义为 props`) + } + } +} + +function genElement (ast, state, isRoot = false) { + if (!ast) { + return '' + } + if (typeof ast === 'string') { + return genText(ast, state) + } + + processElement(ast, state, isRoot) + + const names = Object.keys(ast.attr) + const props = names.length + ? ' ' + + names + .map(name => { + if (name.includes(':else')) { + return name + } + if (ast.attr[name] === '' && name !== 'value') { // value属性需要保留='' + return name + } + return `${name}="${ast.attr[name]}"` + }) + .join(' ') + : '' + if (SELF_CLOSING_TAGS.includes(ast.type)) { + return `<${ast.type}${props}/>` + } + + let children = ast.children + .map(child => { + return genElement(child, state, isRoot && ast.type === 'block') // 如果根节点是 block,则继续 root + }) + .join('') + + if (ast.scoped) { // 简单处理的 scoped slots 子节点的变量 + children = children.replace(new RegExp(ast.scoped + '.', 'g'), '') + } + return `<${ast.type}${props}>${children}` +} + +function genText (ast, state) { + return ast +} + +module.exports = function generate (ast, state) { + if (!Array.isArray(ast)) { + ast = [ast] + } + + let code = ast.map(ast => genElement(ast, state, true)).join('') + + const replaceCodes = state.options.replaceCodes + if (replaceCodes) { + Object.keys(replaceCodes).forEach(key => { + code = code.replace(key, replaceCodes[key]) + }) + } + + return code +} diff --git a/packages/uni-template-compiler/lib/template/traverse.js b/packages/uni-template-compiler/lib/template/traverse.js new file mode 100644 index 000000000..da1f5ba36 --- /dev/null +++ b/packages/uni-template-compiler/lib/template/traverse.js @@ -0,0 +1,464 @@ +const path = require('path') + +const t = require('@babel/types') +const babelTraverse = require('@babel/traverse').default + +const generate = require('./generate') + +const { + genCode, + getCode, + getForKey, + traverseKey +} = require('../util') + +module.exports = function traverse (ast, state = {}) { + babelTraverse(ast, { + WithStatement (path) { + state.ast = traverseExpr(path.node.body.body[0].argument, state) + } + }) + initParent(state.ast) + return state.ast +} + +function initParent (ast, parentNode) { + if (Array.isArray(ast)) { + ast.forEach(node => initParent(node, parentNode)) + } else if (typeof ast === 'object') { + ast.parent = parentNode + + const vueId = ast.$vueId + if (vueId) { + const vuePid = getVueParentId(parentNode) + if (vuePid) { + ast.attr['vue-id'] = genCode( + t.binaryExpression( + '+', + t.binaryExpression( + '+', + t.parenthesizedExpression(vueId), + t.stringLiteral(',') + ), + t.parenthesizedExpression(vuePid) + ) + ) + } + } + initParent(ast.children, ast) + } +} + +function getVueParentId (parentNode) { + if (!parentNode) { + return + } + return parentNode.$vueId || getVueParentId(parentNode.parent) +} + +function traverseExpr (exprNode, state) { + if (t.isCallExpression(exprNode)) { + return traverseCallExpr(exprNode, state) + } else if (t.isConditionalExpression(exprNode)) { + return traverseConditionalExpr(exprNode, state) + } else if (t.isArrayExpression(exprNode)) { + return traverseArrayExpression(exprNode, state) + } else if (t.isIdentifier(exprNode) && exprNode.name === 'undefined') { + return { + type: 'block', + attr: {}, + children: [] + } + } else if (t.isUnaryExpression(exprNode) && exprNode.operator === 'void') { + return false + } else { + throw new Error(`暂不支持 ${getCode(exprNode)} 语法`) + } +} + +const traverses = { + _c: traverseCreateElement, + _t: traverseRenderSlot, + _l: traverseRenderList, + _u: traverseResolveScopedSlots, + _v: traverseCreateTextVNode, + _e: traverseCreateEmptyVNode, + _g: '暂不支持 v-on="$listeners" 用法', + _b: '暂不支持 v-bind="" 用法' +} + +function traverseCallExpr (callExprNode, state) { + const traverse = traverses[callExprNode.callee.name] + if (!traverse) { + throw new Error( + `CallExpression ${callExprNode.callee.name} is not yet implemented` + ) + } else if (typeof traverse === 'string') { + throw new Error(traverse) + } + + return traverse(callExprNode, state) +} + +function traverseConditionalExpr (conditionalExprNode, state) { + const prefix = state.options.platform.prefix + const ret = [{ + type: 'block', + attr: { + [prefix + 'if']: genCode(conditionalExprNode.test) + }, + children: normalizeChildren( + traverseExpr(conditionalExprNode.consequent, state) + ) + }] + if ( + !( + t.isCallExpression(conditionalExprNode.alternate) && + t.isIdentifier(conditionalExprNode.alternate.callee) && + conditionalExprNode.alternate.callee.name === '_e' + ) + ) { + // test?_c():_e() + ret.push({ + type: 'block', + attr: { + [prefix + 'else']: '' + }, + children: normalizeChildren( + traverseExpr(conditionalExprNode.alternate, state) + ) + }) + } + return ret +} + +function traverseCreateElement (callExprNode, state) { + const args = callExprNode.arguments + const tagNode = args[0] + if (!t.isStringLiteral(tagNode)) { + throw new Error(`暂不支持动态组件[${tagNode.name}]`) + } + + const node = { + type: tagNode.value, + attr: {}, + children: [] + } + + if (args.length < 2) { + return node + } + + const dataNodeOrChildNodes = args[1] + if (t.isObjectExpression(dataNodeOrChildNodes)) { + Object.assign(node.attr, traverseDataNode(dataNodeOrChildNodes, state, node)) + } else { + node.children = normalizeChildren(traverseExpr(dataNodeOrChildNodes, state)) + } + if (args.length < 3) { + return node + } + const childNodes = args[2] + if (!t.isNumericLiteral(childNodes)) { + if (node.children && node.children.length) { + node.children = node.children.concat(normalizeChildren(traverseExpr(childNodes, state))) + } else { + node.children = normalizeChildren(traverseExpr(childNodes, state)) + } + } + return node +} + +function traverseDataNode (dataNode, state, node) { + const ret = {} + const specialEvents = state.options.platform.specialEvents[node.type] || {} + const specialEventNames = Object.keys(specialEvents) + dataNode.properties.forEach(property => { + switch (property.key.name) { + case 'slot': + ret['slot'] = genCode(property.value) + break + case 'scopedSlots': // Vue 2.6 + property.value.$node = node + node.children = normalizeChildren(traverseExpr(property.value, state)) + break + case 'attrs': + case 'domProps': + case 'on': + case 'nativeOn': + property.value.properties.forEach(attrProperty => { + if (attrProperty.key.value === 'vue-id') { // initParent 时再处理 vue-id + node.$vueId = attrProperty.value + ret[attrProperty.key.value] = genCode(attrProperty.value) + } else { + if (specialEventNames.includes(attrProperty.key.value)) { + if (t.isIdentifier(attrProperty.value)) { + ret[specialEvents[attrProperty.key.value]] = attrProperty.value.name + } + } else { + ret[attrProperty.key.value] = genCode(attrProperty.value) + } + } + }) + break + case 'class': + case 'staticClass': + ret['class'] = genCode(property.value) + break + case 'style': + case 'staticStyle': + ret['style'] = genCode(property.value) + break + case 'directives': + property.value.elements.find(objectExpression => { + if (t.isObjectExpression(objectExpression)) { + const nameProperty = objectExpression.properties[0] + const isShowDir = + nameProperty && + nameProperty.key.name === 'name' && + t.isStringLiteral(nameProperty.value) && + nameProperty.value.value === 'show' + if (isShowDir) { + objectExpression.properties.find(valueProperty => { + const isValue = valueProperty.key.name === 'value' + if (isValue) { + ret['hidden'] = genCode(valueProperty.value, false, true) + } + return isValue + }) + } + return isShowDir + } + }) + break + } + }) + return ret +} + +function normalizeChildren (nodes) { + if (!Array.isArray(nodes)) { + nodes = [nodes] + } + return nodes.filter(node => { + if (typeof node === 'string' && !node.trim()) { + return false + } + return true + }) +} + +function traverseArrayExpression (arrayExprNodes, state) { + return arrayExprNodes.elements.reduce((nodes, exprNode) => { + return nodes.concat(traverseExpr(exprNode, state)) + }, []) +} + +function genSlotNode (slotName, slotNode, fallbackNodes, state) { + if (!fallbackNodes || t.isNullLiteral(fallbackNodes)) { + return slotNode + } + const prefix = state.options.platform.prefix + return [{ + type: 'block', + attr: { + [prefix + 'if']: '{{$slots.' + slotName + '}}' + }, + children: [slotNode] + }, { + type: 'block', + attr: { + [prefix + 'else']: '' + }, + children: normalizeChildren( + traverseExpr(fallbackNodes, state) + ) + }] +} + +function traverseRenderSlot (callExprNode, state) { + if (!t.isStringLiteral(callExprNode.arguments[0])) { + state.errors.add(`v-slot 不支持动态插槽名`) + return + } + + const slotName = callExprNode.arguments[0].value + + let deleteSlotName = false // 标记是否组件 slot 手动指定了 name="default" + if (callExprNode.arguments.length > 2) { // 作用域插槽 + const props = {} + callExprNode.arguments[2].properties.forEach(property => { + props[property.key.value] = genCode(property.value) + }) + deleteSlotName = props['SLOT_DEFAULT'] && Object.keys(props).length === 1 + if (!deleteSlotName) { + delete props['SLOT_DEFAULT'] + return genSlotNode( + slotName, + state.options.platform.createScopedSlots(slotName, props, state), + callExprNode.arguments[1], + state + ) + } + } + + const node = { + type: 'slot', + attr: { + name: slotName + }, + children: [] + } + + if (deleteSlotName) { + delete node.attr.name + } + + return genSlotNode(slotName, node, callExprNode.arguments[1], state) +} + +function traverseResolveScopedSlots (callExprNode, state) { + return callExprNode.arguments[0].elements.map(slotNode => { + let keyProperty = false + let fnProperty = false + let proxyProperty = false + slotNode.properties.forEach(property => { + switch (property.key.name) { + case 'key': + keyProperty = property + break + case 'fn': + fnProperty = property + break + case 'proxy': + proxyProperty = property + } + }) + const slotName = keyProperty.value.value + const returnExprNodes = fnProperty.value.body.body[0].argument + if (!proxyProperty) { + const resourcePath = state.options.resourcePath + const ownerName = path.basename(resourcePath, path.extname(resourcePath)) + + const parentNode = callExprNode.$node + const parentName = parentNode.type + + const paramExprNode = fnProperty.value.params[0] + return state.options.platform.resolveScopedSlots( + slotName, { + genCode, + generate, + ownerName, + parentName, + parentNode, + resourcePath, + paramExprNode, + returnExprNodes, + traverseExpr, + normalizeChildren + }, + state + ) + } + const node = { + type: 'view', + attr: { + slot: slotName + }, + children: normalizeChildren(traverseExpr(returnExprNodes, state)) + } + return node + }) +} + +function traverseRenderList (callExprNode, state) { + const params = callExprNode.arguments[1].params + const forItem = params.length > 0 ? params[0].name : 'item' + const forIndex = params.length > 1 ? params[1].name : '' + + const forReturnStatementArgument = + callExprNode.arguments[1].body.body[0].argument + + const forKey = traverseKey(forReturnStatementArgument, state) + + const prefix = state.options.platform.prefix + + const attr = { + [prefix + 'for']: genCode(callExprNode.arguments[0]), + [prefix + 'for-item']: forItem + } + + if (forIndex) { + attr[prefix + 'for-index'] = forIndex + } + + if (forKey) { + const key = getForKey(forKey, forIndex, state) + if (key) { + attr[prefix + 'key'] = key + } + } + + return { + type: 'block', + attr, + children: normalizeChildren(traverseExpr(forReturnStatementArgument, state)) + } +} + +function getLeftStringLiteral (expr) { + if (t.isBinaryExpression(expr) && !expr.$toString) { + return getLeftStringLiteral(expr.left) + } else if (t.isStringLiteral(expr)) { + return expr + } +} + +function trim (text, type) { + // TODO 保留换行符? + if (type === 'left') { + text = text.trimLeft() + } else if (type === 'right') { + text = text.trimRight() + } else { + text = text.trim() + } + return text +} + +function traverseCreateTextVNode (callExprNode, state) { + // trimStart|Left and trimEnd|End + const arg = callExprNode.arguments[0] + if (t.isStringLiteral(arg)) { + arg.value = trim(arg.value) + } else if (t.isBinaryExpression(arg) && !arg.$toString) { // 非_s() + // right + const right = arg.right + if (t.isStringLiteral(right)) { + right.value = trim(right.value, 'right') + } + // left + const left = getLeftStringLiteral(arg.left) + if (left && left.value) { + left.value = trim(left.value, 'left') + } + } + if ( + state.options.platform.name === 'mp-baidu' || + state.options.platform.name === 'mp-qq' + ) { + const code = genCode(arg, false, false, false) + if (code.indexOf('{{') === 0) { + if (state.options.platform.name === 'mp-qq') { // 似乎百度也可以走该逻辑, 为了稳定性,仅限 qq + return code.replace(/\\n/g, '\\\\n').replace(/\\t/g, '\\\\t') + } + return code.replace(/([^\\])\\n/g, '$1\\\\n').replace(/([^\\])\\t/g, '$1\\\\t') + } + return code + } + return genCode(arg, false, false, false).replace(/\\\\n/g, '\\n') +} + +function traverseCreateEmptyVNode (callExprNode, state) { + return '' +} diff --git a/packages/uni-template-compiler/lib/util.js b/packages/uni-template-compiler/lib/util.js new file mode 100644 index 000000000..c67000d74 --- /dev/null +++ b/packages/uni-template-compiler/lib/util.js @@ -0,0 +1,170 @@ +const t = require('@babel/types') +const babelTraverse = require('@babel/traverse').default +const babelGenerate = require('@babel/generator').default + +const { + METHOD_RENDER_LIST +} = require('./constants') + +function cached (fn) { + const cache = Object.create(null) + return function cachedFn (str) { + const hit = cache[str] + return hit || (cache[str] = fn(str)) + } +} +const customizeRE = /:/g +const camelizeRE = /-(\w)/g +const hyphenateRE = /\B([A-Z])/g + +const camelize = cached((str) => { + return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '') +}) + +function getCode (node) { + return babelGenerate(t.cloneDeep(node), { + compact: true, + jsescOption: { + quotes: 'single', + minimal: true + } + }).code +} + +function traverseKey (ast, state) { + let forKey = false + babelTraverse(ast, { + noScope: true, + ObjectProperty (path) { + if (forKey) { + return + } + if (path.node.key.name === 'key') { + forKey = path.node.value + path.stop() + } + }, + CallExpression (path) { + if (path.node.callee.name === METHOD_RENDER_LIST) { + path.stop() + } + } + }) + return forKey +} + +function wrapper (code, reverse = false) { + return reverse ? `{{!(${code})}}` : `{{${code}}}` +} + +function genCode (node, noWrapper = false, reverse = false, quotes = true) { + if (t.isStringLiteral(node)) { + return reverse ? `!(${node.value})` : node.value + } else if (t.isIdentifier(node)) { + return noWrapper ? node.name : wrapper(node.name, reverse) + } + let code = getCode(node) + if (quotes) { + code = code.replace(/"/g, '\'') + } + return noWrapper ? code : wrapper(code, reverse) +} + +function getForIndexIdentifier (id) { + return `__i${id}__` +} + +function getForKey (forKey, forIndex, state) { + if (forKey) { + if (t.isIdentifier(forKey)) { + if (forIndex !== forKey.name) { // 非 forIndex + return '*this' + } else { + // TODO + // state.tips.add(`非 h5 平台 v-for 循环不支持使用索引值 ${forIndex} 作为 key,详情参考:https://uniapp.dcloud.io/use?id=key`) + return forKey.name + } + } else if (t.isMemberExpression(forKey)) { + return forKey.property.name || forKey.property.value + } else { + state.tips.add(`非 h5 平台 :key 不支持表达式 ${getCode(forKey)},详情参考:https://uniapp.dcloud.io/use?id=key`) + } + } + return '' +} + +function processMemberProperty (node, state) { + if (node.computed) { + const property = node.property + if (t.isNumericLiteral(property)) { + node.property = t.identifier('__$n' + property.value) + } else if (!t.isStringLiteral(property)) { + if (!state.options.hasOwnProperty('__m__')) { + state.options.__m__ = 0 + state.options.replaceCodes = {} + } + const identifier = '__$m' + (state.options.__m__++) + '__' + state.options.replaceCodes[identifier] = `'+${genCode(property, true)}+'` + node.property = t.identifier(identifier) + } + node.computed = false + } +} + +function processMemberExpression (element, state) { + // item['order']=>item.order + if (t.isMemberExpression(element)) { + element = t.cloneDeep(element) + if (t.isStringLiteral(element.property)) { + element.computed = false + } + // item[itemIndex[0]] = item[__$0__] + // item[1]=item['1'] + processMemberProperty(element, state) + + babelTraverse(element, { + noScope: true, + MemberExpression (path) { + processMemberProperty(path.node, state) + } + }) + + babelTraverse(element, { + noScope: true, + MemberExpression (path) { + if (t.isStringLiteral(path.node.property)) { + path.node.computed = false + } + }, + StringLiteral (path) { + path.replaceWith(t.identifier(path.node.value)) + } + }) + } + return element +} + +module.exports = { + genCode, + getCode, + camelize, + customize: cached((str) => { + return camelize(str.replace(customizeRE, '-')) + }), + capitalize: cached(str => { + return str.charAt(0).toUpperCase() + str.slice(1) + }), + hyphenate: cached((str) => { + return str.replace(hyphenateRE, '-$1').toLowerCase() + }), + getForKey, + traverseKey, + getComponentName: cached((str) => { + if (str.indexOf('wx-') === 0) { + return str.replace('wx-', 'weixin-') + } + return str + }), + processMemberExpression, + getForIndexIdentifier +} diff --git a/packages/uni-template-compiler/package.json b/packages/uni-template-compiler/package.json new file mode 100644 index 000000000..05e774669 --- /dev/null +++ b/packages/uni-template-compiler/package.json @@ -0,0 +1,21 @@ +{ + "name": "@dcloudio/uni-template-compiler", + "version": "0.9.181", + "description": "uni-template-compiler", + "main": "lib/index.js", + "files": [ + "lib" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "fxy060608", + "license": "Apache-2.0", + "dependencies": { + "@babel/parser": "^7.3.3", + "@babel/traverse": "^7.3.3", + "@babel/types": "^7.3.3", + "vue-template-compiler": "^2.6.10" + }, + "gitHead": "a804605136db60bee33145e1463e413afb7b4c1e" +} diff --git a/packages/vue-cli-plugin-hbuilderx/LICENSE b/packages/vue-cli-plugin-hbuilderx/LICENSE new file mode 100755 index 000000000..7a4a3ea24 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/packages/vue-cli-plugin-hbuilderx/README.md b/packages/vue-cli-plugin-hbuilderx/README.md new file mode 100644 index 000000000..f09c474fa --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/README.md @@ -0,0 +1,3 @@ +# @dcloudio/vue-cli-plugin-hbuilderx + +> HBuilderX plugin for vue-cli 3 \ No newline at end of file diff --git a/packages/vue-cli-plugin-hbuilderx/build/css-loader.conf.js b/packages/vue-cli-plugin-hbuilderx/build/css-loader.conf.js new file mode 100644 index 000000000..b2a6df5eb --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/build/css-loader.conf.js @@ -0,0 +1,87 @@ +const { + // jsPreprocessOptions, + nvueCssPreprocessOptions + // htmlPreprocessOptions +} = require('@dcloudio/uni-cli-shared') + +const nvueStyleLoader = { + loader: '@dcloudio/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/style' +} + +const preprocessLoader = { + loader: '@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader', + options: nvueCssPreprocessOptions +} + +const postcssLoader = { + loader: 'postcss-loader', + options: { + sourceMap: false, + parser: require('postcss-comment'), + plugins: [ + require('postcss-import'), + require('@dcloudio/vue-cli-plugin-uni/packages/postcss') + ] + } +} + +const sassLoader = { + loader: 'sass-loader', + options: { + sourceMap: false, + data: '' + } +} + +const lessLoader = { + loader: 'less-loader', + options: { + sourceMap: false + } +} + +const stylusLoader = { + loader: 'stylus-loader', + options: { + sourceMap: false, + preferPathResolver: 'webpack' + } +} + +function createOneOf (preLoader) { + const use = [ + nvueStyleLoader, + preprocessLoader + ] + use.push(postcssLoader) + if (preLoader) { + use.push(preLoader) + } + use.push(preprocessLoader) + + return [{ + resourceQuery: /\?vue/, + use + }, + { + use + } + ] +} + +module.exports = [{ + test: /\.css$/, + oneOf: createOneOf() +}, { + test: /\.scss$/, + oneOf: createOneOf(sassLoader) +}, { + test: /\.sass$/, + oneOf: createOneOf(sassLoader) +}, { + test: /\.less$/, + oneOf: createOneOf(lessLoader) +}, { + test: /\.styl(us)?$/, + oneOf: createOneOf(stylusLoader) +}] diff --git a/packages/vue-cli-plugin-hbuilderx/build/utils.js b/packages/vue-cli-plugin-hbuilderx/build/utils.js new file mode 100644 index 000000000..f3e33d709 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/build/utils.js @@ -0,0 +1,71 @@ +function resolve (module) { + try { + return require.resolve(module) + } catch (e) {} + return module +} + +exports.cssLoaders = function (options) { + options = options || {} + const cssLoader = { + loader: resolve('css-loader'), + options: { + sourceMap: options.sourceMap + } + } + + const postcssLoader = { + loader: resolve('postcss-loader'), + options: { + sourceMap: options.sourceMap + } + } + + // generate loader string to be used with extract text plugin + const generateLoaders = (loader, loaderOptions) => { + let loaders = options.useVue ? [cssLoader] : [] + if (options.usePostCSS) { + loaders.push(postcssLoader) + } + if (loader) { + loaders.push({ + loader: resolve(loader + '-loader'), + options: Object.assign({}, loaderOptions, { + sourceMap: options.sourceMap + }) + }) + } + if (options.useVue) { + return [resolve('vue-style-loader')].concat(loaders) + } else { + return loaders + } + } + + // https://vue-loader.vuejs.org/en/configurations/extract-css.html + return { + less: generateLoaders('less'), + sass: generateLoaders('sass', { + indentedSyntax: true + }), + scss: generateLoaders('sass'), + stylus: generateLoaders('stylus'), + styl: generateLoaders('stylus') + } +} + +// Generate loaders for standalone style files (outside of .vue) +exports.styleLoaders = function (options) { + const output = [] + const loaders = exports.cssLoaders(options) + + for (const extension in loaders) { + const loader = loaders[extension] + output.push({ + test: new RegExp('\\.' + extension + '$'), + use: loader + }) + } + + return output +} diff --git a/packages/vue-cli-plugin-hbuilderx/build/vue-loader.conf.js b/packages/vue-cli-plugin-hbuilderx/build/vue-loader.conf.js new file mode 100644 index 000000000..8f623da8a --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/build/vue-loader.conf.js @@ -0,0 +1,74 @@ +const TAGS = [ + 'text', + 'image', + 'input', + 'textarea', + 'video', + 'web-view', + // 'switch', + 'slider' +] + +const modules = [] + +const deprecated = { + events: { + 'tap': 'click' + } +} + +if (process.env.UNI_USING_NVUE_COMPILER) { + modules.push({ + postTransformNode (el) { + if (TAGS.includes(el.tag)) { + el.tag = 'u-' + el.tag + } + if (el.events) { + const { + events: eventsMap + } = deprecated + Object.keys(el.events).forEach(name => { + // 过时事件类型转换 + if (eventsMap[name]) { + el.events[eventsMap[name]] = el.events[name] + delete el.events[name] + name = eventsMap[name] + } + }) + } + if (el.tag === 'u-video') { + if ( + Array.isArray(el.children) && + el.children.length && + el.children[0].tag !== 'u-scalable' + ) { + el.children = [{ + type: 1, + tag: 'u-scalable', + attrsList: [], + attrsMap: { + style: 'position: absolute;left: 0;right: 0;top: 0;bottom: 0;' + }, + rawAttrsMap: { + style: { + name: 'style', + value: 'position: absolute;left: 0;right: 0;top: 0;bottom: 0;' + } + }, + plain: false, + staticStyle: '{position:"absolute",left:"0",right:"0",top:"0",bottom:"0"}', + children: el.children + }] + } + } + } + }) +} + +module.exports = { + preserveWhitespace: false, + compiler: require('weex-template-compiler'), + compilerOptions: { + modules + } +} diff --git a/packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js b/packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js new file mode 100644 index 000000000..c4cbcc83b --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js @@ -0,0 +1,280 @@ +const path = require('path') +const webpack = require('webpack') +const VueLoaderPlugin = require('vue-loader/lib/plugin') +const CopyWebpackPlugin = require('copy-webpack-plugin') + +const { + done +} = require('@vue/cli-shared-utils') + +const { + getNVueMainEntry, + nvueJsPreprocessOptions, + nvueHtmlPreprocessOptions, + devtoolModuleFilenameTemplate +} = require('@dcloudio/uni-cli-shared') + +const WebpackErrorsPlugin = require('@dcloudio/vue-cli-plugin-uni/packages/webpack-errors-plugin') + +const onErrors = require('@dcloudio/vue-cli-plugin-uni/util/on-errors') + +const cssLoaders = require('./css-loader.conf') +const vueLoaderOptions = require('./vue-loader.conf') + +const jsPreprocessorLoader = { + loader: '@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader', + options: nvueJsPreprocessOptions +} + +const htmlPreprocessorLoader = { + loader: '@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader', + options: nvueHtmlPreprocessOptions +} + +const uniPath = process.env.UNI_USING_V8 + ? '../packages/uni-app-plus-nvue-v8/dist/index.js' + : '../packages/uni-app-plus-nvue/dist/index.js' + +const provide = {} + +if (!process.env.UNI_USING_NATIVE) { + provide['uni'] = [path.resolve(__dirname, uniPath), 'default'] +} + +if (process.env.UNI_USING_V8) { + provide['plus'] = [path.resolve(__dirname, uniPath), 'weexPlus'] +} + +if ( + process.env.UNI_PLATFORM === 'app-plus' && + process.env.UNI_USING_V8 +) { + provide['__f__'] = [require.resolve('@dcloudio/vue-cli-plugin-uni/lib/format-log.js'), 'default'] +} + +const plugins = [ + new VueLoaderPlugin(), + new webpack.DefinePlugin({ + 'process.env': { + 'NODE_ENV': JSON.stringify(process.env.NODE_ENV), + 'VUE_APP_PLATFORM': JSON.stringify(process.env.UNI_PLATFORM) + } + }), + new webpack.BannerPlugin({ + banner: '"use weex:vue";', + raw: true, + exclude: 'Vue' + }), + new webpack.ProvidePlugin(provide), + new WebpackErrorsPlugin({ + onErrors + }), + function (compiler) { + compiler.hooks.done.tapPromise('WebpackAppPlusNVuePlugin', compilation => { + return new Promise((resolve, reject) => { + if (isFirst) { + isFirst = false + } else { + if (process.env.NODE_ENV === 'development') { + done(`Build complete. Watching for changes...`) + } else { + done(`Build complete. `) + } + } + resolve() + }) + }) + } +] + +const excludeModuleReg = /node_modules(?!(\/|\\).*(weex).*)/ + +let isFirst = !process.env.UNI_USING_NATIVE + +const rules = [{ + test: path.resolve(process.env.UNI_INPUT_DIR, 'pages.json'), + use: [{ + loader: '@dcloudio/webpack-uni-pages-loader' + }], + type: 'javascript/auto' +}, { + test: path.resolve(process.env.UNI_INPUT_DIR, getNVueMainEntry()), + use: [{ + loader: '@dcloudio/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/main' + }] +}, { + test: /\.js$/, + use: [{ + loader: 'babel-loader', + options: { + babelrc: false + } + }, + jsPreprocessorLoader + ], + exclude: excludeModuleReg +}, +{ + test: /\.nvue(\?[^?]+)?$/, + use: [{ + loader: 'vue-loader', + options: vueLoaderOptions + }], + exclude: excludeModuleReg +}, +{ + test: /\.vue(\?[^?]+)?$/, + use: [{ + loader: 'vue-loader', + options: vueLoaderOptions + }], + exclude: excludeModuleReg +}, +{ + test: /\.pug$/, + oneOf: [{ + resourceQuery: /vue/, + use: [{ + loader: 'pug-plain-loader' + }] + }, + { + use: [{ + loader: 'raw-loader' + }, { + loader: 'pug-plain-loader' + }] + } + ] +}, +{ + resourceQuery: /vue&type=template/, + use: [htmlPreprocessorLoader] +} +].concat(cssLoaders) + +if (process.env.UNI_USING_NVUE_COMPILER) { + rules.unshift({ + resourceQuery: function (query) { + return query.indexOf('vue&type=template') !== -1 && query.indexOf('mpType=page') !== -1 + }, + use: [{ + loader: '@dcloudio/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/template' + }] + }) +} +if (process.env.UNI_USING_NATIVE) { + plugins.push(new CopyWebpackPlugin([{ + from: path.resolve(process.env.UNI_INPUT_DIR, 'static'), + to: 'static' + }, { + from: path.resolve( + process.env.UNI_HBUILDERX_PLUGINS, + 'weapp-tools/template/v8' + ), + to: process.env.UNI_OUTPUT_DIR + }, { + from: path.resolve( + process.env.UNI_HBUILDERX_PLUGINS, + 'weapp-tools/template/common' + ), + to: process.env.UNI_OUTPUT_DIR, + ignore: [ + '*.js', + '*.json', + '__uniapppicker.html', + '__uniappview.html' + ] + }])) +} + +module.exports = function (entry) { + return { + target: 'node', // 激活 vue-loader 的 isServer 逻辑 + mode: 'development', // process.env.NODE_ENV, + devtool: process.env.NODE_ENV === 'development' ? 'inline-source-map' : false, + watch: process.env.NODE_ENV === 'development', + entry, + externals: { + 'vue': 'Vue' + }, + optimization: { + namedModules: false + }, + output: { + path: process.env.UNI_OUTPUT_DIR, + filename: '[name].js', + devtoolModuleFilenameTemplate + }, + resolve: { + extensions: ['.js', '.nvue', '.vue', '.json'], + alias: { + '@': process.env.UNI_INPUT_DIR, + 'uni-pages': path.resolve(process.env.UNI_INPUT_DIR, 'pages.json'), + 'uni-stat-config': path.resolve(process.env.UNI_INPUT_DIR, 'pages.json') + + '?' + + JSON.stringify({ + type: 'stat' + }) + }, + modules: [ + 'node_modules', + path.resolve(process.env.UNI_INPUT_DIR, 'node_modules') + ] + }, + resolveLoader: { + alias: { + 'babel-loader': require.resolve('babel-loader') + } + }, + module: { + rules + }, + plugins, + stats: { + reasons: true, + errorDetails: true + }, + node: { + global: false, + Buffer: false, + __filename: false, + __dirname: false, + setImmediate: false, + clearImmediate: false, + assert: false, + buffer: false, + child_process: false, + cluster: false, + console: false, + constants: false, + crypto: false, + dgram: false, + dns: false, + domain: false, + events: false, + fs: false, + http: false, + https: false, + module: false, + net: false, + os: false, + path: false, + process: false, + punycode: false, + querystring: false, + readline: false, + repl: false, + stream: false, + string_decoder: false, + sys: false, + timers: false, + tls: false, + tty: false, + url: false, + util: false, + vm: false, + zlib: false + } + } +} diff --git a/packages/vue-cli-plugin-hbuilderx/fork-ts-checker-webpack-plugin.fake.js b/packages/vue-cli-plugin-hbuilderx/fork-ts-checker-webpack-plugin.fake.js new file mode 100644 index 000000000..1c7bd2b6b --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/fork-ts-checker-webpack-plugin.fake.js @@ -0,0 +1,11 @@ +/** + * FakeForkTsCheckerWebpackPlugin + * Runs typescript type checker and linter (tslint) on separate process. + * This speed-ups build a lot. + * + * Options description in README.md + */ +class ForkTsCheckerWebpackPlugin { + apply (compiler) {} +} +module.exports = ForkTsCheckerWebpackPlugin diff --git a/packages/vue-cli-plugin-hbuilderx/generator.js b/packages/vue-cli-plugin-hbuilderx/generator.js new file mode 100644 index 000000000..174b208aa --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/generator.js @@ -0,0 +1,10 @@ +module.exports = (api, options, rootOptions) => { + api.extendPackage(pkg => { + return { + scripts: { + 'dev:app-plus': 'cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch', + 'build:app-plus': 'cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build' + } + } + }) +} diff --git a/packages/vue-cli-plugin-hbuilderx/index.js b/packages/vue-cli-plugin-hbuilderx/index.js new file mode 100644 index 000000000..4b7110b14 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/index.js @@ -0,0 +1,45 @@ +const fs = require('fs') +const path = require('path') + +process.env.UNI_CLI_CONTEXT = path.resolve(__dirname, '../../../') + +process.env.UNI_HBUILDERX_PLUGINS = process.env.UNI_HBUILDERX_PLUGINS || path.resolve(__dirname, '../../../../') + +require('./module-alias') + +const { + devtoolModuleFilenameTemplate +} = require('@dcloudio/uni-cli-shared') + +module.exports = (api, options) => { // 仅处理 app-plus 相关逻辑 + if (process.env.UNI_PLATFORM !== 'app-plus') { + return + } + + if (!fs.existsSync(path.resolve(process.env.UNI_HBUILDERX_PLUGINS, 'weapp-tools/lib/index.js'))) { + console.error('请使用 HBuilderX 编译运行至 app-plus 平台') + process.exit(0) + } + + const plugins = [] + + const output = {} + const WebpackAppPlusPlugin = require('./packages/webpack-app-plus-plugin') + + plugins.push(new WebpackAppPlusPlugin()) + + // sourcemap 输出相对路径 + output.devtoolModuleFilenameTemplate = devtoolModuleFilenameTemplate + + api.configureWebpack(webpackConfig => { + return { + output, + plugins + } + }) +} + +module.exports.defaultModes = { + serve: 'development', + build: 'production' +} diff --git a/packages/vue-cli-plugin-hbuilderx/logo.png b/packages/vue-cli-plugin-hbuilderx/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..bbed27388d7f889c219569739a73b2cbd26ac463 GIT binary patch literal 1453 zcmV;e1ycHnP)NTC~1H!WId#TG>rSH-nRGIbdroF1N+I7cOyHjTJHPMwJzz5`zG6O&*?O~81TQUTY0t$tTH{Txgf|nrdWnf|mCB_Ne`WC=4FccBZ zaHly=bngFa(n2TUS!F!Bj14PE50i)#$E?UG(72!x=H8Kv8ixbD*eIv!>76W(&t>e zaD_LYc#T?Pje59&5It1tCL&2YuXYmw2z7)nJRY4r!E|bh<5S0&a5E6q*jD`vtL)G2 z;rP^10FLAjB6NgQZcEOVt&1iiNfzmwB^=?Iwfhb905|MS{rmqKrm{9wF(R+dx&^W@`jEFw&)QO^L1CvFn+thBS zu*!f#Z6hg0%ETuzYuZH!2ZVzw98`bT*aD}uo@6U@;yxn~iHJ|)c#;66HO;UJ%?hQU zf>fbVDB9G-BKmRA^& zh_VrIud&8^KfKT4?Vn)Z5s((a?zpgAVDa>;oIi91&r2jyA}$4qFcC?-%s||Z&!uNs z%z4aa_MlW?dIcd|O1XcS@+WQXB1J4lQl|84B;pA{%AbJr6tk&3p+)+2g+nQw$MrKd zHPKiM!LE)pfXtu;8qivSR!FU^(r^5t0=r_kh6NE*KVjvcJB$@9T+2kHNuPk%uz9W3 zXw*=%Jb}~--6{`Ct3icgnK4)dy5dA>Nm{rZ&L0F|+Mi_7&46rfgNp#!U_LWL&W*ix zE;ECNirsW8j8z@XL?m4naUG9HOKz<#P;8c2SYM9aLE2m7yfk?)OG5@!!WvR*JYhe4kXqq89(gZI#`Reb zYt*9#LO9(@Jr8^ZP`G$=pgdF7>gl&!;UJadPUUX`8Q?n}bJ;o4Zo1XNoBd0p$+#)X z!3KqmC6rd=Q+a06)A94I?qw_iHbi8%Af**T2=-<7f)MD|97?LliUh=0<3L4Zy$ln6 z7HG@q2?eY6#Fj{3K?=RSnCL>AveKG_#I0HNl zJPGU{O3nVb1$;|P;CtfwRmRe-?Z)SEE8if_B0mBj0aL&!Vq(t#kGJHRib*@)t^zk& z%3lM1CqDg#t@53)CDMto^{D^_;41Nbc4?_w9b7!Uph5kMJuShP6u00000NkvXX Hu0mjfC$6P* literal 0 HcmV?d00001 diff --git a/packages/vue-cli-plugin-hbuilderx/module-alias.js b/packages/vue-cli-plugin-hbuilderx/module-alias.js new file mode 100644 index 000000000..d9c0a2333 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/module-alias.js @@ -0,0 +1,32 @@ +const path = require('path') +const moduleAlias = require('module-alias') + +const { + hasModule, + isInHBuilderX +} = require('@dcloudio/uni-cli-shared') + +// override +moduleAlias.addAlias('weex-styler', path.resolve(__dirname, 'packages/weex-styler')) +moduleAlias.addAlias('weex-template-compiler', path.resolve(__dirname, 'packages/weex-template-compiler')) +moduleAlias.addAlias('./codegen/styleInjection', path.resolve(__dirname, + 'packages/webpack-uni-nvue-loader/lib/styleInjection')) + +if (isInHBuilderX) { + moduleAlias.addAlias('typescript', path.resolve(process.env.UNI_HBUILDERX_PLUGINS, + 'compile-typescript/node_modules/typescript')) + moduleAlias.addAlias('less', path.resolve(process.env.UNI_HBUILDERX_PLUGINS, + 'compile-less/node_modules/less')) + moduleAlias.addAlias('node-sass', path.resolve(process.env.UNI_HBUILDERX_PLUGINS, + 'compile-node-sass/node_modules/node-sass-china')) + moduleAlias.addAlias('stylus', path.resolve(process.env.UNI_HBUILDERX_PLUGINS, + 'compile-stylus/node_modules/stylus')) + moduleAlias.addAlias('pug', path.resolve(process.env.UNI_HBUILDERX_PLUGINS, + 'compile-pug-cli/node_modules/pug')) + + if (!hasModule('typescript')) { // 因为 cli-plugin-typescript 会直接读取typescript/package.json,故,如果未安装 typescript,则先设置一个假的 + moduleAlias.addAlias('typescript/package.json', path.resolve(__dirname, 'typescript.json')) + moduleAlias.addAlias('fork-ts-checker-webpack-plugin', path.resolve(__dirname, + 'fork-ts-checker-webpack-plugin.fake.js')) + } +} diff --git a/packages/vue-cli-plugin-hbuilderx/package.json b/packages/vue-cli-plugin-hbuilderx/package.json new file mode 100644 index 000000000..771674a31 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/package.json @@ -0,0 +1,16 @@ +{ + "name": "@dcloudio/vue-cli-plugin-hbuilderx", + "version": "1.0.134", + "description": "HBuilderX plugin for vue-cli 3", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "fxy060608", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^5.2.1", + "escodegen": "^1.8.1", + "css": "~2.2.1" + } +} diff --git a/packages/vue-cli-plugin-hbuilderx/packages/babel-plugin-console/LICENSE b/packages/vue-cli-plugin-hbuilderx/packages/babel-plugin-console/LICENSE new file mode 100755 index 000000000..7a4a3ea24 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/babel-plugin-console/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/packages/vue-cli-plugin-hbuilderx/packages/babel-plugin-console/dist/index.js b/packages/vue-cli-plugin-hbuilderx/packages/babel-plugin-console/dist/index.js new file mode 100644 index 000000000..4a42087d7 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/babel-plugin-console/dist/index.js @@ -0,0 +1,52 @@ +const METHODS = ['error', 'warn', 'info', 'log', 'debug'] +const FORMAT_LOG = '__f__' +module.exports = function({ + types: t +}) { + + return { + visitor: { + CallExpression(path, state) { + + const opts = state.opts + + if (path.node.callee.object && + path.node.callee.object.name === 'console' && + METHODS.includes(path.node.callee.property.name)) { + if (path.node.callee.property.name === 'debug') { //console.debug=>console.log + path.node.callee.property.name = 'log' + } + + let file = state.file.opts.filename + if (file) { + if (opts && opts.file) { + file = opts.file(file) + } + if (file) { + const args = path.node.arguments + const arg = args[0] + if ( + arg && + arg.type === 'CallExpression' && + arg.callee.name === FORMAT_LOG + ) { + return + } + args.push({ + type: 'StringLiteral', + value: ` at ${file}:${path.node.loc.start.line}` + }) + path.node.arguments = [ + t.callExpression( + t.identifier(FORMAT_LOG), + args + ) + ] + } + } + } + + } + } + } +} diff --git a/packages/vue-cli-plugin-hbuilderx/packages/babel-plugin-console/package.json b/packages/vue-cli-plugin-hbuilderx/packages/babel-plugin-console/package.json new file mode 100644 index 000000000..e81b48538 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/babel-plugin-console/package.json @@ -0,0 +1,11 @@ +{ + "name": "@dcloudio/babel-plugin-console", + "version": "0.0.1", + "description": "uni-app babel-plugin-console", + "main": "dist/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "fxy060608", + "license": "Apache-2.0" +} diff --git a/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue-v8/LICENSE b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue-v8/LICENSE new file mode 100755 index 000000000..7a4a3ea24 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue-v8/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue-v8/dist/index.js b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue-v8/dist/index.js new file mode 100644 index 000000000..36ef212d5 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue-v8/dist/index.js @@ -0,0 +1,781 @@ +function initUni() { + + var isFn = function isFn(v) { + return typeof v === 'function'; + }; + + var handlePromise = function handlePromise(promise) { + return promise.then(function(data) { + return [null, data]; + }).catch(function(err) { + return [err]; + }); + }; + + var REGEX = /^\$|^on|^create|Sync$|Manager$|^pause/; + var API_NORMAL_LIST = ['os', 'getCurrentSubNVue', 'getSubNVueById', 'stopRecord', 'stopVoice', + 'stopBackgroundAudio', 'stopPullDownRefresh', 'hideKeyboard', 'hideToast', 'hideLoading', + 'showNavigationBarLoading', 'hideNavigationBarLoading', 'canIUse', 'navigateBack', 'closeSocket', + 'pageScrollTo', 'drawCanvas' + ]; + + var shouldPromise = function shouldPromise(name) { + if (REGEX.test(name) && name !== 'createBLEConnection') { + return false; + } + if (~API_NORMAL_LIST.indexOf(name)) { + return false; + } + return true; + }; + + var promisify = function promisify(api) { + return function() { + for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + params[_key - 1] = arguments[_key]; + } + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + if (isFn(options.success) || isFn(options.fail) || isFn(options.complete)) { + return api.apply(undefined, [options].concat(params)); + } + return handlePromise(new Promise(function(resolve, reject) { + api.apply(undefined, [Object.assign({}, options, { + success: resolve, + fail: reject + })].concat(params)); + /* eslint-disable no-extend-native */ + Promise.prototype.finally = function(callback) { + var promise = this.constructor; + return this.then(function(value) { + return promise.resolve(callback()).then(function() { + return value; + }); + }, function(reason) { + return promise.resolve(callback()).then(function() { + throw reason; + }); + }); + }; + })); + }; + }; + + var onMessageCallbacks = []; + + var origin = void 0; + + function onSubNVueMessage(data) { + onMessageCallbacks.forEach(function(callback) { + return callback({ + origin: origin, + data: data + }); + }); + } + + var webviewId = weexPlus.webview.currentWebview().id; + + var channel = new BroadcastChannel('UNI-APP-SUBNVUE'); + channel.onmessage = function(event) { + if (event.data.to === webviewId) { + onSubNVueMessage(event.data.data); + } + }; + + function wrapper(webview) { + webview.$processed = true; + + var currentWebviewId = weexPlus.webview.currentWebview().id; + var isPopupNVue = currentWebviewId === webview.id; + + var hostNVueId = webview.__uniapp_origin_type === 'uniNView' && webview.__uniapp_origin_id; + var popupNVueId = webview.id; + + webview.postMessage = function(data) { + if (hostNVueId) { + channel.postMessage({ + data: data, + to: isPopupNVue ? hostNVueId : popupNVueId + }); + } else { + postMessage({ + type: 'UniAppSubNVue', + data: data + }); + } + }; + webview.onMessage = function(callback) { + onMessageCallbacks.push(callback); + }; + + if (!webview.__uniapp_mask_id) { + return; + } + origin = webview.__uniapp_host; + + var maskColor = webview.__uniapp_mask; + + var maskWebview = weexPlus.webview.getWebviewById(webview.__uniapp_mask_id); + maskWebview = maskWebview.parent() || maskWebview;//再次检测父 + var oldShow = webview.show; + var oldHide = webview.hide; + var oldClose = webview.close; + + var showMask = function showMask() { + maskWebview.setStyle({ + mask: maskColor + }); + }; + var closeMask = function closeMask() { + maskWebview.setStyle({ + mask: 'none' + }); + }; + webview.show = function() { + showMask(); + + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return oldShow.apply(webview, args); + }; + webview.hide = function() { + closeMask(); + + for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + return oldHide.apply(webview, args); + }; + webview.close = function() { + closeMask(); + + for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; + } + + return oldClose.apply(webview, args); + }; + } + + function getSubNVueById(id) { + var webview = weexPlus.webview.getWebviewById(id); + if (webview && !webview.$processed) { + wrapper(webview); + } + return webview; + } + + function getCurrentSubNVue() { + return getSubNVueById(weexPlus.webview.currentWebview().id); + } + + var plus = weex.requireModule('plus'); + var globalEvent = weex.requireModule('globalEvent'); + + var id = 0; + var callbacks = {}; + + var UNIAPP_SERVICE_NVUE_ID = '__uniapp__service'; + + globalEvent.addEventListener('plusMessage', function(e) { + if (e.data.type === 'UniAppJsApi') { + invoke(e.data.id, e.data.data); + } else if (e.data.type === 'UniAppSubNVue') { + onSubNVueMessage(e.data.data, e.data.options); + } else if (e.data.type === 'onNavigationBarButtonTap') { + if (typeof onNavigationBarButtonTapCallback === 'function') { + onNavigationBarButtonTapCallback(e.data.data); + } + } else if (e.data.type === 'onNavigationBarSearchInputChanged') { + if (typeof onNavigationBarSearchInputChangedCallback === 'function') { + onNavigationBarSearchInputChangedCallback(e.data.data); + } + } else if (e.data.type === 'onNavigationBarSearchInputConfirmed') { + if (typeof onNavigationBarSearchInputConfirmedCallback === 'function') { + onNavigationBarSearchInputConfirmedCallback(e.data.data); + } + } else if (e.data.type === 'onNavigationBarSearchInputClicked') { + if (typeof onNavigationBarSearchInputClickedCallback === 'function') { + onNavigationBarSearchInputClickedCallback(e.data.data); + } + } + }); + + var createCallback = function createCallback(args, type) { + var callback = function callback(res) { + if (isFn(args)) { + args(res); + } else if (args) { + if (~res.errMsg.indexOf(':ok')) { + isFn(args.success) && args.success(res); + } else if (~res.errMsg.indexOf(':fail')) { + isFn(args.fail) && args.fail(res); + } + isFn(args.complete) && args.complete(res); + } + }; + if (isFn(args) || args && isFn(args.callback)) { + callback.keepAlive = true; + } + return callback; + }; + + var invoke = function invoke(callbackId, data) { + var callback = callbacks[callbackId]; + if (callback) { + callback(data); + if (!callback.keepAlive) { + delete callbacks[callbackId]; + } + } else { + console.error('callback[' + callbackId + '] is undefined'); + } + }; + + var publish = function publish(_ref) { + var id = _ref.id, + type = _ref.type, + params = _ref.params; + + callbacks[id] = createCallback(params, type); + plus.postMessage({ + id: id, + type: type, + params: params + }, UNIAPP_SERVICE_NVUE_ID); + }; + + function postMessage(data) { + plus.postMessage(data, UNIAPP_SERVICE_NVUE_ID); + } + + var createPublish = function createPublish(name) { + return function(args) { + publish({ + id: id++, + type: name, + params: args + }); + }; + }; + + var onNavigationBarButtonTapCallback = void 0; + var onNavigationBarSearchInputChangedCallback = void 0; + var onNavigationBarSearchInputConfirmedCallback = void 0; + var onNavigationBarSearchInputClickedCallback = void 0; + + function onNavigationBarButtonTap(callback) { + onNavigationBarButtonTapCallback = callback; + } + + function onNavigationBarSearchInputChanged(callback) { + onNavigationBarSearchInputChangedCallback = callback; + } + + function onNavigationBarSearchInputConfirmed(callback) { + onNavigationBarSearchInputConfirmedCallback = callback; + } + + function onNavigationBarSearchInputClicked(callback) { + onNavigationBarSearchInputClickedCallback = callback; + } + + function requireNativePlugin(pluginName) { + return weex.requireModule(pluginName); + } + + var dom = weex.requireModule('dom'); + + function loadFontFace(_ref) { + var family = _ref.family, + source = _ref.source, + desc = _ref.desc, + success = _ref.success, + fail = _ref.fail, + complete = _ref.complete; + + dom.addRule('fontFace', { + fontFamily: family, + src: source.replace(/"/g, '\'') + }); + var res = { + errMsg: 'loadFontFace:ok', + status: 'loaded' + }; + isFn(success) && success(res); + isFn(complete) && complete(res); + } + + var globalEvent$1 = weex.requireModule('globalEvent'); + + var callbacks$1 = []; + + globalEvent$1.addEventListener('plusMessage', function(e) { + if (e.data.type === 'UniAppReady') { + ready.isUniAppReady = true; + if (callbacks$1.length) { + callbacks$1.forEach(function(callback) { + return callback(); + }); + callbacks$1 = []; + } + } + }); + + function ready(callback) { + if (typeof callback === 'function') { + if (this.isUniAppReady) { + callback(); + } else { + callbacks$1.push(callback); + } + } + } + + var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function(obj) { + return typeof obj; + } : function(obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? + "symbol" : typeof obj; + }; + + var stream = weex.requireModule('stream'); + + // let requestTaskId = 0 + + var METHOD_GET = 'GET'; + var METHOD_POST = 'POST'; + var CONTENT_TYPE_JSON = 'application/json'; + var CONTENT_TYPE_FORM = 'application/x-www-form-urlencoded'; + + var serialize = function serialize(data) { + var method = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : METHOD_GET; + var contentType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : CONTENT_TYPE_FORM; + + if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') { + if (method.toUpperCase() === METHOD_POST && contentType.toLowerCase() === CONTENT_TYPE_JSON) { + return JSON.stringify(data); + } else { + return Object.keys(data).map(function(key) { + return encodeURIComponent(key) + '=' + encodeURIComponent(data[key]); + }).join('&'); + } + } + return data; + }; + + function request(_ref) { + var url = _ref.url, + data = _ref.data, + header = _ref.header, + _ref$method = _ref.method, + method = _ref$method === undefined ? 'GET' : _ref$method, + _ref$dataType = _ref.dataType, + dataType = _ref$dataType === undefined ? 'json' : _ref$dataType, + responseType = _ref.responseType, + success = _ref.success, + fail = _ref.fail, + complete = _ref.complete; + + // requestTaskId++ + var aborted = false; + + var hasContentType = false; + var headers = {}; + if (header) { + for (var name in header) { + if (!hasContentType && name.toLowerCase() === 'content-type') { + hasContentType = true; + headers['Content-Type'] = header[name]; + } else { + headers[name] = header[name]; + } + } + } + if (method === METHOD_GET && data) { + url = url + (~url.indexOf('?') ? url.substr(-1) === '&' || url.substr(-1) === '?' ? '' : '&' : '?') + + serialize(data); + } + stream.fetch({ + url: url, + method: method, + headers: headers, + type: dataType === 'json' ? 'json' : 'text', + body: method !== METHOD_GET ? serialize(data, method, headers['Content-Type']) : '' + }, function(_ref2) { + var status = _ref2.status, + ok = _ref2.ok, + statusText = _ref2.statusText, + data = _ref2.data, + headers = _ref2.headers; + + var ret = {}; + if (!status || status === -1 || aborted) { + ret.errMsg = 'request:fail'; + isFn(fail) && fail(ret); + } else { + ret.data = data; + ret.statusCode = status; + ret.header = headers; + isFn(success) && success(ret); + } + isFn(complete) && complete(ret); + }); + return { + abort: function abort() { + aborted = true; + } + }; + } + + var storage = weex.requireModule('plusstorage'); + var UNIAPP_STORAGE_DATA_TYPE = '__TYPE'; + + function getStorage(_ref) { + var key = _ref.key, + data = _ref.data, + success = _ref.success, + fail = _ref.fail, + complete = _ref.complete; + + storage.getItem(key + UNIAPP_STORAGE_DATA_TYPE, function(ret) { + if (ret.result === 'success') { + var dataType = ret.data; + storage.getItem(key, function(res) { + if (res.result === 'success') { + var result = res.data; + if (dataType && result) { + if (dataType !== 'String') { + result = JSON.parse(result); + } + isFn(success) && success({ + errMsg: 'getStorage:ok', + data: result + }); + } else { + res.errMsg = 'setStorage:fail'; + isFn(fail) && fail(res); + } + } else { + res.errMsg = 'setStorage:fail'; + isFn(fail) && fail(res); + } + isFn(complete) && complete(res); + }); + } else { + ret.errMsg = 'setStorage:fail'; + isFn(fail) && fail(ret); + isFn(complete) && complete(ret); + } + }); + } + + function setStorage(_ref2) { + var key = _ref2.key, + data = _ref2.data, + success = _ref2.success, + fail = _ref2.fail, + complete = _ref2.complete; + + var dataType = 'String'; + if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') { + dataType = 'Object'; + data = JSON.stringify(data); + } + storage.setItem(key, data, function(res) { + if (res.result === 'success') { + storage.setItem(key + UNIAPP_STORAGE_DATA_TYPE, dataType, function(ret) { + if (ret.result === 'success') { + isFn(success) && success({ + errMsg: 'setStorage:ok' + }); + } else { + ret.errMsg = 'setStorage:fail'; + isFn(fail) && fail(ret); + } + }); + } else { + res.errMsg = 'setStorage:fail'; + isFn(fail) && fail(res); + } + isFn(complete) && complete(res); + }); + } + + function removeStorage(_ref3) { + var key = _ref3.key, + data = _ref3.data, + success = _ref3.success, + fail = _ref3.fail, + complete = _ref3.complete; + + storage.removeItem(key, function(res) { + if (res.result === 'success') { + isFn(success) && success({ + errMsg: 'removeStorage:ok' + }); + } else { + res.errMsg = 'removeStorage:fail'; + isFn(fail) && fail(res); + } + isFn(complete) && complete(res); + }); + storage.removeItem(key + UNIAPP_STORAGE_DATA_TYPE); + } + + function clearStorage(_ref4) { + var key = _ref4.key, + data = _ref4.data, + success = _ref4.success, + fail = _ref4.fail, + complete = _ref4.complete; + } + + var clipboard = weex.requireModule('clipboard'); + + function getClipboardData(_ref) { + var success = _ref.success, + fail = _ref.fail, + complete = _ref.complete; + + clipboard.getString(function(_ref2) { + var data = _ref2.data; + + var res = { + errMsg: 'getClipboardData:ok', + data: data + }; + isFn(success) && success(res); + isFn(complete) && complete(res); + }); + } + + function setClipboardData(_ref3) { + var data = _ref3.data, + success = _ref3.success, + fail = _ref3.fail, + complete = _ref3.complete; + + var res = { + errMsg: 'setClipboardData:ok' + }; + clipboard.setString(data); + isFn(success) && success(res); + isFn(complete) && complete(res); + } + + var getEmitter = function() { + if (typeof getUniEmitter === 'function') { + /* eslint-disable no-undef */ + return getUniEmitter; + } + var Emitter = { + $on: function $on() { + console.warn('uni.$on failed'); + }, + $off: function $off() { + console.warn('uni.$off failed'); + }, + $once: function $once() { + console.warn('uni.$once failed'); + }, + $emit: function $emit() { + console.warn('uni.$emit failed'); + } + }; + return function getUniEmitter() { + return Emitter; + }; + }(); + + function apply(ctx, method, args) { + return ctx[method].apply(ctx, args); + } + + function $on() { + return apply(getEmitter(), '$on', [].concat(Array.prototype.slice.call(arguments))); + } + + function $off() { + return apply(getEmitter(), '$off', [].concat(Array.prototype.slice.call(arguments))); + } + + function $once() { + return apply(getEmitter(), '$once', [].concat(Array.prototype.slice.call(arguments))); + } + + function $emit() { + return apply(getEmitter(), '$emit', [].concat(Array.prototype.slice.call(arguments))); + } + + + + var api = /*#__PURE__*/ Object.freeze({ + loadFontFace: loadFontFace, + ready: ready, + request: request, + getStorage: getStorage, + setStorage: setStorage, + removeStorage: removeStorage, + clearStorage: clearStorage, + getClipboardData: getClipboardData, + setClipboardData: setClipboardData, + onSubNVueMessage: onSubNVueMessage, + getSubNVueById: getSubNVueById, + getCurrentSubNVue: getCurrentSubNVue, + $on: $on, + $off: $off, + $once: $once, + $emit: $emit + }); + + + var wx = { + uploadFile: true, + downloadFile: true, + chooseImage: true, + previewImage: true, + getImageInfo: true, + saveImageToPhotosAlbum: true, + chooseVideo: true, + saveVideoToPhotosAlbum: true, + saveFile: true, + getSavedFileList: true, + getSavedFileInfo: true, + removeSavedFile: true, + openDocument: true, + setStorage: true, + getStorage: true, + getStorageInfo: true, + removeStorage: true, + clearStorage: true, + getLocation: true, + chooseLocation: true, + openLocation: true, + getSystemInfo: true, + getNetworkType: true, + makePhoneCall: true, + scanCode: true, + setScreenBrightness: true, + getScreenBrightness: true, + setKeepScreenOn: true, + vibrateLong: true, + vibrateShort: true, + addPhoneContact: true, + showToast: true, + showLoading: true, + hideToast: true, + hideLoading: true, + showModal: true, + showActionSheet: true, + setNavigationBarTitle: true, + setNavigationBarColor: true, + navigateTo: true, + redirectTo: true, + reLaunch: true, + switchTab: true, + navigateBack: true, + getProvider: true, + login: true, + getUserInfo: true, + share: true, + requestPayment: true, + subscribePush: true, + unsubscribePush: true, + onPush: true, + offPush: true + }; + + var baseUni = { + os: { + nvue: true + } + }; + + var uni = {}; + + if (typeof Proxy !== 'undefined') { + uni = new Proxy({}, { + get: function get(target, name) { + if (name === 'os') { + return { + nvue: true + }; + } + if (name === 'postMessage') { + return postMessage; + } + if (name === 'requireNativePlugin') { + return requireNativePlugin; + } + if (name === 'onNavigationBarButtonTap') { + return onNavigationBarButtonTap; + } + if (name === 'onNavigationBarSearchInputChanged') { + return onNavigationBarSearchInputChanged; + } + if (name === 'onNavigationBarSearchInputConfirmed') { + return onNavigationBarSearchInputConfirmed; + } + if (name === 'onNavigationBarSearchInputClicked') { + return onNavigationBarSearchInputClicked; + } + var method = api[name]; + if (!method) { + method = createPublish(name); + } + if (shouldPromise(name)) { + return promisify(method); + } + return method; + } + }); + } else { + Object.keys(baseUni).forEach(function(key) { + uni[key] = baseUni[key]; + }); + + uni.postMessage = postMessage; + + uni.requireNativePlugin = requireNativePlugin; + + uni.onNavigationBarButtonTap = onNavigationBarButtonTap; + + uni.onNavigationBarSearchInputChanged = onNavigationBarSearchInputChanged; + + uni.onNavigationBarSearchInputConfirmed = onNavigationBarSearchInputConfirmed; + + uni.onNavigationBarSearchInputClicked = onNavigationBarSearchInputClicked; + + Object.keys(wx).forEach(function(name) { + var method = api[name]; + if (!method) { + method = createPublish(name); + } + if (shouldPromise(name)) { + uni[name] = promisify(method); + } else { + uni[name] = method; + } + }); + } + return uni; +} + +var createUni; + +if (typeof getUni === 'function') { + createUni = getUni; +} else { + createUni = initUni; +} +var weexPlus = new WeexPlus(weex); +export default createUni(weex, weexPlus, BroadcastChannel); +export { + weexPlus +}; diff --git a/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue-v8/package.json b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue-v8/package.json new file mode 100644 index 000000000..d3b27a577 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue-v8/package.json @@ -0,0 +1,11 @@ +{ + "name": "@dcloudio/uni-app-plus-nvue-v8", + "version": "0.0.1", + "description": "uni-app app-plus-nvue-v8", + "main": "dist/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "fxy060608", + "license": "Apache-2.0" +} diff --git a/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue/LICENSE b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue/LICENSE new file mode 100755 index 000000000..7a4a3ea24 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue/dist/index.js b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue/dist/index.js new file mode 100644 index 000000000..10582dd30 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue/dist/index.js @@ -0,0 +1,612 @@ +var isFn = function isFn(v) { + return typeof v === 'function'; +}; + +var handlePromise = function handlePromise(promise) { + return promise.then(function (data) { + return [null, data]; + }).catch(function (err) { + return [err]; + }); +}; + +var REGEX = /^on|^create|Sync$|Manager$|^pause/; +var API_NORMAL_LIST = ['os', 'stopRecord', 'stopVoice', 'stopBackgroundAudio', 'stopPullDownRefresh', 'hideKeyboard', 'hideToast', 'hideLoading', 'showNavigationBarLoading', 'hideNavigationBarLoading', 'canIUse', 'navigateBack', 'closeSocket', 'pageScrollTo', 'drawCanvas']; + +var shouldPromise = function shouldPromise(name) { + if (REGEX.test(name) && name !== 'createBLEConnection') { + return false; + } + if (~API_NORMAL_LIST.indexOf(name)) { + return false; + } + return true; +}; + +var promisify = function promisify(api) { + return function () { + for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + params[_key - 1] = arguments[_key]; + } + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + if (isFn(options.success) || isFn(options.fail) || isFn(options.complete)) { + return api.apply(undefined, [options].concat(params)); + } + return handlePromise(new Promise(function (resolve, reject) { + api.apply(undefined, [Object.assign({}, options, { + success: resolve, + fail: reject + })].concat(params)); + /* eslint-disable no-extend-native */ + Promise.prototype.finally = function (callback) { + var promise = this.constructor; + return this.then(function (value) { + return promise.resolve(callback()).then(function () { + return value; + }); + }, function (reason) { + return promise.resolve(callback()).then(function () { + throw reason; + }); + }); + }; + })); + }; +}; + +var UNIAPP_LAUNCH_WEBVIEW_ID = '__UNIAPP_LAUNCH_WEBVIEW_ID'; + +var plus = weex.requireModule('plus'); +var storage = weex.requireModule('plusstorage'); +var globalEvent = weex.requireModule('globalEvent'); + +var id = 0; +var callbacks = {}; + +var WEBVIEW_ID = ''; + +if (weex.config.plus_appid) { + WEBVIEW_ID = weex.config.plus_appid; +} else { + storage && storage.getItem && storage.getItem(UNIAPP_LAUNCH_WEBVIEW_ID, function (evt) { + if (evt.result === 'success' && evt.data) { + WEBVIEW_ID = evt.data; + } + }); +} + +globalEvent.addEventListener('plusMessage', function (e) { + if (e.data.type === 'UniAppJsApi') { + invoke(e.data.id, e.data.data); + } else if (e.data.type === 'onNavigationBarButtonTap') { + if (typeof onNavigationBarButtonTapCallback === 'function') { + onNavigationBarButtonTapCallback(e.data.data); + } + } else if (e.data.type === 'onNavigationBarSearchInputChanged') { + if (typeof onNavigationBarSearchInputChangedCallback === 'function') { + onNavigationBarSearchInputChangedCallback(e.data.data); + } + } else if (e.data.type === 'onNavigationBarSearchInputConfirmed') { + if (typeof onNavigationBarSearchInputConfirmedCallback === 'function') { + onNavigationBarSearchInputConfirmedCallback(e.data.data); + } + } else if (e.data.type === 'onNavigationBarSearchInputClicked') { + if (typeof onNavigationBarSearchInputClickedCallback === 'function') { + onNavigationBarSearchInputClickedCallback(e.data.data); + } + } +}); + +var createCallback = function createCallback(args, type) { + var callback = function callback(res) { + if (isFn(args)) { + args(res); + } else if (args) { + if (~res.errMsg.indexOf(':ok')) { + isFn(args.success) && args.success(res); + } else if (~res.errMsg.indexOf(':fail')) { + isFn(args.fail) && args.fail(res); + } + isFn(args.complete) && args.complete(res); + } + }; + if (isFn(args) || args && isFn(args.callback)) { + callback.keepAlive = true; + } + return callback; +}; + +var invoke = function invoke(callbackId, data) { + var callback = callbacks[callbackId]; + if (callback) { + callback(data); + if (!callback.keepAlive) { + delete callbacks[callbackId]; + } + } else { + console.error('callback[' + callbackId + '] is undefined'); + } +}; + +var publish = function publish(_ref) { + var id = _ref.id, + type = _ref.type, + params = _ref.params; + + callbacks[id] = createCallback(params, type); + if (WEBVIEW_ID) { + plus.postMessage({ + id: id, + type: type, + params: params + }, WEBVIEW_ID); + } else { + console.error('launch webview id is not ready'); + } +}; + +function postMessage(data) { + if (WEBVIEW_ID) { + plus.postMessage(data, WEBVIEW_ID); + } else { + console.error('launch webview id is not ready'); + } +} + +var createPublish = function createPublish(name) { + return function (args) { + publish({ + id: id++, + type: name, + params: args + }); + }; +}; + +var onNavigationBarButtonTapCallback = void 0; +var onNavigationBarSearchInputChangedCallback = void 0; +var onNavigationBarSearchInputConfirmedCallback = void 0; +var onNavigationBarSearchInputClickedCallback = void 0; +function onNavigationBarButtonTap(callback) { + onNavigationBarButtonTapCallback = callback; +} +function onNavigationBarSearchInputChanged(callback) { + onNavigationBarSearchInputChangedCallback = callback; +} +function onNavigationBarSearchInputConfirmed(callback) { + onNavigationBarSearchInputConfirmedCallback = callback; +} +function onNavigationBarSearchInputClicked(callback) { + onNavigationBarSearchInputClickedCallback = callback; +} + +function requireNativePlugin(pluginName) { + return weex.requireModule(pluginName); +} + +var dom = weex.requireModule('dom'); + +function loadFontFace(_ref) { + var family = _ref.family, + source = _ref.source, + desc = _ref.desc, + success = _ref.success, + fail = _ref.fail, + complete = _ref.complete; + + dom.addRule('fontFace', { + fontFamily: family, + src: source.replace(/"/g, '\'') + }); + var res = { + errMsg: 'loadFontFace:ok', + status: 'loaded' + }; + isFn(success) && success(res); + isFn(complete) && complete(res); +} + +var globalEvent$1 = weex.requireModule('globalEvent'); + +var callbacks$1 = []; + +globalEvent$1.addEventListener('plusMessage', function (e) { + if (e.data.type === 'UniAppReady') { + ready.isUniAppReady = true; + if (callbacks$1.length) { + callbacks$1.forEach(function (callback) { + return callback(); + }); + callbacks$1 = []; + } + } +}); + +function ready(callback) { + if (typeof callback === 'function') { + if (this.isUniAppReady) { + callback(); + } else { + callbacks$1.push(callback); + } + } +} + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; +} : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; +}; + +var stream = weex.requireModule('stream'); + +// let requestTaskId = 0 + +var METHOD_GET = 'GET'; +var METHOD_POST = 'POST'; +var CONTENT_TYPE_JSON = 'application/json'; +var CONTENT_TYPE_FORM = 'application/x-www-form-urlencoded'; + +var serialize = function serialize(data) { + var method = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : METHOD_GET; + var contentType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : CONTENT_TYPE_FORM; + + if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') { + if (method.toUpperCase() === METHOD_POST && contentType.toLowerCase() === CONTENT_TYPE_JSON) { + return JSON.stringify(data); + } else { + return Object.keys(data).map(function (key) { + return encodeURIComponent(key) + '=' + encodeURIComponent(data[key]); + }).join('&'); + } + } + return data; +}; + +function request(_ref) { + var url = _ref.url, + data = _ref.data, + header = _ref.header, + _ref$method = _ref.method, + method = _ref$method === undefined ? 'GET' : _ref$method, + _ref$dataType = _ref.dataType, + dataType = _ref$dataType === undefined ? 'json' : _ref$dataType, + responseType = _ref.responseType, + success = _ref.success, + fail = _ref.fail, + complete = _ref.complete; + + // requestTaskId++ + var aborted = false; + + var hasContentType = false; + var headers = {}; + if (header) { + for (var name in header) { + if (!hasContentType && name.toLowerCase() === 'content-type') { + hasContentType = true; + headers['Content-Type'] = header[name]; + } else { + headers[name] = header[name]; + } + } + } + if (method === METHOD_GET && data) { + url = url + (~url.indexOf('?') ? url.substr(-1) === '&' || url.substr(-1) === '?' ? '' : '&' : '?') + serialize(data); + } + stream.fetch({ + url: url, + method: method, + headers: headers, + type: dataType === 'json' ? 'json' : 'text', + body: method !== METHOD_GET ? serialize(data, method, headers['Content-Type']) : '' + }, function (_ref2) { + var status = _ref2.status, + ok = _ref2.ok, + statusText = _ref2.statusText, + data = _ref2.data, + headers = _ref2.headers; + + var ret = {}; + if (!status || status === -1 || aborted) { + ret.errMsg = 'request:fail'; + isFn(fail) && fail(ret); + } else { + ret.data = data; + ret.statusCode = status; + ret.header = headers; + isFn(success) && success(ret); + } + isFn(complete) && complete(ret); + }); + return { + abort: function abort() { + aborted = true; + } + }; +} + +var storage$1 = weex.requireModule('plusstorage'); +var UNIAPP_STORAGE_DATA_TYPE = '__TYPE'; + +function getStorage(_ref) { + var key = _ref.key, + data = _ref.data, + success = _ref.success, + fail = _ref.fail, + complete = _ref.complete; + + storage$1.getItem(key + UNIAPP_STORAGE_DATA_TYPE, function (ret) { + if (ret.result === 'success') { + var dataType = ret.data; + storage$1.getItem(key, function (res) { + if (res.result === 'success') { + var result = res.data; + if (dataType && result) { + if (dataType !== 'String') { + result = JSON.parse(result); + } + isFn(success) && success({ + errMsg: 'getStorage:ok', + data: result + }); + } else { + res.errMsg = 'setStorage:fail'; + isFn(fail) && fail(res); + } + } else { + res.errMsg = 'setStorage:fail'; + isFn(fail) && fail(res); + } + isFn(complete) && complete(res); + }); + } else { + ret.errMsg = 'setStorage:fail'; + isFn(fail) && fail(ret); + isFn(complete) && complete(ret); + } + }); +} +function setStorage(_ref2) { + var key = _ref2.key, + data = _ref2.data, + success = _ref2.success, + fail = _ref2.fail, + complete = _ref2.complete; + + var dataType = 'String'; + if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') { + dataType = 'Object'; + data = JSON.stringify(data); + } + storage$1.setItem(key, data, function (res) { + if (res.result === 'success') { + storage$1.setItem(key + UNIAPP_STORAGE_DATA_TYPE, dataType, function (ret) { + if (ret.result === 'success') { + isFn(success) && success({ + errMsg: 'setStorage:ok' + }); + } else { + ret.errMsg = 'setStorage:fail'; + isFn(fail) && fail(ret); + } + }); + } else { + res.errMsg = 'setStorage:fail'; + isFn(fail) && fail(res); + } + isFn(complete) && complete(res); + }); +} + +function removeStorage(_ref3) { + var key = _ref3.key, + data = _ref3.data, + success = _ref3.success, + fail = _ref3.fail, + complete = _ref3.complete; + + storage$1.removeItem(key, function (res) { + if (res.result === 'success') { + isFn(success) && success({ + errMsg: 'removeStorage:ok' + }); + } else { + res.errMsg = 'removeStorage:fail'; + isFn(fail) && fail(res); + } + isFn(complete) && complete(res); + }); + storage$1.removeItem(key + UNIAPP_STORAGE_DATA_TYPE); +} + +function clearStorage(_ref4) { + var key = _ref4.key, + data = _ref4.data, + success = _ref4.success, + fail = _ref4.fail, + complete = _ref4.complete; +} + +var clipboard = weex.requireModule('clipboard'); + +function getClipboardData(_ref) { + var success = _ref.success, + fail = _ref.fail, + complete = _ref.complete; + + clipboard.getString(function (_ref2) { + var data = _ref2.data; + + var res = { + errMsg: 'getClipboardData:ok', + data: data + }; + isFn(success) && success(res); + isFn(complete) && complete(res); + }); +} + +function setClipboardData(_ref3) { + var data = _ref3.data, + success = _ref3.success, + fail = _ref3.fail, + complete = _ref3.complete; + + var res = { + errMsg: 'setClipboardData:ok' + }; + clipboard.setString(data); + isFn(success) && success(res); + isFn(complete) && complete(res); +} + + + +var api = /*#__PURE__*/Object.freeze({ + loadFontFace: loadFontFace, + ready: ready, + request: request, + getStorage: getStorage, + setStorage: setStorage, + removeStorage: removeStorage, + clearStorage: clearStorage, + getClipboardData: getClipboardData, + setClipboardData: setClipboardData +}); + +var wx = { + uploadFile: true, + downloadFile: true, + chooseImage: true, + previewImage: true, + getImageInfo: true, + saveImageToPhotosAlbum: true, + chooseVideo: true, + saveVideoToPhotosAlbum: true, + saveFile: true, + getSavedFileList: true, + getSavedFileInfo: true, + removeSavedFile: true, + openDocument: true, + setStorage: true, + getStorage: true, + getStorageInfo: true, + removeStorage: true, + clearStorage: true, + getLocation: true, + chooseLocation: true, + openLocation: true, + getSystemInfo: true, + getNetworkType: true, + makePhoneCall: true, + scanCode: true, + setScreenBrightness: true, + getScreenBrightness: true, + setKeepScreenOn: true, + vibrateLong: true, + vibrateShort: true, + addPhoneContact: true, + showToast: true, + showLoading: true, + hideToast: true, + hideLoading: true, + showModal: true, + showActionSheet: true, + setNavigationBarTitle: true, + setNavigationBarColor: true, + navigateTo: true, + redirectTo: true, + reLaunch: true, + switchTab: true, + navigateBack: true, + getProvider: true, + login: true, + getUserInfo: true, + share: true, + requestPayment: true, + subscribePush: true, + unsubscribePush: true, + onPush: true, + offPush: true +}; + +var uni = {}; + +var baseUni = { + os: { + nvue: true + } +}; + +if (typeof Proxy !== 'undefined') { + uni = new Proxy({}, { + get: function get(target, name) { + if (name === 'os') { + return { + nvue: true + }; + } + if (name === 'postMessage') { + return postMessage; + } + if (name === 'requireNativePlugin') { + return requireNativePlugin; + } + if (name === 'onNavigationBarButtonTap') { + return onNavigationBarButtonTap; + } + if (name === 'onNavigationBarSearchInputChanged') { + return onNavigationBarSearchInputChanged; + } + if (name === 'onNavigationBarSearchInputConfirmed') { + return onNavigationBarSearchInputConfirmed; + } + if (name === 'onNavigationBarSearchInputClicked') { + return onNavigationBarSearchInputClicked; + } + var method = api[name]; + if (!method) { + method = createPublish(name); + } + if (shouldPromise(name)) { + return promisify(method); + } + return method; + } + }); +} else { + Object.keys(baseUni).forEach(function (key) { + uni[key] = baseUni[key]; + }); + + uni.postMessage = postMessage; + + uni.requireNativePlugin = requireNativePlugin; + + uni.onNavigationBarButtonTap = onNavigationBarButtonTap; + + uni.onNavigationBarSearchInputChanged = onNavigationBarSearchInputChanged; + + uni.onNavigationBarSearchInputConfirmed = onNavigationBarSearchInputConfirmed; + + uni.onNavigationBarSearchInputClicked = onNavigationBarSearchInputClicked; + + Object.keys(wx).forEach(function (name) { + var method = api[name]; + if (!method) { + method = createPublish(name); + } + if (shouldPromise(name)) { + uni[name] = promisify(method); + } else { + uni[name] = method; + } + }); +} + +var uni$1 = uni; + +export default uni$1; diff --git a/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue/package.json b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue/package.json new file mode 100644 index 000000000..91f8ada8a --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus-nvue/package.json @@ -0,0 +1,11 @@ +{ + "name": "@dcloudio/uni-app-plus-nvue", + "version": "0.0.1", + "description": "uni-app app-plus-nvue", + "main": "dist/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "fxy060608", + "license": "Apache-2.0" +} diff --git a/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/LICENSE b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/LICENSE new file mode 100755 index 000000000..7a4a3ea24 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/dist/index.js b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/dist/index.js new file mode 100644 index 000000000..98fd3a789 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/dist/index.js @@ -0,0 +1,157 @@ +var isFn = function isFn(v) { + return typeof v === 'function'; +}; + +var handlePromise = function handlePromise(promise) { + return promise.then(function (data) { + return [null, data]; + }).catch(function (err) { + return [err]; + }); +}; + +var REGEX = /^on|^create|Sync$|Manager$|^pause/; +var API_NORMAL_LIST = ['os', 'stopRecord', 'stopVoice', 'stopBackgroundAudio', 'stopPullDownRefresh', 'hideKeyboard', 'hideToast', 'hideLoading', 'showNavigationBarLoading', 'hideNavigationBarLoading', 'canIUse', 'navigateBack', 'closeSocket', 'pageScrollTo', 'drawCanvas']; + +var shouldPromise = function shouldPromise(name) { + if (REGEX.test(name) && name !== 'createBLEConnection') { + return false; + } + if (~API_NORMAL_LIST.indexOf(name)) { + return false; + } + return true; +}; + +var promisify = function promisify(api) { + return function () { + for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + params[_key - 1] = arguments[_key]; + } + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + if (isFn(options.success) || isFn(options.fail) || isFn(options.complete)) { + return api.apply(undefined, [options].concat(params)); + } + return handlePromise(new Promise(function (resolve, reject) { + api.apply(undefined, [Object.assign({}, options, { + success: resolve, + fail: reject + })].concat(params)); + /* eslint-disable no-extend-native */ + Promise.prototype.finally = function (callback) { + var promise = this.constructor; + return this.then(function (value) { + return promise.resolve(callback()).then(function () { + return value; + }); + }, function (reason) { + return promise.resolve(callback()).then(function () { + throw reason; + }); + }); + }; + })); + }; +}; + +var EPS = 1e-4; +var BASE_DEVICE_WIDTH = 750; +var isIOS = false; +var deviceWidth = 0; +var deviceDPR = 0; + +function checkDeviceWidth() { + var _wx$getSystemInfoSync = wx.getSystemInfoSync(), + platform = _wx$getSystemInfoSync.platform, + pixelRatio = _wx$getSystemInfoSync.pixelRatio, + windowWidth = _wx$getSystemInfoSync.windowWidth; + + deviceWidth = windowWidth; + deviceDPR = pixelRatio; + isIOS = platform === 'ios'; +} + +function transformUpx(number, newDeviceWidth) { + if (deviceWidth === 0) { + checkDeviceWidth(); + } + + if (number === 0) { + return 0; + } + + var result = number / BASE_DEVICE_WIDTH * (newDeviceWidth || deviceWidth); + if (result < 0) { + result = -result; + } + result = Math.floor(result + EPS); + if (result === 0) { + if (deviceDPR === 1 || !isIOS) { + return 1; + } else { + return 0.5; + } + } + return number < 0 ? -result : result; +} + +function requireNativePlugin(pluginName) { + /* eslint-disable no-undef */ + return __requireNativePlugin__(pluginName); +} + +var uni = {}; + +var baseUni = { + os: { + plus: true + } +}; + +if (typeof Proxy !== 'undefined') { + uni = new Proxy({}, { + get: function get(target, name) { + if (baseUni.hasOwnProperty(name)) { + return baseUni[name]; + } + + if (name === 'upx2px') { + return transformUpx; + } + if (name === 'requireNativePlugin') { + return requireNativePlugin; + } + if (!wx.hasOwnProperty(name)) { + return; + } + if (shouldPromise(name)) { + return promisify(wx[name]); + } + return wx[name]; + } + }); +} else { + uni.upx2px = transformUpx; + + uni.requireNativePlugin = requireNativePlugin; + + Object.keys(baseUni).forEach(function (key) { + uni[key] = baseUni[key]; + }); + + Object.keys(wx).forEach(function (key) { + if (wx.hasOwnProperty(key)) { + if (shouldPromise(key)) { + uni[key] = promisify(wx[key]); + } else { + uni[key] = wx[key]; + } + } + }); +} + +var uni$1 = uni; + +export default uni$1; diff --git a/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/dist/index.new.js b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/dist/index.new.js new file mode 100644 index 000000000..ea568d891 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/dist/index.new.js @@ -0,0 +1,626 @@ +import Vue from 'vue'; + +const _toString = Object.prototype.toString; +const hasOwnProperty = Object.prototype.hasOwnProperty; + +function isFn (fn) { + return typeof fn === 'function' +} + +function isStr (str) { + return typeof str === 'string' +} + +function isPlainObject (obj) { + return _toString.call(obj) === '[object Object]' +} + +function hasOwn (obj, key) { + return hasOwnProperty.call(obj, key) +} + +function noop () {} + +const SYNC_API_RE = /hideKeyboard|upx2px|canIUse|^create|Sync$|Manager$/; + +const CONTEXT_API_RE = /^create|Manager$/; + +const CALLBACK_API_RE = /^on/; + +function isContextApi (name) { + return CONTEXT_API_RE.test(name) +} +function isSyncApi (name) { + return SYNC_API_RE.test(name) +} + +function isCallbackApi (name) { + return CALLBACK_API_RE.test(name) +} + +function handlePromise (promise) { + return promise.then(data => { + return [null, data] + }) + .catch(err => [err]) +} + +function shouldPromise (name) { + if (isSyncApi(name)) { + return false + } + if (isCallbackApi(name)) { + return false + } + return true +} + +function promisify (name, api) { + if (!shouldPromise(name)) { + return api + } + return function promiseApi (options = {}, ...params) { + if (isFn(options.success) || isFn(options.fail) || isFn(options.complete)) { + return api(options, ...params) + } + return handlePromise(new Promise((resolve, reject) => { + api(Object.assign({}, options, { + success: resolve, + fail: reject + }), ...params); + /* eslint-disable no-extend-native */ + Promise.prototype.finally = function (callback) { + const promise = this.constructor; + return this.then( + value => promise.resolve(callback()).then(() => value), + reason => promise.resolve(callback()).then(() => { + throw reason + }) + ) + }; + })) + } +} + +const EPS = 1e-4; +const BASE_DEVICE_WIDTH = 750; +let isIOS = false; +let deviceWidth = 0; +let deviceDPR = 0; + +function checkDeviceWidth () { + const { + platform, + pixelRatio, + windowWidth + } = wx.getSystemInfoSync(); // uni=>wx runtime 编译目标是 uni 对象,内部不允许直接使用 uni + + deviceWidth = windowWidth; + deviceDPR = pixelRatio; + isIOS = platform === 'ios'; +} + +function upx2px (number, newDeviceWidth) { + if (deviceWidth === 0) { + checkDeviceWidth(); + } + + number = Number(number); + if (number === 0) { + return 0 + } + let result = (number / BASE_DEVICE_WIDTH) * (newDeviceWidth || deviceWidth); + if (result < 0) { + result = -result; + } + result = Math.floor(result + EPS); + if (result === 0) { + if (deviceDPR === 1 || !isIOS) { + return 1 + } else { + return 0.5 + } + } + return number < 0 ? -result : result +} + +var protocols = {}; + +const CALLBACKS = ['success', 'fail', 'cancel', 'complete']; + +function processCallback (methodName, method, returnValue) { + return function (res) { + return method(processReturnValue(methodName, res, returnValue)) + } +} + +function processArgs (methodName, fromArgs, argsOption = {}, returnValue = {}, keepFromArgs = false) { + if (isPlainObject(fromArgs)) { // 一般 api 的参数解析 + const toArgs = keepFromArgs === true ? fromArgs : {}; // returnValue 为 false 时,说明是格式化返回值,直接在返回值对象上修改赋值 + if (isFn(argsOption)) { + argsOption = argsOption(fromArgs, toArgs) || {}; + } + for (let key in fromArgs) { + if (hasOwn(argsOption, key)) { + let keyOption = argsOption[key]; + if (isFn(keyOption)) { + keyOption = keyOption(fromArgs[key], fromArgs, toArgs); + } + if (!keyOption) { // 不支持的参数 + console.warn(`app-plus ${methodName}暂不支持${key}`); + } else if (isStr(keyOption)) { // 重写参数 key + toArgs[keyOption] = fromArgs[key]; + } else if (isPlainObject(keyOption)) { // {name:newName,value:value}可重新指定参数 key:value + toArgs[keyOption.name ? keyOption.name : key] = keyOption.value; + } + } else if (CALLBACKS.includes(key)) { + toArgs[key] = processCallback(methodName, fromArgs[key], returnValue); + } else { + if (!keepFromArgs) { + toArgs[key] = fromArgs[key]; + } + } + } + return toArgs + } else if (isFn(fromArgs)) { + fromArgs = processCallback(methodName, fromArgs, returnValue); + } + return fromArgs +} + +function processReturnValue (methodName, res, returnValue, keepReturnValue = false) { + if (isFn(protocols.returnValue)) { // 处理通用 returnValue + res = protocols.returnValue(methodName, res); + } + return processArgs(methodName, res, returnValue, {}, keepReturnValue) +} + +function wrapper (methodName, method) { + if (hasOwn(protocols, methodName)) { + const protocol = protocols[methodName]; + if (!protocol) { // 暂不支持的 api + return function () { + console.error(`app-plus 暂不支持${methodName}`); + } + } + return function (arg1, arg2) { // 目前 api 最多两个参数 + let options = protocol; + if (isFn(protocol)) { + options = protocol(arg1); + } + + arg1 = processArgs(methodName, arg1, options.args, options.returnValue); + + const returnValue = wx[options.name || methodName](arg1, arg2); + if (isSyncApi(methodName)) { // 同步 api + return processReturnValue(methodName, returnValue, options.returnValue, isContextApi(methodName)) + } + return returnValue + } + } + return method +} + +const todoApis = Object.create(null); + +const TODOS = [ + 'subscribePush', + 'unsubscribePush', + 'onPush', + 'offPush', + 'share' +]; + +function createTodoApi (name) { + return function todoApi ({ + fail, + complete + }) { + const res = { + errMsg: `${name}:fail:暂不支持 ${name} 方法` + }; + isFn(fail) && fail(res); + isFn(complete) && complete(res); + } +} + +TODOS.forEach(function (name) { + todoApis[name] = createTodoApi(name); +}); + +var providers = {}; + +function getProvider ({ + service, + success, + fail, + complete +}) { + let res = false; + if (providers[service]) { + res = { + errMsg: 'getProvider:ok', + service, + provider: providers[service] + }; + isFn(success) && success(res); + } else { + res = { + errMsg: 'getProvider:fail:服务[' + service + ']不存在' + }; + isFn(fail) && fail(res); + } + isFn(complete) && complete(res); +} + +var extraApi = /*#__PURE__*/Object.freeze({ + getProvider: getProvider +}); + +function requireNativePlugin (pluginName) { + /* eslint-disable no-undef */ + return __requireNativePlugin__(pluginName) +} + +var api = /*#__PURE__*/Object.freeze({ + requireNativePlugin: requireNativePlugin +}); + +const MOCKS = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__']; + +function initMocks (vm) { + const mpInstance = vm.$mp[vm.mpType]; + MOCKS.forEach(mock => { + if (hasOwn(mpInstance, mock)) { + vm[mock] = mpInstance[mock]; + } + }); +} + +function initHooks (mpOptions, hooks) { + hooks.forEach(hook => { + mpOptions[hook] = function (args) { + this.$vm.__call_hook(hook, args); + }; + }); +} + +function getData (data) { + if (typeof data === 'function') { + try { + return data() + } catch (e) { + console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。'); + } + return {} + } + return data || {} +} + +const PROP_TYPES = [String, Number, Boolean, Object, Array, null]; + +function getProperties (props) { + const properties = {}; + if (Array.isArray(props)) { // ['title'] + props.forEach(key => { + properties[key] = null; + }); + } else if (isPlainObject(props)) { // {title:{type:String,default:''},content:String} + Object.keys(props).forEach(key => { + const opts = props[key]; + if (isPlainObject(opts)) { // title:{type:String,default:''} + let value = opts['default']; + if (isFn(value)) { + value = value(); + } + properties[key] = { + type: PROP_TYPES.includes(opts.type) ? opts.type : null, + value + }; + } else { // content:String + properties[key] = PROP_TYPES.includes(opts) ? opts : null; + } + }); + } + return properties +} + +function wrapper$1 (event) { + event.stopPropagation = noop; + event.preventDefault = noop; + + event.target = event.target || {}; + event.detail = event.detail || {}; + // TODO 又得兼容 mpvue 的 mp 对象 + event.mp = event; + event.target = Object.assign({}, event.target, event.detail); + return event +} + +function processEventArgs (event, args = [], isCustom) { + if (isCustom && !args.length) { // 无参数,直接传入 detail 数组 + return event.detail + } + const ret = []; + args.forEach(arg => { + if (arg === '$event') { + ret.push(isCustom ? event.detail[0] : event); + } else { + ret.push(arg); + } + }); + + return ret +} + +const ONCE = '~'; +const CUSTOM = '^'; + +function handleEvent (event) { + event = wrapper$1(event); + + // [['tap',[['handle',[1,2,a]],['handle1',[1,2,a]]]]] + const eventOpts = (event.currentTarget || event.target).dataset.eventOpts; + if (!eventOpts) { + return console.warn(`事件信息不存在`) + } + + // [['handle',[1,2,a]],['handle1',[1,2,a]]] + const eventType = event.type; + eventOpts.forEach(eventOpt => { + let type = eventOpt[0]; + const eventsArray = eventOpt[1]; + + const isCustom = type.charAt(0) === CUSTOM; + type = isCustom ? type.slice(1) : type; + const isOnce = type.charAt(0) === ONCE; + type = isOnce ? type.slice(1) : type; + + if (eventsArray && eventType === type) { + eventsArray.forEach(eventArray => { + const handler = this.$vm[eventArray[0]]; + if (isOnce) { + if (handler.once) { + return + } + handler.once = true; + } + handler.apply(this.$vm, processEventArgs(event, eventArray[1], isCustom)); + }); + } + }); +} + +function handleLink (event) { + event.detail.$parent = this.$vm; +} + +function initRefs (vm) { + const mpInstance = vm.$mp[vm.mpType]; + Object.defineProperty(vm, '$refs', { + get () { + const $refs = Object.create(null); + const components = mpInstance.selectAllComponents('.__ref__'); + components.forEach(component => { + const id = component.id; + $refs[id] = component.$vm; + }); + const forComponents = mpInstance.selectAllComponents('.__ref-in-for__'); + forComponents.forEach(component => { + const id = component.id; + if (!$refs[id]) { + $refs[id] = []; + } + $refs[id].push(component.$vm); + }); + return $refs + } + }); +} + +const hooks = [ + 'onShow', + 'onHide', + 'onError', + 'onPageNotFound' +]; + +function createApp (vueOptions) { + vueOptions = vueOptions.default || vueOptions; + + const appOptions = { + onLaunch (args) { + this.$vm = new Vue(vueOptions); + this.$vm.mpType = 'app'; + this.$vm.$mp = { + app: this + }; + this.$vm.$mount(); + this.$vm.__call_hook('onLaunch', args); + } + }; + + initHooks(appOptions, hooks); + + App(appOptions); + + return vueOptions +} + +const hooks$1 = [ + 'onShow', + 'onHide', + 'onPullDownRefresh', + 'onReachBottom', + 'onShareAppMessage', + 'onPageScroll', + 'onResize', + 'onTabItemTap', + 'onBackPress', + 'onNavigationBarButtonTap', + 'onNavigationBarSearchInputChanged', + 'onNavigationBarSearchInputConfirmed', + 'onNavigationBarSearchInputClicked' +]; + +function createPage (vueOptions) { + vueOptions = vueOptions.default || vueOptions; + const pageOptions = { + data: getData(vueOptions.data), + onLoad (args) { + this.$vm = new Vue(vueOptions); + this.$vm.mpType = 'page'; + this.$vm.$mp = { + data: {}, + page: this + }; + + initRefs(this.$vm); + initMocks(this.$vm); + + this.$vm.$mount(); + this.$vm.__call_hook('onLoad', args); + }, + onReady () { + this.$vm._isMounted = true; + this.$vm.__call_hook('onReady'); + }, + onUnload () { + this.$vm.__call_hook('onUnload'); + this.$vm.$destroy(); + }, + __e: handleEvent, + __l: handleLink + }; + + initHooks(pageOptions, hooks$1); + + return Page(pageOptions) +} + +function createComponent (vueOptions) { + vueOptions = vueOptions.default || vueOptions; + + const properties = getProperties(vueOptions.props); + + const VueComponent = Vue.extend(vueOptions); + + const componentOptions = { + options: { + multipleSlots: true, + addGlobalClass: true + }, + data: getData(vueOptions.data), + properties, + attached () { + // props的处理,一个是直接 与 mp 的 properties 对接,另一个是要做成 reactive,且排除掉 render watch + const options = { + propsData: this.properties, + $component: this + }; + // 初始化 vue 实例 + this.$vm = new VueComponent(options); + this.$vm.mpType = 'component'; + this.$vm.$mp = { + data: {}, + component: this + }; + + initRefs(this.$vm); + initMocks(this.$vm); + + // 初始化渲染数据 + this.$vm.$mount(); + }, + ready () { + this.triggerEvent('__l', this.$vm); + + const eventId = this.dataset.eventId; + if (eventId) { + const listeners = this.$vm.$parent.$mp.listeners; + if (listeners) { + const listenerOpts = listeners[eventId]; + Object.keys(listenerOpts).forEach(eventType => { + listenerOpts[eventType].forEach(handler => { + this.$vm[handler.once ? '$once' : '$on'](eventType, handler); + }); + }); + } + } + + this.$vm._isMounted = true; + this.$vm.__call_hook('mounted'); + this.$vm.__call_hook('onReady'); + }, + detached () { + this.$vm.$destroy(); + }, + pageLifetimes: { + show (args) { + this.$vm.__call_hook('onPageShow', args); + }, + hide () { + this.$vm.__call_hook('onPageHide'); + }, + resize (size) { + this.$vm.__call_hook('onPageResize', size); + } + }, + methods: { + __e: handleEvent, + __l: handleLink + } + }; + + return Component(componentOptions) +} + +let uni = {}; + +if (typeof Proxy !== 'undefined') { + uni = new Proxy({}, { + get (target, name) { + if (name === 'upx2px') { + return upx2px + } + if (api[name]) { + return promisify(name, api[name]) + } + if (extraApi[name]) { + return promisify(name, extraApi[name]) + } + if (todoApis[name]) { + return promisify(name, todoApis[name]) + } + if (!hasOwn(wx, name) && !hasOwn(protocols, name)) { + return + } + return promisify(name, wrapper(name, wx[name])) + } + }); +} else { + uni.upx2px = upx2px; + + Object.keys(todoApis).forEach(name => { + uni[name] = promisify(name, todoApis[name]); + }); + + Object.keys(extraApi).forEach(name => { + uni[name] = promisify(name, todoApis[name]); + }); + + Object.keys(api).forEach(name => { + uni[name] = promisify(name, api[name]); + }); + + Object.keys(wx).forEach(name => { + if (hasOwn(wx, name) || hasOwn(protocols, name)) { + uni[name] = promisify(name, wrapper(name, wx[name])); + } + }); +} + +var uni$1 = uni; + +export default uni$1; +export { createApp, createPage, createComponent }; diff --git a/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/package.json b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/package.json new file mode 100644 index 000000000..4f254be11 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/uni-app-plus/package.json @@ -0,0 +1,11 @@ +{ + "name": "@dcloudio/uni-app-plus", + "version": "0.0.1", + "description": "uni-app app-plus", + "main": "dist/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "fxy060608", + "license": "Apache-2.0" +} diff --git a/packages/vue-cli-plugin-hbuilderx/packages/webpack-app-plus-plugin/index.js b/packages/vue-cli-plugin-hbuilderx/packages/webpack-app-plus-plugin/index.js new file mode 100644 index 000000000..4edfb0c38 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/webpack-app-plus-plugin/index.js @@ -0,0 +1,48 @@ +const fs = require('fs') +const path = require('path') + +const { + log, + done +} = require('@vue/cli-shared-utils') + +class WebpackAppPlusPlugin { + apply(compiler) { + compiler.hooks.done.tapPromise('WebpackAppPlusPlugin', compilation => { + return new Promise((resolve, reject) => { + const callback = function() { + fs.copyFileSync(path.resolve(process.env.UNI_OUTPUT_TMP_DIR, + 'manifest.json'), + path.resolve(process.env.UNI_OUTPUT_DIR, 'manifest.json')) + log() + if (process.env.NODE_ENV === 'development') { + done(`Build complete. Watching for changes...`) + } else { + done(`Build complete. `) + } + resolve() + } + + if (process.env.UNI_USING_NATIVE) { + return resolve() + } + // Copy manifest.json + const wxmp = require(path.resolve(process.env.UNI_HBUILDERX_PLUGINS, + 'weapp-tools/lib')) + try { + wxmp( + process.env.UNI_OUTPUT_TMP_DIR, + process.env.UNI_OUTPUT_DIR, + path.basename(process.env.UNI_INPUT_DIR), + callback + ) + } catch (e) { + resolve() + console.error(e.message) + } + }) + }) + } +} + +module.exports = WebpackAppPlusPlugin diff --git a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/LICENSE b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/LICENSE new file mode 100755 index 000000000..7a4a3ea24 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/main.js b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/main.js new file mode 100644 index 000000000..907954416 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/main.js @@ -0,0 +1,72 @@ +const fs = require('fs') +const path = require('path') + +const loaderUtils = require('loader-utils') + +const { + parseComponent +} = require('weex-template-compiler') + +const { + attrsToQuery +} = require('vue-loader/lib/codegen/utils') + +const { + normalizePath +} = require('@dcloudio/uni-cli-shared') + +const appVuePath = path.resolve(process.env.UNI_INPUT_DIR, 'App.vue') + +function genStyleRequest(style, i, stringifyRequest) { + const src = style.src || normalizePath(appVuePath) + const attrsQuery = attrsToQuery(style.attrs, 'css') + const query = `?vue&type=style&index=${i}${attrsQuery}` + return stringifyRequest(src + query) +} + +function getAppStyleCode(stringifyRequest) { + if (!process.env.UNI_USING_NVUE_COMPILER) { + return '' + } + let code = 'App.appStyle = {}\n' + let styles = [] + try { + if (fs.existsSync(appVuePath)) { + styles = parseComponent(fs.readFileSync(appVuePath, 'utf8')).styles + } + } catch (e) {} + styles.forEach((style, index) => { + code = code + + `Vue.prototype.__merge_style(require(${genStyleRequest(style,index,stringifyRequest)}).default,App.appStyle)\n` + }) + return code +} + +module.exports = function(content) { + this.cacheable && this.cacheable() + + const loaderContext = this + + const statCode = process.env.UNI_USING_STAT ? `import '@dcloudio/uni-stat';` : '' + + if (this.resourceQuery) { + const params = loaderUtils.parseQuery(this.resourceQuery) + if (params && params.page) { + + const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r) + + params.page = decodeURIComponent(params.page) + // import Vue from 'vue'是为了触发 vendor 合并 + return ` +${statCode} +import App from './${normalizePath(params.page)}.nvue?mpType=page' +App.mpType = 'page' +App.route = '${params.page}' +App.el = '#root' +${getAppStyleCode(stringifyRequest)} +new Vue(App) +` + } + } + return statCode + content +} diff --git a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/style.js b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/style.js new file mode 100644 index 000000000..6eff3c3cd --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/style.js @@ -0,0 +1,70 @@ +var path = require('path') +var styler = require('weex-styler') +var { + normalizePath +} = require('@dcloudio/uni-cli-shared') +module.exports = function(content) { + this.cacheable && this.cacheable() + return 'module.exports = ' + genStyleString(content.replace(/\!important/g, ''), this) +} + +// @todo: +// font-relative lengths: em, ex, ch, ic +// viewport-relative lengths: vi, vb +// https://drafts.csswg.org/css-values/#lengths +var REGEXP_LENGTH = /^([-+]?[0-9]*\.?[0-9]+)(rem|vw|vh|vmin|vmax|cm|mm|q|in|pt|pc|px)$/ + +function convertLength(k, v) { + if (typeof v !== 'string') { + return v + } + var result = v.match(REGEXP_LENGTH) + if (result) { + if (result[2] === 'px') { + return result[1] + } + return result[1] + 'CSS_UNIT_' + result[2].toUpperCase() + } + return v +} + +let isFirst = true + +function genStyleString(input, loader) { + var output = '{}' + var resourcePath = normalizePath(path.relative(process.env.UNI_INPUT_DIR, loader.resourcePath)) + styler.parse(input, function(err, obj) { + if (err) { + loader.emitError(err) + return + } + if (obj && obj.jsonStyle) { + if (obj.log) { + var msgs = [] + obj.log.map((log) => { + if (log.reason.indexOf('NOTE:') !== 0) { //仅显示警告,错误信息 + if (log.selectors) { + msgs.push(`${log.selectors}: ${log.reason} at ${resourcePath}:${log.line}`) + } else { + msgs.push(`${log.reason} at ${resourcePath}:${log.line}`) + } + } + }) + if (msgs.length) { + if (isFirst) { + msgs.unshift( + `nvue中不支持如下css。如全局或公共样式受影响,建议将告警样式写在ifndef APP-PLUS-NVUE的条件编译中,详情如下:` + ) + isFirst = false + } + msgs.forEach(msg => console.warn(msg)) + } + } + try { + output = JSON.stringify(obj.jsonStyle, convertLength, 2) + .replace(/"([-+]?[0-9]*\.?[0-9]+)CSS_UNIT_([A-Z]+)"/g, '$1 * CSS_UNIT.$2') + } catch (e) {} + } + }) + return output +} diff --git a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/styleInjection.js b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/styleInjection.js new file mode 100644 index 000000000..dd84223b0 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/styleInjection.js @@ -0,0 +1,135 @@ +const { attrsToQuery } = require('vue-loader/lib/codegen/utils') +const hotReloadAPIPath = JSON.stringify(require.resolve('vue-hot-reload-api')) +const nonWhitespaceRE = /\S+/ + +module.exports = function genStyleInjectionCode ( + loaderContext, + styles, + id, + resourcePath, + stringifyRequest, + needsHotReload, + needsExplicitInjection +) { + let styleImportsCode = `` + let styleInjectionCode = `` + let cssModulesHotReloadCode = `` + + let hasCSSModules = false + const cssModuleNames = new Map() + + function genStyleRequest (style, i) { + const src = style.src || resourcePath + const attrsQuery = attrsToQuery(style.attrs, 'css') + const inheritQuery = `&${loaderContext.resourceQuery.slice(1)}` + // make sure to only pass id when necessary so that we don't inject + // duplicate tags when multiple components import the same css file + const idQuery = style.scoped ? `&id=${id}` : `` + const query = `?vue&type=style&index=${i}${idQuery}${attrsQuery}${inheritQuery}` + return stringifyRequest(src + query) + } + + function genCSSModulesCode (style, request, i) { + hasCSSModules = true + + const moduleName = style.module === true ? '$style' : style.module + if (cssModuleNames.has(moduleName)) { + loaderContext.emitError(`CSS module name ${moduleName} is not unique!`) + } + cssModuleNames.set(moduleName, true) + + // `(vue-)style-loader` exports the name-to-hash map directly + // `css-loader` exports it in `.locals` + const locals = `(style${i}.locals || style${i})` + const name = JSON.stringify(moduleName) + + if (!needsHotReload) { + styleInjectionCode += `this[${name}] = ${locals}\n` + } else { + styleInjectionCode += ` + cssModules[${name}] = ${locals} + Object.defineProperty(this, ${name}, { + configurable: true, + get: function () { + return cssModules[${name}] + } + }) + ` + cssModulesHotReloadCode += ` + module.hot && module.hot.accept([${request}], function () { + var oldLocals = cssModules[${name}] + if (oldLocals) { + var newLocals = require(${request}) + if (JSON.stringify(newLocals) !== JSON.stringify(oldLocals)) { + cssModules[${name}] = newLocals + require(${hotReloadAPIPath}).rerender("${id}") + } + } + }) + ` + } + } + + // empty styles: with no `src` specified or only contains whitespaces + const isNotEmptyStyle = style => style.src || nonWhitespaceRE.test(style.content) + // explicit injection is needed in SSR (for critical CSS collection) + // or in Shadow Mode (for injection into shadow root) + // In these modes, vue-style-loader exports objects with the __inject__ + // method; otherwise we simply import the styles. + if (!needsExplicitInjection) { + styles.forEach((style, i) => { + // do not generate requests for empty styles + if (isNotEmptyStyle(style)) { + const request = genStyleRequest(style, i) + styleImportsCode += `import style${i} from ${request}\n` + if (style.module) genCSSModulesCode(style, request, i) + } + }) + } else { + styleInjectionCode = `if(!this.$options.style){ + this.$options.style = {} +} +if(this.__merge_style && this.$root && this.$root.$options.appStyle){ + this.__merge_style(this.$root.$options.appStyle) +} +` + styles.forEach((style, i) => { + if (isNotEmptyStyle(style)) { + const request = genStyleRequest(style, i) + styleInjectionCode += ( + `if(this.__merge_style){ + this.__merge_style(require(${request}).default) + }else{ + Object.assign(this.$options.style,require(${request}).default) + }\n`//fixed by xxxxxx 简单处理,与 weex-vue-loader 保持一致 + //`var style${i} = require(${request})\n` + + //`if (style${i}.__inject__) style${i}.__inject__(context)\n` + ) + if (style.module) genCSSModulesCode(style, request, i) + } + }) + } + + if (!needsExplicitInjection && !hasCSSModules) { + return styleImportsCode + } + + return ` +${styleImportsCode} +${hasCSSModules && needsHotReload ? `var cssModules = {}` : ``} +${needsHotReload ? `var disposed = false` : ``} + +function injectStyles (context) { + ${needsHotReload ? `if (disposed) return` : ``} + ${styleInjectionCode} +} + +${needsHotReload ? ` + module.hot && module.hot.dispose(function (data) { + disposed = true + }) +` : ``} + +${cssModulesHotReloadCode} + `.trim() +} diff --git a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/template.js b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/template.js new file mode 100644 index 000000000..c5316da2a --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/template.js @@ -0,0 +1,4 @@ +module.exports = function(content) { + this.cacheable && this.cacheable() + return `${content}` +} diff --git a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/package.json b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/package.json new file mode 100644 index 000000000..08bd72686 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/package.json @@ -0,0 +1,10 @@ +{ + "name": "@dcloudio/webpack-uni-nvue-loader", + "version": "0.0.1", + "description": "webpack-uni-nvue-loader", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "fxy060608", + "license": "Apache-2.0" +} diff --git a/packages/vue-cli-plugin-hbuilderx/packages/weex-styler/LICENSE b/packages/vue-cli-plugin-hbuilderx/packages/weex-styler/LICENSE new file mode 100644 index 000000000..e032cea76 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/weex-styler/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-present, songsiqi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/vue-cli-plugin-hbuilderx/packages/weex-styler/README.md b/packages/vue-cli-plugin-hbuilderx/packages/weex-styler/README.md new file mode 100644 index 000000000..6b08f51a5 --- /dev/null +++ b/packages/vue-cli-plugin-hbuilderx/packages/weex-styler/README.md @@ -0,0 +1,124 @@ +# Weex `' + } + return css +} diff --git a/packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/lib/addStylesShadow.js b/packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/lib/addStylesShadow.js new file mode 100644 index 000000000..72947108e --- /dev/null +++ b/packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/lib/addStylesShadow.js @@ -0,0 +1,70 @@ +import listToStyles from './listToStyles' + +export default function addStylesToShadowDOM (parentId, list, shadowRoot) { + var styles = listToStyles(parentId, list) + addStyles(styles, shadowRoot) +} + +/* +type StyleObject = { + id: number; + parts: Array +} + +type StyleObjectPart = { + css: string; + media: string; + sourceMap: ?string +} +*/ + +function addStyles (styles /* Array */, shadowRoot) { + const injectedStyles = + shadowRoot._injectedStyles || + (shadowRoot._injectedStyles = {}) + for (var i = 0; i < styles.length; i++) { + var item = styles[i] + var style = injectedStyles[item.id] + if (!style) { + for (var j = 0; j < item.parts.length; j++) { + addStyle(item.parts[j], shadowRoot) + } + injectedStyles[item.id] = true + } + } +} + +function createStyleElement (shadowRoot) { + var styleElement = document.createElement('style') + styleElement.type = 'text/css' + shadowRoot.appendChild(styleElement) + return styleElement +} + +function addStyle (obj /* StyleObjectPart */, shadowRoot) { + var styleElement = createStyleElement(shadowRoot) + var css = obj.css + var media = obj.media + var sourceMap = obj.sourceMap + + if (media) { + styleElement.setAttribute('media', media) + } + + if (sourceMap) { + // https://developer.chrome.com/devtools/docs/javascript-debugging + // this makes source maps inside style tags work properly in Chrome + css += '\n/*# sourceURL=' + sourceMap.sources[0] + ' */' + // http://stackoverflow.com/a/26603875 + css += '\n/*# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + ' */' + } + + if (styleElement.styleSheet) { + styleElement.styleSheet.cssText = css + } else { + while (styleElement.firstChild) { + styleElement.removeChild(styleElement.firstChild) + } + styleElement.appendChild(document.createTextNode(css)) + } +} diff --git a/packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/lib/listToStyles.js b/packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/lib/listToStyles.js new file mode 100644 index 000000000..bc86bb40d --- /dev/null +++ b/packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/lib/listToStyles.js @@ -0,0 +1,27 @@ +/** + * Translates the list format produced by css-loader into something + * easier to manipulate. + */ +export default function listToStyles (parentId, list) { + var styles = [] + var newStyles = {} + for (var i = 0; i < list.length; i++) { + var item = list[i] + var id = item[0] + var css = item[1] + var media = item[2] + var sourceMap = item[3] + var part = { + id: parentId + ':' + i, + css: css, + media: media, + sourceMap: sourceMap + } + if (!newStyles[id]) { + styles.push(newStyles[id] = { id: id, parts: [part] }) + } else { + newStyles[id].parts.push(part) + } + } + return styles +} diff --git a/packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/package.json b/packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/package.json new file mode 100644 index 000000000..30b7be5af --- /dev/null +++ b/packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/package.json @@ -0,0 +1,26 @@ +{ + "name": "vue-style-loader", + "version": "4.1.2", + "author": "Evan You", + "description": "Vue.js style loader module for webpack", + "repository": { + "type": "git", + "url": "git@github.com:vuejs/vue-style-loader.git" + }, + "scripts": { + "test": "jest", + "prepublishOnly": "conventional-changelog -p angular -r 2 -i CHANGELOG.md -s" + }, + "license": "MIT", + "dependencies": { + "hash-sum": "^1.0.2", + "loader-utils": "^1.0.2" + }, + "devDependencies": { + "babel-core": "^6.26.0", + "babel-jest": "^22.1.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", + "conventional-changelog-cli": "^2.0.1", + "jest": "^22.1.4" + } +} diff --git a/packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/test/test.js b/packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/test/test.js new file mode 100644 index 000000000..10d5128c5 --- /dev/null +++ b/packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/test/test.js @@ -0,0 +1,94 @@ +import addStylesClient from '../lib/addStylesClient' +import addStylesServer from '../lib/addStylesServer' + +const mockedList = [ + [1, 'h1 { color: red; }', ''], + [1, 'p { color: green; }', ''], + [2, 'span { color: blue; }', ''], + [2, 'span { color: blue; }', 'print'] +] + +test('addStylesClient (dev)', () => { + const update = addStylesClient('foo', mockedList, false) + assertStylesMatch(mockedList) + const mockedList2 = mockedList.slice(1, 3) + update(mockedList2) + assertStylesMatch(mockedList2) + update() + expect(document.querySelectorAll('style').length).toBe(0) +}) + +test('addStylesClient (prod)', () => { + const update = addStylesClient('foo', mockedList, true) + assertStylesMatch(mockedList) + const mockedList2 = mockedList.slice(2) + update(mockedList2) + assertStylesMatch(mockedList2) + update() + expect(document.querySelectorAll('style').length).toBe(0) +}) + +test('addStylesClient (dev + ssr)', () => { + mockSSRTags(mockedList, 'foo') + const update = addStylesClient('foo', mockedList, false) + assertStylesMatch(mockedList) + update() + expect(document.querySelectorAll('style').length).toBe(0) +}) + +test('addStylesClient (prod + ssr)', () => { + mockProdSSRTags(mockedList, 'foo') + const update = addStylesClient('foo', mockedList, true) + expect(document.querySelectorAll('style').length).toBe(1) +}) + +test('addStylesServer (dev)', () => { + const context = global.__VUE_SSR_CONTEXT__ = {} + addStylesServer('foo', mockedList, false) + expect(context.styles).toBe( + `` + + `` + + `` + + `` + ) +}) + +test('addStylesServer (prod)', () => { + const context = global.__VUE_SSR_CONTEXT__ = {} + addStylesServer('foo', mockedList, true) + expect(context.styles).toBe( + `` + + `` + ) +}) + +// --- helpers --- + +function assertStylesMatch (list) { + const styles = document.querySelectorAll('style') + expect(styles.length).toBe(list.length) + ;[].forEach.call(styles, (style, i) => { + expect(style.textContent.indexOf(list[i][1]) > -1).toBe(true) + }) +} + +function mockSSRTags (list, parentId) { + list.forEach((item, i) => { + const style = document.createElement('style') + style.setAttribute('data-vue-ssr-id', `${parentId}:${i}`) + style.textContent = item[1] + if (item[2]) { + style.setAttribute('media', item[2]) + } + document.head.appendChild(style) + }) +} + +function mockProdSSRTags (list, parentId) { + const style = document.createElement('style') + style.setAttribute('data-vue-ssr-id', list.map((item, i) => `${parentId}:${i}`).join(' ')) + style.textContent = list.map(item => item[1]).join('\n') + document.head.appendChild(style) +} diff --git a/packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/yarn.lock b/packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/yarn.lock new file mode 100644 index 000000000..4071f74e3 --- /dev/null +++ b/packages/vue-cli-plugin-uni/packages/h5-vue-style-loader/yarn.lock @@ -0,0 +1,3274 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0-beta.35": + version "7.0.0-beta.39" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.39.tgz#91c90bb65207fc5a55128cb54956ded39e850457" + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +JSONStream@^1.0.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.4.tgz#615bb2adb0cd34c8f4c447b5f6512fa1d8f16a2e" + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + +abab@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + +acorn-globals@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538" + dependencies: + acorn "^5.0.0" + +acorn@^5.0.0, acorn@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.3.0.tgz#7446d39459c54fb49a80e6ee6478149b940ec822" + +add-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" + +ajv@^4.9.1: + version "4.11.8" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +ajv@^5.1.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +ansi-escapes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@^3.1.0, ansi-styles@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" + dependencies: + color-convert "^1.9.0" + +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + +append-transform@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" + dependencies: + default-require-extensions "^1.0.0" + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + +are-we-there-yet@~1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-flatten@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + +array-ify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + +async@^1.4.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +async@^2.1.4: + version "2.6.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" + dependencies: + lodash "^4.14.0" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + +aws4@^1.2.1, aws4@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + +babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.0.0, babel-core@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.0" + debug "^2.6.8" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.7" + slash "^1.0.0" + source-map "^0.5.6" + +babel-generator@^6.18.0, babel-generator@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.6" + trim-right "^1.0.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-jest@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-22.1.0.tgz#7fae6f655fffe77e818a8c2868c754a42463fdfd" + dependencies: + babel-plugin-istanbul "^4.1.5" + babel-preset-jest "^22.1.0" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-istanbul@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.5.tgz#6760cdd977f411d3e175bb064f2bc327d99b2b6e" + dependencies: + find-up "^2.1.0" + istanbul-lib-instrument "^1.7.5" + test-exclude "^4.1.1" + +babel-plugin-jest-hoist@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.1.0.tgz#c1281dd7887d77a1711dc760468c3b8285dde9ee" + +babel-plugin-syntax-object-rest-spread@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + +babel-plugin-transform-es2015-modules-commonjs@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-preset-jest@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-22.1.0.tgz#ff4e704102f9642765e2254226050561d8942ec9" + dependencies: + babel-plugin-jest-hoist "^22.1.0" + babel-plugin-syntax-object-rest-spread "^6.13.0" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.18.0, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.18.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + dependencies: + tweetnacl "^0.14.3" + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +boom@4.x.x: + version "4.3.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" + dependencies: + hoek "4.x.x" + +boom@5.x.x: + version "5.2.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" + dependencies: + hoek "4.x.x" + +brace-expansion@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +browser-process-hrtime@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz#425d68a58d3447f02a04aa894187fce8af8b7b8e" + +browser-resolve@^1.11.2: + version "1.11.2" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" + dependencies: + resolve "1.1.7" + +bser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" + dependencies: + node-int64 "^0.4.0" + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase-keys@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" + dependencies: + camelcase "^4.1.0" + map-obj "^2.0.0" + quick-lru "^1.0.0" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.0.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" + dependencies: + ansi-styles "^3.1.0" + escape-string-regexp "^1.0.5" + supports-color "^4.0.0" + +ci-info@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.2.tgz#03561259db48d0474c8bdc90f5b47b068b6bbfb4" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +cliui@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.0.0.tgz#743d4650e05f36d1ed2575b59638d87322bfbbcc" + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +color-convert@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" + dependencies: + color-name "^1.1.1" + +color-name@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +compare-func@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648" + dependencies: + array-ify "^1.0.0" + dot-prop "^3.0.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +content-type-parser@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7" + +conventional-changelog-angular@^1.6.6: + version "1.6.6" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz#b27f2b315c16d0a1f23eb181309d0e6a4698ea0f" + dependencies: + compare-func "^1.3.1" + q "^1.5.1" + +conventional-changelog-atom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-atom/-/conventional-changelog-atom-2.0.0.tgz#cd6453469cfb8fc345af3391b92990251c95558b" + dependencies: + q "^1.5.1" + +conventional-changelog-cli@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-cli/-/conventional-changelog-cli-2.0.1.tgz#1bceb924a063b05757e131e93d6674bd7d3f5bc7" + dependencies: + add-stream "^1.0.0" + conventional-changelog "^2.0.1" + lodash "^4.2.1" + meow "^4.0.0" + tempfile "^1.1.1" + +conventional-changelog-codemirror@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.0.tgz#bfb61ccabacdd3bf8425a5cbe92276c86c5a0c1e" + dependencies: + q "^1.5.1" + +conventional-changelog-core@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-3.0.0.tgz#228bc97f436bbdde3fd6009557d16ce04497512c" + dependencies: + conventional-changelog-writer "^4.0.0" + conventional-commits-parser "^3.0.0" + dateformat "^3.0.0" + get-pkg-repo "^1.0.0" + git-raw-commits "^2.0.0" + git-remote-origin-url "^2.0.0" + git-semver-tags "^2.0.0" + lodash "^4.2.1" + normalize-package-data "^2.3.5" + q "^1.5.1" + read-pkg "^1.1.0" + read-pkg-up "^1.0.1" + through2 "^2.0.0" + +conventional-changelog-ember@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-ember/-/conventional-changelog-ember-2.0.0.tgz#4104571fc8871bcf08501a3d5252b25d1a9a070c" + dependencies: + q "^1.5.1" + +conventional-changelog-eslint@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.0.tgz#cc5376cb29a622c1ade197e155bf054640c05cd3" + dependencies: + q "^1.5.1" + +conventional-changelog-express@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-express/-/conventional-changelog-express-2.0.0.tgz#d3d020118fbfce21a75e025ec097101e355a2361" + dependencies: + q "^1.5.1" + +conventional-changelog-jquery@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-jquery/-/conventional-changelog-jquery-0.1.0.tgz#0208397162e3846986e71273b6c79c5b5f80f510" + dependencies: + q "^1.4.1" + +conventional-changelog-jscs@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-jscs/-/conventional-changelog-jscs-0.1.0.tgz#0479eb443cc7d72c58bf0bcf0ef1d444a92f0e5c" + dependencies: + q "^1.4.1" + +conventional-changelog-jshint@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.0.tgz#7a038330f485082e489f47f5d07539036949f87d" + dependencies: + compare-func "^1.3.1" + q "^1.5.1" + +conventional-changelog-preset-loader@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.0.0.tgz#69fea3db554d9b2a95dcaf7c603c1a0a389a7603" + +conventional-changelog-writer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.0.0.tgz#3ed983c8ef6a3aa51fe44e82c9c75e86f1b5aa42" + dependencies: + compare-func "^1.3.1" + conventional-commits-filter "^2.0.0" + dateformat "^3.0.0" + handlebars "^4.0.2" + json-stringify-safe "^5.0.1" + lodash "^4.2.1" + meow "^4.0.0" + semver "^5.5.0" + split "^1.0.0" + through2 "^2.0.0" + +conventional-changelog@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-2.0.1.tgz#0d8f0f9668eaeaa5edd612896e7f3cc4385b31c9" + dependencies: + conventional-changelog-angular "^1.6.6" + conventional-changelog-atom "^2.0.0" + conventional-changelog-codemirror "^2.0.0" + conventional-changelog-core "^3.0.0" + conventional-changelog-ember "^2.0.0" + conventional-changelog-eslint "^3.0.0" + conventional-changelog-express "^2.0.0" + conventional-changelog-jquery "^0.1.0" + conventional-changelog-jscs "^0.1.0" + conventional-changelog-jshint "^2.0.0" + conventional-changelog-preset-loader "^2.0.0" + +conventional-commits-filter@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.0.tgz#a0ce1d1ff7a1dd7fab36bee8e8256d348d135651" + dependencies: + is-subset "^0.1.1" + modify-values "^1.0.0" + +conventional-commits-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.0.0.tgz#7f604549a50bd8f60443fbe515484b1c2f06a5c4" + dependencies: + JSONStream "^1.0.4" + is-text-path "^1.0.0" + lodash "^4.2.1" + meow "^4.0.0" + split2 "^2.0.0" + through2 "^2.0.0" + trim-off-newlines "^1.0.0" + +convert-source-map@^1.4.0, convert-source-map@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" + +core-js@^2.4.0, core-js@^2.5.0: + version "2.5.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +cryptiles@3.x.x: + version "3.1.2" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" + dependencies: + boom "5.x.x" + +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b" + +"cssstyle@>= 0.2.37 < 0.3.0": + version "0.2.37" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-0.2.37.tgz#541097234cb2513c83ceed3acddc27ff27987d54" + dependencies: + cssom "0.3.x" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + dependencies: + array-find-index "^1.0.1" + +dargs@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17" + dependencies: + number-is-nan "^1.0.0" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +dateformat@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" + +debug@^2.2.0, debug@^2.6.8: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + +debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + +decamelize-keys@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + +decamelize@^1.0.0, decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +deep-extend@~0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +default-require-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" + dependencies: + strip-bom "^2.0.0" + +define-properties@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + dependencies: + foreach "^2.0.5" + object-keys "^1.0.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + +detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + +diff@^3.2.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" + +domexception@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + dependencies: + webidl-conversions "^4.0.2" + +dot-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" + dependencies: + is-obj "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + +error-ex@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + dependencies: + is-arrayish "^0.2.1" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.5.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + dependencies: + is-callable "^1.1.1" + is-date-object "^1.0.1" + is-symbol "^1.0.1" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +escodegen@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.0.tgz#9811a2f265dc1cd3894420ee3717064b632b8852" + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.5.6" + +esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + +esprima@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + +estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +exec-sh@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.1.tgz#163b98a6e89e6b65b47c2a28d215bc1f63989c38" + dependencies: + merge "^1.1.3" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +expect@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-22.1.0.tgz#f8f9b019ab275d859cbefed531fbaefe8972431d" + dependencies: + ansi-styles "^3.2.0" + jest-diff "^22.1.0" + jest-get-type "^22.1.0" + jest-matcher-utils "^22.1.0" + jest-message-util "^22.1.0" + jest-regex-util "^22.1.0" + +extend@~3.0.0, extend@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + +fast-deep-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +fb-watchman@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" + dependencies: + bser "^2.0.0" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + +fileset@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" + dependencies: + glob "^7.0.3" + minimatch "^3.0.3" + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +form-data@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8" + dependencies: + nan "^2.3.0" + node-pre-gyp "^0.6.39" + +fstream-ignore@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.0.2, function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +get-caller-file@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + +get-pkg-repo@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" + dependencies: + hosted-git-info "^2.1.4" + meow "^3.3.0" + normalize-package-data "^2.3.0" + parse-github-repo-url "^1.3.0" + through2 "^2.0.0" + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + dependencies: + assert-plus "^1.0.0" + +git-raw-commits@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.0.tgz#d92addf74440c14bcc5c83ecce3fb7f8a79118b5" + dependencies: + dargs "^4.0.1" + lodash.template "^4.0.2" + meow "^4.0.0" + split2 "^2.0.0" + through2 "^2.0.0" + +git-remote-origin-url@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" + dependencies: + gitconfiglocal "^1.0.0" + pify "^2.3.0" + +git-semver-tags@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-2.0.0.tgz#c218fd895bdf8e8e02f6bde555b2c3893ac73cd7" + dependencies: + meow "^4.0.0" + semver "^5.5.0" + +gitconfiglocal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" + dependencies: + ini "^1.3.2" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + +handlebars@^4.0.2, handlebars@^4.0.3: + version "4.0.11" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" + dependencies: + async "^1.4.0" + optimist "^0.6.1" + source-map "^0.4.4" + optionalDependencies: + uglify-js "^2.6" + +har-schema@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + +har-validator@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + dependencies: + ajv "^4.9.1" + har-schema "^1.0.5" + +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" + dependencies: + function-bind "^1.0.2" + +hash-sum@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" + +hawk@3.1.3, hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hawk@~6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" + dependencies: + boom "4.x.x" + cryptiles "3.x.x" + hoek "4.x.x" + sntp "2.x.x" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +hoek@4.x.x: + version "4.2.0" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + dependencies: + whatwg-encoding "^1.0.1" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +iconv-lite@0.4.19: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + +import-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" + dependencies: + pkg-dir "^2.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + dependencies: + repeating "^2.0.0" + +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@~2.0.0, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +ini@^1.3.2, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + +invariant@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-callable@^1.1.1, is-callable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" + +is-ci@^1.0.10: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5" + dependencies: + ci-info "^1.0.0" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-generator-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-subset@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" + +is-symbol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + +is-text-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" + dependencies: + text-extensions "^1.0.0" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +istanbul-api@^1.1.14: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.2.1.tgz#0c60a0515eb11c7d65c6b50bba2c6e999acd8620" + dependencies: + async "^2.1.4" + fileset "^2.0.2" + istanbul-lib-coverage "^1.1.1" + istanbul-lib-hook "^1.1.0" + istanbul-lib-instrument "^1.9.1" + istanbul-lib-report "^1.1.2" + istanbul-lib-source-maps "^1.2.2" + istanbul-reports "^1.1.3" + js-yaml "^3.7.0" + mkdirp "^0.5.1" + once "^1.4.0" + +istanbul-lib-coverage@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da" + +istanbul-lib-hook@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b" + dependencies: + append-transform "^0.4.0" + +istanbul-lib-instrument@^1.7.5, istanbul-lib-instrument@^1.8.0, istanbul-lib-instrument@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz#250b30b3531e5d3251299fdd64b0b2c9db6b558e" + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.18.0" + istanbul-lib-coverage "^1.1.1" + semver "^5.3.0" + +istanbul-lib-report@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz#922be27c13b9511b979bd1587359f69798c1d425" + dependencies: + istanbul-lib-coverage "^1.1.1" + mkdirp "^0.5.1" + path-parse "^1.0.5" + supports-color "^3.1.2" + +istanbul-lib-source-maps@^1.2.1, istanbul-lib-source-maps@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz#750578602435f28a0c04ee6d7d9e0f2960e62c1c" + dependencies: + debug "^3.1.0" + istanbul-lib-coverage "^1.1.1" + mkdirp "^0.5.1" + rimraf "^2.6.1" + source-map "^0.5.3" + +istanbul-reports@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.3.tgz#3b9e1e8defb6d18b1d425da8e8b32c5a163f2d10" + dependencies: + handlebars "^4.0.3" + +jest-changed-files@^22.1.4: + version "22.1.4" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-22.1.4.tgz#1f7844bcb739dec07e5899a633c0cb6d5069834e" + dependencies: + throat "^4.0.0" + +jest-cli@^22.1.4: + version "22.1.4" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-22.1.4.tgz#0fe9f3ac881b0cdc00227114c58583a2ebefcc04" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.1.11" + import-local "^1.0.0" + is-ci "^1.0.10" + istanbul-api "^1.1.14" + istanbul-lib-coverage "^1.1.1" + istanbul-lib-instrument "^1.8.0" + istanbul-lib-source-maps "^1.2.1" + jest-changed-files "^22.1.4" + jest-config "^22.1.4" + jest-environment-jsdom "^22.1.4" + jest-get-type "^22.1.0" + jest-haste-map "^22.1.0" + jest-message-util "^22.1.0" + jest-regex-util "^22.1.0" + jest-resolve-dependencies "^22.1.0" + jest-runner "^22.1.4" + jest-runtime "^22.1.4" + jest-snapshot "^22.1.2" + jest-util "^22.1.4" + jest-worker "^22.1.0" + micromatch "^2.3.11" + node-notifier "^5.1.2" + realpath-native "^1.0.0" + rimraf "^2.5.4" + slash "^1.0.0" + string-length "^2.0.0" + strip-ansi "^4.0.0" + which "^1.2.12" + yargs "^10.0.3" + +jest-config@^22.1.4: + version "22.1.4" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-22.1.4.tgz#075ffacce83c3e38cf85b1b9ba0d21bd3ee27ad0" + dependencies: + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^22.1.4" + jest-environment-node "^22.1.4" + jest-get-type "^22.1.0" + jest-jasmine2 "^22.1.4" + jest-regex-util "^22.1.0" + jest-resolve "^22.1.4" + jest-util "^22.1.4" + jest-validate "^22.1.2" + pretty-format "^22.1.0" + +jest-diff@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-22.1.0.tgz#0fad9d96c87b453896bf939df3dc8aac6919ac38" + dependencies: + chalk "^2.0.1" + diff "^3.2.0" + jest-get-type "^22.1.0" + pretty-format "^22.1.0" + +jest-docblock@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-22.1.0.tgz#3fe5986d5444cbcb149746eb4b07c57c5a464dfd" + dependencies: + detect-newline "^2.1.0" + +jest-environment-jsdom@^22.1.4: + version "22.1.4" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-22.1.4.tgz#704518ce8375f7ec5de048d1e9c4268b08a03e00" + dependencies: + jest-mock "^22.1.0" + jest-util "^22.1.4" + jsdom "^11.5.1" + +jest-environment-node@^22.1.4: + version "22.1.4" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-22.1.4.tgz#0f2946e8f8686ce6c5d8fa280ce1cd8d58e869eb" + dependencies: + jest-mock "^22.1.0" + jest-util "^22.1.4" + +jest-get-type@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.1.0.tgz#4e90af298ed6181edc85d2da500dbd2753e0d5a9" + +jest-haste-map@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-22.1.0.tgz#1174c6ff393f9818ebf1163710d8868b5370da2a" + dependencies: + fb-watchman "^2.0.0" + graceful-fs "^4.1.11" + jest-docblock "^22.1.0" + jest-worker "^22.1.0" + micromatch "^2.3.11" + sane "^2.0.0" + +jest-jasmine2@^22.1.4: + version "22.1.4" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-22.1.4.tgz#cada0baf50a220c616a9575728b80d4ddedebe8b" + dependencies: + callsites "^2.0.0" + chalk "^2.0.1" + co "^4.6.0" + expect "^22.1.0" + graceful-fs "^4.1.11" + is-generator-fn "^1.0.0" + jest-diff "^22.1.0" + jest-matcher-utils "^22.1.0" + jest-message-util "^22.1.0" + jest-snapshot "^22.1.2" + source-map-support "^0.5.0" + +jest-leak-detector@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-22.1.0.tgz#08376644cee07103da069baac19adb0299b772c2" + dependencies: + pretty-format "^22.1.0" + +jest-matcher-utils@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-22.1.0.tgz#e164665b5d313636ac29f7f6fe9ef0a6ce04febc" + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + pretty-format "^22.1.0" + +jest-message-util@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-22.1.0.tgz#51ba0794cb6e579bfc4e9adfac452f9f1a0293fc" + dependencies: + "@babel/code-frame" "^7.0.0-beta.35" + chalk "^2.0.1" + micromatch "^2.3.11" + slash "^1.0.0" + stack-utils "^1.0.1" + +jest-mock@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-22.1.0.tgz#87ec21c0599325671c9a23ad0e05c86fb5879b61" + +jest-regex-util@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-22.1.0.tgz#5daf2fe270074b6da63e5d85f1c9acc866768f53" + +jest-resolve-dependencies@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-22.1.0.tgz#340e4139fb13315cd43abc054e6c06136be51e31" + dependencies: + jest-regex-util "^22.1.0" + +jest-resolve@^22.1.4: + version "22.1.4" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-22.1.4.tgz#72b9b371eaac48f84aad4ad732222ffe37692602" + dependencies: + browser-resolve "^1.11.2" + chalk "^2.0.1" + +jest-runner@^22.1.4: + version "22.1.4" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-22.1.4.tgz#e039039110cb1b31febc0f99e349bf7c94304a2f" + dependencies: + exit "^0.1.2" + jest-config "^22.1.4" + jest-docblock "^22.1.0" + jest-haste-map "^22.1.0" + jest-jasmine2 "^22.1.4" + jest-leak-detector "^22.1.0" + jest-message-util "^22.1.0" + jest-runtime "^22.1.4" + jest-util "^22.1.4" + jest-worker "^22.1.0" + throat "^4.0.0" + +jest-runtime@^22.1.4: + version "22.1.4" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-22.1.4.tgz#1474d9f5cda518b702e0b25a17d4ef3fc563a20c" + dependencies: + babel-core "^6.0.0" + babel-jest "^22.1.0" + babel-plugin-istanbul "^4.1.5" + chalk "^2.0.1" + convert-source-map "^1.4.0" + exit "^0.1.2" + graceful-fs "^4.1.11" + jest-config "^22.1.4" + jest-haste-map "^22.1.0" + jest-regex-util "^22.1.0" + jest-resolve "^22.1.4" + jest-util "^22.1.4" + json-stable-stringify "^1.0.1" + micromatch "^2.3.11" + realpath-native "^1.0.0" + slash "^1.0.0" + strip-bom "3.0.0" + write-file-atomic "^2.1.0" + yargs "^10.0.3" + +jest-snapshot@^22.1.2: + version "22.1.2" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-22.1.2.tgz#b270cf6e3098f33aceeafda02b13eb0933dc6139" + dependencies: + chalk "^2.0.1" + jest-diff "^22.1.0" + jest-matcher-utils "^22.1.0" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^22.1.0" + +jest-util@^22.1.4: + version "22.1.4" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-22.1.4.tgz#ac8cbd43ee654102f1941f3f0e9d1d789a8b6a9b" + dependencies: + callsites "^2.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.11" + is-ci "^1.0.10" + jest-message-util "^22.1.0" + jest-validate "^22.1.2" + mkdirp "^0.5.1" + +jest-validate@^22.1.2: + version "22.1.2" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-22.1.2.tgz#c3b06bcba7bd9a850919fe336b5f2a8c3a239404" + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + leven "^2.1.0" + pretty-format "^22.1.0" + +jest-worker@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-22.1.0.tgz#0987832fe58fbdc205357f4c19b992446368cafb" + dependencies: + merge-stream "^1.0.1" + +jest@^22.1.4: + version "22.1.4" + resolved "https://registry.yarnpkg.com/jest/-/jest-22.1.4.tgz#9ec71373a38f40ff92a3e5e96ae85687c181bb72" + dependencies: + jest-cli "^22.1.4" + +js-tokens@^3.0.0, js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +js-yaml@^3.7.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +jsdom@^11.5.1: + version "11.6.2" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.6.2.tgz#25d1ef332d48adf77fc5221fe2619967923f16bb" + dependencies: + abab "^1.0.4" + acorn "^5.3.0" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + browser-process-hrtime "^0.1.2" + content-type-parser "^1.0.2" + cssom ">= 0.3.2 < 0.4.0" + cssstyle ">= 0.2.37 < 0.3.0" + domexception "^1.0.0" + escodegen "^1.9.0" + html-encoding-sniffer "^1.0.2" + left-pad "^1.2.0" + nwmatcher "^1.4.3" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.83.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.3" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-url "^6.4.0" + ws "^4.0.0" + xml-name-validator "^3.0.0" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json5@^0.5.0, json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +left-pad@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.2.0.tgz#d30a73c6b8201d8f7d8e7956ba9616087a68e0ee" + +leven@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +loader-utils@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash._reinterpolate@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + +lodash.template@^4.0.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" + dependencies: + lodash._reinterpolate "~3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316" + dependencies: + lodash._reinterpolate "~3.0.0" + +lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.4: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +lodash@^4.2.1: + version "4.17.10" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +loose-envify@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lru-cache@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + dependencies: + tmpl "1.0.x" + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + +map-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + +meow@^3.3.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +meow@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/meow/-/meow-4.0.1.tgz#d48598f6f4b1472f35bf6317a95945ace347f975" + dependencies: + camelcase-keys "^4.0.0" + decamelize-keys "^1.0.0" + loud-rejection "^1.0.0" + minimist "^1.1.3" + minimist-options "^3.0.1" + normalize-package-data "^2.3.4" + read-pkg-up "^3.0.0" + redent "^2.0.0" + trim-newlines "^2.0.0" + +merge-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + dependencies: + readable-stream "^2.0.1" + +merge@^1.1.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da" + +micromatch@^2.1.5, micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +mime-db@~1.30.0: + version "1.30.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.7: + version "2.1.17" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" + dependencies: + mime-db "~1.30.0" + +mimic-fn@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" + +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist-options@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + +"mkdirp@>=0.5 0", mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +modify-values@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +nan@^2.3.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + +node-notifier@^5.1.2: + version "5.2.1" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.2.1.tgz#fa313dd08f5517db0e2502e5758d664ac69f9dea" + dependencies: + growly "^1.3.0" + semver "^5.4.1" + shellwords "^0.1.1" + which "^1.3.0" + +node-pre-gyp@^0.6.39: + version "0.6.39" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" + dependencies: + detect-libc "^1.0.2" + hawk "3.1.3" + mkdirp "^0.5.1" + nopt "^4.0.1" + npmlog "^4.0.2" + rc "^1.1.7" + request "2.81.0" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^2.2.1" + tar-pack "^3.4.0" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.0, normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +nwmatcher@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.3.tgz#64348e3b3d80f035b40ac11563d278f8b72db89c" + +oauth-sign@~0.8.1, oauth-sign@~0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object-keys@^1.0.8: + version "1.0.11" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +once@^1.3.0, once@^1.3.3, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optionator@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +p-limit@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + +parse-github-repo-url@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + dependencies: + pify "^3.0.0" + +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + dependencies: + find-up "^2.1.0" + +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +pretty-format@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-22.1.0.tgz#2277605b40ed4529ae4db51ff62f4be817647914" + dependencies: + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" + +private@^0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +punycode@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + +q@^1.4.1, q@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + +qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + +qs@~6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + +quick-lru@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" + +randomatic@^1.1.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +rc@^1.1.7: + version "1.2.4" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.4.tgz#a0f606caae2a3b862bbd0ef85482c0125b315fa3" + dependencies: + deep-extend "~0.4.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg@^1.0.0, read-pkg@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.1.4: + version "2.3.3" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + safe-buffer "~5.1.1" + string_decoder "~1.0.3" + util-deprecate "~1.0.1" + +readable-stream@^2.1.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +realpath-native@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.0.tgz#7885721a83b43bd5327609f0ddecb2482305fdf0" + dependencies: + util.promisify "^1.0.0" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +redent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" + dependencies: + indent-string "^3.0.0" + strip-indent "^2.0.0" + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + dependencies: + is-equal-shallow "^0.1.3" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + dependencies: + lodash "^4.13.1" + +request-promise-native@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" + dependencies: + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + +request@2.81.0: + version "2.81.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~4.2.1" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + performance-now "^0.2.0" + qs "~6.4.0" + safe-buffer "^5.0.1" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "^0.6.0" + uuid "^3.0.0" + +request@^2.83.0: + version "2.83.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + har-validator "~5.0.3" + hawk "~6.0.2" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + stringstream "~0.0.5" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + dependencies: + resolve-from "^3.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +rimraf@2, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + +safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + +sane@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-2.3.0.tgz#3f3df584abf69e63d4bb74f0f8c42468e4d7d46b" + dependencies: + anymatch "^1.3.0" + exec-sh "^0.2.0" + fb-watchman "^2.0.0" + minimatch "^3.0.2" + minimist "^1.1.1" + walker "~1.0.5" + watch "~0.18.0" + optionalDependencies: + fsevents "^1.1.1" + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +sntp@2.x.x: + version "2.1.0" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" + dependencies: + hoek "4.x.x" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + +source-map-support@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.3.tgz#2b3d5fff298cfa4d1afd7d4352d569e9a0158e76" + dependencies: + source-map "^0.6.0" + +source-map@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + +spdx-license-ids@^1.0.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + +split2@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" + dependencies: + through2 "^2.0.2" + +split@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + dependencies: + through "2" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +sshpk@^1.7.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +stack-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" + +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + +string-length@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" + dependencies: + astral-regex "^1.0.0" + strip-ansi "^4.0.0" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^2.0.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" + dependencies: + safe-buffer "~5.1.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + dependencies: + safe-buffer "~5.1.0" + +stringstream@~0.0.4, stringstream@~0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-bom@3.0.0, strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + dependencies: + get-stdin "^4.0.1" + +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^3.1.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + dependencies: + has-flag "^1.0.0" + +supports-color@^4.0.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" + dependencies: + has-flag "^2.0.0" + +symbol-tree@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" + +tar-pack@^3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" + dependencies: + debug "^2.2.0" + fstream "^1.0.10" + fstream-ignore "^1.0.5" + once "^1.3.3" + readable-stream "^2.1.4" + rimraf "^2.5.1" + tar "^2.2.1" + uid-number "^0.0.6" + +tar@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +tempfile@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-1.1.1.tgz#5bcc4eaecc4ab2c707d8bc11d99ccc9a2cb287f2" + dependencies: + os-tmpdir "^1.0.0" + uuid "^2.0.1" + +test-exclude@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26" + dependencies: + arrify "^1.0.1" + micromatch "^2.3.11" + object-assign "^4.1.0" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + +text-extensions@^1.0.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.7.0.tgz#faaaba2625ed746d568a23e4d0aacd9bf08a8b39" + +throat@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + +through2@^2.0.0, through2@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +through@2, "through@>=2.2.7 <3": + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + +tough-cookie@>=2.3.3, tough-cookie@^2.3.3, tough-cookie@~2.3.0, tough-cookie@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" + dependencies: + punycode "^1.4.1" + +tr46@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + dependencies: + punycode "^2.1.0" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + +trim-newlines@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" + +trim-off-newlines@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +uglify-js@^2.6: + version "2.8.29" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + dependencies: + source-map "~0.5.1" + yargs "~3.10.0" + optionalDependencies: + uglify-to-browserify "~1.0.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +uid-number@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +util.promisify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +uuid@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + +uuid@^3.0.0, uuid@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" + +validate-npm-package-license@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + dependencies: + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +w3c-hr-time@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + dependencies: + browser-process-hrtime "^0.1.2" + +walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + dependencies: + makeerror "1.0.x" + +watch@~0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" + dependencies: + exec-sh "^0.2.0" + minimist "^1.2.0" + +webidl-conversions@^4.0.1, webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz#57c235bc8657e914d24e1a397d3c82daee0a6ba3" + dependencies: + iconv-lite "0.4.19" + +whatwg-url@^6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.4.0.tgz#08fdf2b9e872783a7a1f6216260a1d66cc722e08" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.0" + webidl-conversions "^4.0.1" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + +which@^1.2.12, which@^1.2.9, which@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" + dependencies: + string-width "^1.0.2" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write-file-atomic@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +ws@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-4.0.0.tgz#bfe1da4c08eeb9780b986e0e4d10eccd7345999f" + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + +xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yargs-parser@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950" + dependencies: + camelcase "^4.1.0" + +yargs@^10.0.3: + version "10.1.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.1.2.tgz#454d074c2b16a51a43e2fb7807e4f9de69ccb5c5" + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^8.1.0" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" diff --git a/packages/vue-cli-plugin-uni/packages/h5-vue/LICENSE b/packages/vue-cli-plugin-uni/packages/h5-vue/LICENSE new file mode 100644 index 000000000..b65dd9e62 --- /dev/null +++ b/packages/vue-cli-plugin-uni/packages/h5-vue/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013-present, Yuxi (Evan) You + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/vue-cli-plugin-uni/packages/h5-vue/README.md b/packages/vue-cli-plugin-uni/packages/h5-vue/README.md new file mode 100644 index 000000000..c89a48c66 --- /dev/null +++ b/packages/vue-cli-plugin-uni/packages/h5-vue/README.md @@ -0,0 +1,264 @@ +

Vue logo

+ +

+ Build Status + Coverage Status + Downloads + Version + License + Chat +
+ Sauce Test Status +

+ +

Supporting Vue.js

+ +Vue.js is an MIT-licensed open source project. It's an independent project with its ongoing development made possible entirely thanks to the support by these awesome [backers](https://github.com/vuejs/vue/blob/dev/BACKERS.md). If you'd like to join them, please consider: + +- [Become a backer or sponsor on Patreon](https://www.patreon.com/evanyou). +- [Become a backer or sponsor on Open Collective](https://opencollective.com/vuejs). +- [One-time donation via PayPal or crypto-currencies.](https://vuejs.org/support-vuejs/#One-time-Donations) + +#### What's the difference between Patreon and OpenCollective? + +Funds donated via Patreon go directly to support Evan You's full-time work on Vue.js. Funds donated via OpenCollective are managed with transparent expenses and will be used for compensating work and expenses for core team members or sponsoring community events. Your name/logo will receive proper recognition and exposure by donating on either platform. + +

Special Sponsors

+ + + + + + + + + +
+ + + + + + + + + + + +
+ + +

Sponsors via Patreon

+ +

Platinum

+ + + + + + + + + + +
+ + + + + + + + + + + +
+ + +

Gold

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + +

Sponsors via Open Collective

+ +

Platinum

+ + + + +

Gold

+ + + + + + + +--- + +## Introduction + +Vue (pronounced `/vjuː/`, like view) is a **progressive framework** for building user interfaces. It is designed from the ground up to be incrementally adoptable, and can easily scale between a library and a framework depending on different use cases. It consists of an approachable core library that focuses on the view layer only, and an ecosystem of supporting libraries that helps you tackle complexity in large Single-Page Applications. + +#### Browser Compatibility + +Vue.js supports all browsers that are [ES5-compliant](http://kangax.github.io/compat-table/es5/) (IE8 and below are not supported). + +## Ecosystem + +| Project | Status | Description | +|---------|--------|-------------| +| [vue-router] | [![vue-router-status]][vue-router-package] | Single-page application routing | +| [vuex] | [![vuex-status]][vuex-package] | Large-scale state management | +| [vue-cli] | [![vue-cli-status]][vue-cli-package] | Project scaffolding | +| [vue-loader] | [![vue-loader-status]][vue-loader-package] | Single File Component (`*.vue` file) loader for webpack | +| [vue-server-renderer] | [![vue-server-renderer-status]][vue-server-renderer-package] | Server-side rendering support | +| [vue-class-component] | [![vue-class-component-status]][vue-class-component-package] | TypeScript decorator for a class-based API | +| [vue-rx] | [![vue-rx-status]][vue-rx-package] | RxJS integration | +| [vue-devtools] | [![vue-devtools-status]][vue-devtools-package] | Browser DevTools extension | + +[vue-router]: https://github.com/vuejs/vue-router +[vuex]: https://github.com/vuejs/vuex +[vue-cli]: https://github.com/vuejs/vue-cli +[vue-loader]: https://github.com/vuejs/vue-loader +[vue-server-renderer]: https://github.com/vuejs/vue/tree/dev/packages/vue-server-renderer +[vue-class-component]: https://github.com/vuejs/vue-class-component +[vue-rx]: https://github.com/vuejs/vue-rx +[vue-devtools]: https://github.com/vuejs/vue-devtools + +[vue-router-status]: https://img.shields.io/npm/v/vue-router.svg +[vuex-status]: https://img.shields.io/npm/v/vuex.svg +[vue-cli-status]: https://img.shields.io/npm/v/vue-cli.svg +[vue-loader-status]: https://img.shields.io/npm/v/vue-loader.svg +[vue-server-renderer-status]: https://img.shields.io/npm/v/vue-server-renderer.svg +[vue-class-component-status]: https://img.shields.io/npm/v/vue-class-component.svg +[vue-rx-status]: https://img.shields.io/npm/v/vue-rx.svg +[vue-devtools-status]: https://img.shields.io/chrome-web-store/v/nhdogjmejiglipccpnnnanhbledajbpd.svg + +[vue-router-package]: https://npmjs.com/package/vue-router +[vuex-package]: https://npmjs.com/package/vuex +[vue-cli-package]: https://npmjs.com/package/vue-cli +[vue-loader-package]: https://npmjs.com/package/vue-loader +[vue-server-renderer-package]: https://npmjs.com/package/vue-server-renderer +[vue-class-component-package]: https://npmjs.com/package/vue-class-component +[vue-rx-package]: https://npmjs.com/package/vue-rx +[vue-devtools-package]: https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd + +## Documentation + +To check out [live examples](https://vuejs.org/v2/examples/) and docs, visit [vuejs.org](https://vuejs.org). + +## Questions + +For questions and support please use the [the official forum](http://forum.vuejs.org) or [community chat](https://chat.vuejs.org/). The issue list of this repo is **exclusively** for bug reports and feature requests. + +## Issues + +Please make sure to read the [Issue Reporting Checklist](https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#issue-reporting-guidelines) before opening an issue. Issues not conforming to the guidelines may be closed immediately. + +## Changelog + +Detailed changes for each release are documented in the [release notes](https://github.com/vuejs/vue/releases). + +## Stay In Touch + +- [Twitter](https://twitter.com/vuejs) +- [Blog](https://medium.com/the-vue-point) +- [Job Board](https://vuejobs.com/?ref=vuejs) + +## Contribution + +Please make sure to read the [Contributing Guide](https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md) before making a pull request. If you have a Vue-related project/component/tool, add it with a pull request to [this curated list](https://github.com/vuejs/awesome-vue)! + +Thank you to all the people who already contributed to Vue! + + + + +## License + +[MIT](http://opensource.org/licenses/MIT) + +Copyright (c) 2013-present, Yuxi (Evan) You diff --git a/packages/vue-cli-plugin-uni/packages/h5-vue/dist/README.md b/packages/vue-cli-plugin-uni/packages/h5-vue/dist/README.md new file mode 100644 index 000000000..fc0e9ddf0 --- /dev/null +++ b/packages/vue-cli-plugin-uni/packages/h5-vue/dist/README.md @@ -0,0 +1,124 @@ +## Explanation of Build Files + +| | UMD | CommonJS | ES Module | +| --- | --- | --- | --- | +| **Full** | vue.js | vue.common.js | vue.esm.js | +| **Runtime-only** | vue.runtime.js | vue.runtime.common.js | vue.runtime.esm.js | +| **Full (production)** | vue.min.js | | | +| **Runtime-only (production)** | vue.runtime.min.js | | | + +### Terms + +- **Full**: builds that contains both the compiler and the runtime. + +- **Compiler**: code that is responsible for compiling template strings into JavaScript render functions. + +- **Runtime**: code that is responsible for creating Vue instances, rendering and patching virtual DOM, etc. Basically everything minus the compiler. + +- **[UMD](https://github.com/umdjs/umd)**: UMD builds can be used directly in the browser via a ` + + + + + +

Debugging mode -

+ +

+ +

+ +``` + +```js +var configValue = '/* @echo FOO */' || 'default value'; + +// @ifdef DEBUG +someDebuggingCall() +// @endif + +``` + +## Directive syntax + +### Basic example + +The most basic usage is for files that only have two states, non-processed and processed. +In this case, your `@exclude` directives are removed after preprocessing + +```html + + +
You're on dev!
+ + +``` + +After build + +```html + + +``` + +### All directives + + - `@if VAR='value'` / `@endif` + This will include the enclosed block if your test passes + - `@ifdef VAR` / `@endif` + This will include the enclosed block if VAR is defined (typeof !== 'undefined') + - `@ifndef VAR` / `@endif` + This will include the enclosed block if VAR is not defined (typeof === 'undefined') + - `@include` + This will include the source from an external file. If the included source ends with a newline then the + following line will be space indented to the level the @include was found. + - `@include-static` + Works the same way as `@include` but doesn't process the included file recursively. Is useful if a large + file has to be included and the recursive processing is not necessary or would otherwise take too long. + - `@extend file.html` / `@endextend` + This will use the source from the external file indicated with the `@extend` tag to wrap the enclosed block. + - `@extendable` + This tag is used to indicate the location in a file referenced using `@extend` where the block enclosed by `@extend` will be populated. + - `@exclude` / `@endexclude` + This will remove the enclosed block upon processing + - `@echo VAR` + This will include the environment variable VAR into your source + - `@foreach $VAR in ARR` / `@endfor` + This will repeat the enclosed block for each value in the Array or Object in ARR. Each value in ARR can be interpolated into the resulting content with $VAR. + - `@exec FUNCTION([param1, param2...])` + This will execute the environment FUNCTION with its parameters and echo the result into your source. The parameter + could be a string or a reference to another environment variable. + +### Extended html Syntax + +This is useful for more fine grained control of your files over multiple +environment configurations. You have access to simple tests of any variable within the context (or ENV, if not supplied) + +```html + + +
You're on dev!
+ + + + + + + + + + +``` + +With a `NODE_ENV` set to `production` and `0xDEADBEEF` in +`COMMIT_HASH` this will be built to look like + +```html + + + + + + + +``` + +With NODE_ENV not set or set to dev and nothing in COMMIT_HASH, +the built file will be + +```html + +
You're on dev!
+ + + + + +``` + +You can also have conditional blocks that are hidden by default by using the +fictional `!>` end tag instead of `-->` after your condition: + +```html + +``` + +### JavaScript, CSS, C, Java Syntax + +Extended syntax below, but will work without specifying a test + +```js +normalFunction(); +//@exclude +superExpensiveDebugFunction() +//@endexclude + +anotherFunction('/* @echo USERNAME */'); +``` + +Built with a NODE_ENV of production : + +```js +normalFunction(); + +anotherFunction('jsoverson'); +``` + +Like HTML, you can have conditional blocks that are hidden by default by ending the directive with a `**` instead of `*/` + +```js +angular.module('myModule', ['dep1' + , 'dep2' + /* @if NODE_ENV='production' ** + , 'prod_dep' + /* @endif */ + /* @exclude ** + , 'debug_dep' + /* @endexclude */ +]); + +``` + +_Note: Hidden by default blocks only work with block comments (`/* */`) but not with line comments (`//`)._ + +CSS example + +```css +body { +/* @if NODE_ENV=='development' */ + background-color: red; +/* @endif */ + +} +// @include util.css +``` + +(CSS preprocessing supports single line comment style directives) + + + +### Shell, PHP + +```bash +#!/bin/bash + +# @include util.sh +``` + +## API + +### preprocess(source[, context[, options]]) -> preprocessedSource + +Preprocesses a source provided as a string and returns the preprocessed source. + +#### source +Type: `String` (mandatory) + +The source to preprocess. + +#### context +Type: `Object` +Default: `process.env` + +The context that contains the variables that are used in the source. For `@extend` variants and `@include` the additional +context property `src` is available inside of files to be included that contains the current file name. This property is also +available in the context of the source file if one of the `preprocessFile*()` API variants are used. + +#### options +Type: `Object` + +The options object allows to pass additional options to `preprocess`. Available options are: + +##### options.fileNotFoundSilentFail +Type: `Boolean` +Default: `false` + +When using `@include` variants and `@extend`, `preprocess` will by default throw an exception in case an included +file can't be found. Set this option to `true` to instruct `preprocess` to fail silently and instead of throwing +to write a message inside of the preprocessed file that an included file could not be found. + +##### options.srcDir +Type: `String` +Default: `process.cwd()` + +The directory where to look for files included via `@include` variants and `@extend`. + +##### options.srcEol +Type: `String` +Default: EOL of source string or `os.EOL` if source string contains multiple different or no EOLs. + +The end of line (EOL) character to use for the preprocessed result. May be one of: + - `\r\n` - Windows + - `\n` - Linux/OSX/Unix + - `\r` - legacy Mac + +##### options.type +Type: `String` +Default: `html` + +The syntax type of source string to preprocess. There are 3 main syntax variants: + - `html`, aliases: `xml` + - `js`, aliases: `javascript`, `jsx`, `c`, `cc`, `cpp`, `cs`, `csharp`, `java`, `less`, `sass`, `scss`, `css`, `php`, + `ts`, `tsx`, `peg`, `pegjs`, `jade`, `styl` + - `coffee`, aliases: `bash`, `shell`, `sh` + +### preprocessFile(srcFile, destFile[, context[, callback[, options]]]) + +Preprocesses a `sourceFile` and saves the result to `destFile`. Simple wrapper around `fs.readFile()` and `fs.writeFile()`. + +#### srcFile +Type: `String` (mandatory) + +The path to the source file to preprocess. + +#### destFile +Type: `String` (mandatory) + +The path to the destination file where the preprocessed result shall be saved. + +#### context +See `context` [attribute description](#context) of `preprocess()` function. + +#### callback +Type: `function(err)` + +The callback function that is called upon error or completion. Receives an error if something goes wrong as first parameter. + +#### options +See `options` [attribute description](#options) of `preprocess()` function. Differs only in that the default `srcDir` value is set +to the path of the provided source file instead of `process.cwd()` and the default `type` is derived from source file extension. + + +### preprocessFileSync(srcFile, destFile[, context[, options]]) + +Preprocesses a `sourceFile` and saves the result to `destFile`. Simple wrapper around `fs.readFileSync()` and `fs.writeFileSync()`. + +#### srcFile +Type: `String` (mandatory) + +The path to the source file to preprocess. + +#### destFile +Type: `String` (mandatory) + +The path to the destination file where the preprocessed result shall be saved. + +#### context +See `context` [attribute description](#context) of `preprocess()` function. + +#### options +See `options` [attribute description](#options) of `preprocess()` function. Differs only in that the default `srcDir` value is set +to the path of the provided source file instead of `process.cwd()` and the default `type` is derived from source file extension. + +## Usage Examples + +```js +var pp = require('preprocess'); + +var text = 'Hi, I am '; + +pp.preprocess(text); +// -> Hi, I am jsoverson + +pp.preprocess(text, {USERNAME : "Bob"}); +// -> Hi, I am Bob + +// specify the format to use for the directives as the third parameter +pp.preprocess(text, {USERNAME : "Bob"}, {type: 'html'}); +// -> Hi, I am Bob + +// Preprocess files asynchronously +pp.preprocessFile(src, dest, context, callback, options); + +// Preprocess files synchronously +pp.preprocessFileSync(src, dest, context, options); +``` + +## Contributing +In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or +changed functionality. Lint and test your code using jshint + +## Release History + - 3.1.0 + - Added `.jsx` file extension as an alias for `js` (@BendingBender, #79) + - Added `.tsx` file extension as an alias for `js` (@rosendi, #100) + - Bumped XRegExp to v3 + + - 3.0.1/2 Fixes for backward compatibility and regex cleanups (thanks to @anseki for suggestions, #77) + - 3.0.0 + + Breaking changes: + - If a file requested by `@include` or `@extend` can not be found, `preprocess` will now throw by default + with a possibility to opt in to the legacy behavior via the `fileNotFoundSilentFail` option (@BendingBender, #35). + - Fixed multiple issues with newlines (@BendingBender, #8), this may result in output that differs from earlier + versions. + - The `srcDir` option was moved to the options object and now defaults to `process.cwd` instead of throwing by + default (@BendingBender, #68) + + New functionality: + - All block directives (ones that have a start and an end token, like `@if`/`@endif`) are now processed recursively (@Frizi, #61) + - Added hidden by default configuration blocks for `js` (@mallowigi, #40) and `html` (@Frizi, #66) + + Fixes: + - fixed `@exec` in files included via `@include` and `@extend` (@BendingBender, #58) + - changed `@extend` and `@exclude` html regex so that directives may appear more than once in one line (@BendingBender, #36) + - fixed multiple issues with coffescript syntax (@BendingBender, #39) + - fixed `@if` and `@foreach` to not require trailing whitespace (@BendingBender, #74) + + - 2.3.1 Fixed @echo and @exec directives to allow `-` and `*` characters, fixed @exec with multiple params (@BendingBender, #21, #45, #51, #54). + - 2.3.0 Added support for @include-static (@BendingBender) + - 2.2.0 Added support for @foreach and @extend (@orionstein) + - 2.1.1 Added support for .styl files via js regex (@nsonnad) + - 2.1.0 Added automatic support for numerous formats, merged @exec, hidden by default html tags, added simple directives + - 2.0.0 Added ability to echo strings, added conditional comments, removed lodash, merged 17, 13, 15, 16 + - 1.2.0 Added processing for hash-style comments (@marsch). Added more file aliases. + - 1.1.0 Added deep inclusion, fixed sequential ifs + - 1.0.1 Fixed multiple inline echo statements + - 1.0.0 Pulled from grunt-preprocess to stand alone + +## License + +Copyright Jarrod Overson + +Written by Jarrod Overson + +Licensed under the Apache 2.0 license. + +[npm-image]: https://nodei.co/npm/preprocess.png?downloads=true +[npm-url]: https://www.npmjs.com/package/preprocess +[linux-ci-image]: https://img.shields.io/travis/jsoverson/preprocess/master.svg?style=flat-square&label=Linux%20build +[linux-ci-url]: https://travis-ci.org/jsoverson/preprocess +[windows-ci-image]: https://img.shields.io/appveyor/ci/BendingBender/preprocess/master.svg?style=flat-square&label=Windows%20build +[windows-ci-url]: https://ci.appveyor.com/project/BendingBender/preprocess +[deps-image]: https://img.shields.io/david/jsoverson/preprocess.svg?style=flat-square +[deps-url]: https://david-dm.org/jsoverson/preprocess +[dev-deps-image]: https://img.shields.io/david/dev/jsoverson/preprocess.svg?style=flat-square +[dev-deps-url]: https://david-dm.org/jsoverson/preprocess#info=devDependencies +[coverage-image]: https://img.shields.io/coveralls/jsoverson/preprocess/master.svg?style=flat-square +[coverage-url]: https://coveralls.io/r/jsoverson/preprocess?branch=master diff --git a/packages/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess/lib/preprocess.js b/packages/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess/lib/preprocess.js new file mode 100755 index 000000000..0c3be9731 --- /dev/null +++ b/packages/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess/lib/preprocess.js @@ -0,0 +1,431 @@ +/* + * preprocess + * https://github.com/onehealth/preprocess + * + * Copyright (c) 2012 OneHealth Solutions, Inc. + * Written by Jarrod Overson - http://jarrodoverson.com/ + * Licensed under the Apache 2.0 license. + */ + +'use strict' + +exports.preprocess = preprocess +exports.preprocessFile = preprocessFile +exports.preprocessFileSync = preprocessFileSync + +var path = require('path') + +var fs = require('fs') + +var os = require('os') + +var delim = require('./regexrules') + +var XRegExp = require('xregexp') + +function preprocessFile (srcFile, destFile, context, callback, options) { + options = getOptionsForFile(srcFile, options) + context.src = srcFile + + fs.readFile(srcFile, function (err, data) { + if (err) return callback(err, data) + var parsed = preprocess(data, context, options) + fs.writeFile(destFile, parsed, callback) + }) +} + +function preprocessFileSync (srcFile, destFile, context, options) { + options = getOptionsForFile(srcFile, options) + context.src = srcFile + + var data = fs.readFileSync(srcFile) + var parsed = preprocess(data, context, options) + return fs.writeFileSync(destFile, parsed) +} + +function getOptionsForFile (srcFile, options) { + options = options || {} + options.srcDir = options.srcDir || path.dirname(srcFile) + options.type = options.type || getExtension(srcFile) + + return options +} + +function getExtension (filename) { + var ext = path.extname(filename || '').split('.') + return ext[ext.length - 1] +} + +function preprocess (src, context, typeOrOptions) { + src = src.toString() + context = context || process.env + + // default values + var options = { + fileNotFoundSilentFail: false, + srcDir: process.cwd(), + srcEol: getEolType(src), + type: delim['html'] + } + + // needed for backward compatibility with 2.x.x series + if (typeof typeOrOptions === 'string') { + typeOrOptions = { + type: typeOrOptions + } + } + + // needed for backward compatibility with 2.x.x series + if (typeof context.srcDir === 'string') { + typeOrOptions = typeOrOptions || {} + typeOrOptions.srcDir = context.srcDir + } + + if (typeOrOptions && typeof typeOrOptions === 'object') { + options.srcDir = typeOrOptions.srcDir || options.srcDir + options.fileNotFoundSilentFail = typeOrOptions.fileNotFoundSilentFail || options.fileNotFoundSilentFail + options.srcEol = typeOrOptions.srcEol || options.srcEol + options.type = delim[typeOrOptions.type] || options.type + } + + context = copy(context) + + return preprocessor(src, context, options) +} + +function preprocessor (src, context, opts, noRestoreEol) { + src = normalizeEol(src) + + var rv = src + + rv = replace(rv, opts.type.include, processIncludeDirective.bind(null, false, context, opts)) + + if (opts.type.extend) { + rv = replaceRecursive(rv, opts.type.extend, function (startMatches, endMatches, include, recurse) { + var file = (startMatches[1] || '').trim() + var extendedContext = copy(context) + var extendedOpts = copy(opts) + extendedContext.src = path.join(opts.srcDir, file) + extendedOpts.srcDir = path.dirname(extendedContext.src) + + var fileContents = getFileContents(extendedContext.src, opts.fileNotFoundSilentFail, context.src) + if (fileContents.error) { + return fileContents.contents + } + + var extendedSource = preprocessor(fileContents.contents, extendedContext, extendedOpts, true).trim() + + if (extendedSource) { + include = include.replace(/^\n?|\n?$/g, '') + return replace(extendedSource, opts.type.extendable, recurse(include)) + } else { + return '' + } + }) + } + + if (opts.type.foreach) { + rv = replaceRecursive(rv, opts.type.foreach, function (startMatches, endMatches, include, recurse) { + var variable = (startMatches[1] || '').trim() + var forParams = variable.split(' ') + if (forParams.length === 3) { + var contextVar = forParams[2] + var arrString = getDeepPropFromObj(context, contextVar) + var eachArr + if (arrString.match(/\{(.*)\}/)) { + eachArr = JSON.parse(arrString) + } else if (arrString.match(/\[(.*)\]/)) { + eachArr = arrString.slice(1, -1) + eachArr = eachArr.split(',') + eachArr = eachArr.map(function (arrEntry) { + return arrEntry.replace(/\s*(['"])(.*)\1\s*/, '$2') + }) + } else { + eachArr = arrString.split(',') + } + + var replaceToken = new RegExp(XRegExp.escape(forParams[0]), 'g') + var recursedInclude = recurse(include) + + return Object.keys(eachArr).reduce(function (stringBuilder, arrKey) { + var arrEntry = eachArr[arrKey] + return stringBuilder + recursedInclude.replace(replaceToken, arrEntry) + }, '') + } else { + return '' + } + }) + } + + if (opts.type.exclude) { + rv = replaceRecursive(rv, opts.type.exclude, function (startMatches, endMatches, include, recurse) { + var test = (startMatches[1] || '').trim() + return testPasses(test, context) ? '' : recurse(include) + }) + } + + if (opts.type.if) { + rv = replaceRecursive(rv, opts.type.if, function (startMatches, endMatches, include, recurse) { + var variant = startMatches[1] + var test = (startMatches[2] || '').trim() + switch (variant) { + case 'if': + case 'ifdef': + return testPasses(test, context) ? (padContent(startMatches.input) + recurse(include) + padContent(endMatches.input)) : padContent(startMatches.input + include + endMatches.input) + case 'ifndef': + return !testPasses(test, context) ? (padContent(startMatches.input) + recurse(include) + padContent(endMatches.input)) : padContent(startMatches.input + include + endMatches.input) +// case 'ifdef': +// return typeof getDeepPropFromObj(context, test) !== 'undefined' ? (padContent(startMatches.input) + recurse(include) + padContent(endMatches.input)) : padContent(startMatches.input + include + endMatches.input) // fixed by xxxxxx +// case 'ifndef': +// return typeof getDeepPropFromObj(context, test) === 'undefined' ? (padContent(startMatches.input) + recurse(include) + padContent(endMatches.input)) : padContent(startMatches.input + include + endMatches.input) // fixed by xxxxxx + default: + throw new Error('Unknown if variant ' + variant + '.') + } + }) + } + + rv = replace(rv, opts.type.echo, function (match, variable) { + variable = (variable || '').trim() + // if we are surrounded by quotes, echo as a string + var stringMatch = variable.match(/^(['"])(.*)\1$/) + if (stringMatch) return stringMatch[2] + + return getDeepPropFromObj(context, (variable || '').trim()) + }) + + rv = replace(rv, opts.type.exec, function (match, name, value) { + name = (name || '').trim() + value = value || '' + + var params = value.split(',') + var stringRegex = /^['"](.*)['"]$/ + + params = params.map(function (param) { + param = param.trim() + if (stringRegex.test(param)) { // handle string parameter + return param.replace(stringRegex, '$1') + } else { // handle variable parameter + return getDeepPropFromObj(context, param) + } + }) + + var fn = getDeepPropFromObj(context, name) + if (!fn || typeof fn !== 'function') return '' + + return fn.apply(context, params) + }) + + rv = replace(rv, opts.type['include-static'], processIncludeDirective.bind(null, true, context, opts)) + + if (!noRestoreEol) { + rv = restoreEol(rv, opts.srcEol) + } + + return rv +} +var splitRE = /\r?\n/g + +function padContent (content) { + return Array(content.split(splitRE).length).join('\n') +} + +function getEolType (source) { + var eol + var foundEolTypeCnt = 0 + + if (source.indexOf('\r\n') >= 0) { + eol = '\r\n' + foundEolTypeCnt++ + } + if (/\r[^\n]/.test(source)) { + eol = '\r' + foundEolTypeCnt++ + } + if (/[^\r]\n/.test(source)) { + eol = '\n' + foundEolTypeCnt++ + } + + if (eol == null || foundEolTypeCnt > 1) { + eol = os.EOL + } + + return eol +} + +function normalizeEol (source, indent) { + // only process any kind of EOL if indentation has to be added, otherwise replace only non \n EOLs + if (indent) { + source = source.replace(/(?:\r?\n)|\r/g, '\n' + indent) + } else { + source = source.replace(/(?:\r\n)|\r/g, '\n') + } + + return source +} + +function restoreEol (normalizedSource, originalEol) { + if (originalEol !== '\n') { + normalizedSource = normalizedSource.replace(/\n/g, originalEol) + } + + return normalizedSource +} + +function replace (rv, rule, processor) { + var isRegex = typeof rule === 'string' || rule instanceof RegExp + var isArray = Array.isArray(rule) + + if (isRegex) { + rule = [new RegExp(rule, 'gmi')] + } else if (isArray) { + rule = rule.map(function (subRule) { + return new RegExp(subRule, 'gmi') + }) + } else { + throw new Error('Rule must be a String, a RegExp, or an Array.') + } + + return rule.reduce(function (rv, rule) { + return rv.replace(rule, processor) + }, rv) +} + +function replaceRecursive (rv, rule, processor) { + if (!rule.start || !rule.end) { + throw new Error('Recursive rule must have start and end.') + } + + var startRegex = new RegExp(rule.start, 'mi') + var endRegex = new RegExp(rule.end, 'mi') + + function matchReplacePass (content) { + var matches = XRegExp.matchRecursive(content, rule.start, rule.end, 'gmi', { + valueNames: ['between', 'left', 'match', 'right'] + }) + + var matchGroup = { + left: null, + match: null, + right: null + } + + return matches.reduce(function (builder, match) { + switch (match.name) { + case 'between': + builder += match.value + break + case 'left': + matchGroup.left = startRegex.exec(match.value) + break + case 'match': + matchGroup.match = match.value + break + case 'right': + matchGroup.right = endRegex.exec(match.value) + builder += processor(matchGroup.left, matchGroup.right, matchGroup.match, matchReplacePass) + break + } + return builder + }, '') + } + + return matchReplacePass(rv) +} + +function processIncludeDirective (isStatic, context, opts, match, linePrefix, file) { + file = (file || '').trim() + var indent = linePrefix.replace(/\S/g, ' ') + var includedContext = copy(context) + var includedOpts = copy(opts) + includedContext.src = path.join(opts.srcDir, file) + includedOpts.srcDir = path.dirname(includedContext.src) + + var fileContents = getFileContents(includedContext.src, opts.fileNotFoundSilentFail, context.src) + if (fileContents.error) { + return linePrefix + fileContents.contents + } + + var includedSource = fileContents.contents + if (isStatic) { + includedSource = fileContents.contents + } else { + includedSource = preprocessor(fileContents.contents, includedContext, includedOpts, true) + } + + includedSource = normalizeEol(includedSource, indent) + + if (includedSource) { + return linePrefix + includedSource + } else { + return linePrefix + } +} + +function getTestTemplate (test) { + /* jshint evil:true */ + test = test || 'true' + test = test.trim() + + // force single equals replacement + test = test.replace(/([^=!])=([^=])/g, '$1==$2') + //fixed by xxxxxx + test = test.replace(/-/g,'_') + /* eslint-disable no-new-func */ + return new Function('context', 'with (context||{}){ return ( ' + test + ' ); }') +} + +function testPasses (test, context) { + var testFn = getTestTemplate(test) + try{ + return testFn(context, getDeepPropFromObj) + }catch(e){} + return false +} + +function getFileContents (path, failSilent, requesterPath) { + try { + fs.statSync(path) + } catch (e) { + if (failSilent) { + return { + error: true, + contents: path + ' not found!' + } + } else { + var errMsg = path + errMsg = requesterPath ? errMsg + ' requested from ' + requesterPath : errMsg + errMsg += ' not found!' + throw new Error(errMsg) + } + } + return { + error: false, + contents: fs.readFileSync(path).toString() + } +} + +function copy (obj) { + return Object.keys(obj).reduce(function (copyObj, objKey) { + copyObj[objKey] = obj[objKey] + return copyObj + }, {}) +} + +function getDeepPropFromObj (obj, propPath) { + propPath.replace(/\[([^\]+?])\]/g, '.$1') + propPath = propPath.split('.') + + // fast path, no need to loop if structurePath contains only a single segment + if (propPath.length === 1) { + return obj[propPath[0]] + } + + // loop only as long as possible (no exceptions for null/undefined property access) + propPath.some(function (pathSegment) { + obj = obj[pathSegment] + return (obj == null) + }) + + return obj +} diff --git a/packages/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess/lib/regexrules.js b/packages/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess/lib/regexrules.js new file mode 100755 index 000000000..d78cb2714 --- /dev/null +++ b/packages/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess/lib/regexrules.js @@ -0,0 +1,114 @@ + +module.exports = { + simple: { + echo: '^#echo[ \t]+(.*?)[ \t]*$', + exec: '^#exec[ \t]+(\\S+)[ \t]*\\((.*)\\)[ \t]*$', + include: '^(.*)#include(?!-)[ \t]+(.*?)[ \t]*$', // allow prefix characters to specify the indent level of included file + 'include-static': '^(.*)#include-static[ \t]+(.*?)[ \t]*$' + }, + html: { + echo: '|!>)', + exec: '|!>)', + include: '(.*)|!>)', + 'include-static': '(.*)|!>)', + exclude: { + start: '[ \t]*|!>)(?:[ \t]*\n+)?', + end: '[ \t]*|!>)(?:[ \t]*\n)?' + }, + extend: { + start: '[ \t]*|!>)(?:[ \t]*\n+)?', + end: '[ \t]*|!>)(?:[ \t]*\n)?' + }, + extendable: '|!>)', + if: { + start: '[ \t]*|!>)(?:[ \t]*\n+)?', + end: '[ \t]*|!>)(?:[ \t]*\n)?' + }, + foreach: { + start: '[ \t]*|!>)(?:[ \t]*\n+)?', + end: '[ \t]*|!>)(?:[ \t]*\n)?' + } + }, + js: { + echo: [ + '/\\*[ \t]*#echo[ \t]+(.*?)[ \t]*\\*(?:\\*|/)', + '//[ \t]*#echo[ \t]+(.*?)[ \t]*$' + ], + exec: '(?://|/\\*)[ \t]*#exec[ \t]+(\\S+)[ \t]*\\((.*)\\)[ \t]*(?:\\*(?:\\*|/))?', + include: [ + '^(.*)/\\*[ \t]*#include(?!-)[ \t]+(.*?)[ \t]*\\*(?:\\*|/)', + '^(.*)//[ \t]*#include(?!-)[ \t]+(.*?)[ \t]*$' + ], + 'include-static': [ + '^(.*)/\\*[ \t]*#include-static[ \t]+(.*?)[ \t]*\\*(?:\\*|/)', + '^(.*)//[ \t]*#include-static[ \t]+(.*?)[ \t]*$' + ], + exclude: { + start: '[ \t]*(?://|/\\*)[ \t]*#exclude(?:[ \t]+([^\n*]*))?[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n+)?', + end: '[ \t]*(?://|/\\*)[ \t]*#endexclude[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?' + }, + extend: { + start: '[ \t]*(?://|/\\*)[ \t]*#extend(?!able)[ \t]+([^\n*]*)(?:\\*(?:\\*|/))?(?:[ \t]*\n+)?', + end: '[ \t]*(?://|/\\*)[ \t]*#endextend[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?' + }, + extendable: '[ \t]*(?://|/\\*)[ \t]*#extendable[ \t]*(?:\\*/)?', + if: { + start: '[ \t]*(?://|/\\*)[ \t]*#(ifndef|ifdef|if)[ \t]+([^\n*]*)(?:\\*(?:\\*|/))?(?:[ \t]*\n+)?', + end: '[ \t]*(?://|/\\*)[ \t]*#endif[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?' + }, + foreach: { + start: '[ \t]*(?://|/\\*)[ \t]*#foreach[ \t]+([^\n*]*)(?:\\*(?:\\*|/))?(?:[ \t]*\n+)?', + end: '[ \t]*(?://|/\\*)[ \t]*#endfor[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?' + } + }, + coffee: { + echo: '#+[ \t]*@echo[ \t]+(.*?)[ \t]*$', + exec: '#+[ \t]*@exec[ \t]+(\\S+)[ \t]*\\((.*)\\)[ \t]*$', + include: '^(.*?)#+[ \t]*@include(?!-)[ \t]+(.*?)[ \t]*$', + 'include-static': '^(.*?)#+[ \t]*@include-static[ \t]+(.*?)[ \t]*$', + exclude: { + start: '^[ \t]*#+[ \t]*@exclude(?:[ \t]+(.*?))?[ \t]*\n+', + end: '^[ \t]*#+[ \t]*@endexclude[ \t]*\n?' + }, + extend: { + start: '^[ \t]*#+[ \t]*@extend(?!able)[ \t]+(.*?)\n+', + end: '^[ \t]*#+[ \t]*@endextend[ \t]*\n?' + }, + extendable: '^[ \t]*#+[ \t]*@extendable[ \t]*$', + if: { + start: '^[ \t]*#+[ \t]*@(ifndef|ifdef|if)[ \t]+(.*?)[ \t]*\n+', + end: '^[ \t]*#+[ \t]*@endif[ \t]*\n?' + }, + foreach: { + start: '^[ \t]*#+[ \t]*@foreach[ \t]+(.*?)[ \t]*\n+', + end: '^[ \t]*#+[ \t]*@endfor[ \t]*\n?' + } + } +} + +module.exports.xml = module.exports.html + +module.exports.javascript = module.exports.js +module.exports.jsx = module.exports.js +module.exports.c = module.exports.js +module.exports.cc = module.exports.js +module.exports.cpp = module.exports.js +module.exports.cs = module.exports.js +module.exports.csharp = module.exports.js +module.exports.java = module.exports.js +module.exports.less = module.exports.js +module.exports.sass = module.exports.js +module.exports.scss = module.exports.js +module.exports.css = module.exports.js +module.exports.php = module.exports.js +module.exports.ts = module.exports.js +module.exports.tsx = module.exports.js +module.exports.peg = module.exports.js +module.exports.pegjs = module.exports.js +module.exports.jade = module.exports.js +module.exports.styl = module.exports.js +module.exports.go = module.exports.js + +module.exports.bash = module.exports.coffee +module.exports.shell = module.exports.coffee +module.exports.sh = module.exports.coffee diff --git a/packages/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess/package.json b/packages/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess/package.json new file mode 100755 index 000000000..7629227f9 --- /dev/null +++ b/packages/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess/package.json @@ -0,0 +1,68 @@ +{ + "name": "preprocess", + "description": "Preprocess directives in HTML, JavaScript, etc directives based off variable context", + "version": "3.1.0", + "homepage": "https://github.com/jsoverson/preprocess", + "author": { + "name": "Jarrod Overson", + "email": "jsoverson@gmail.com", + "url": "http://jarrodoverson.com/" + }, + "repository": { + "type": "git", + "url": "git://github.com/jsoverson/preprocess.git" + }, + "bugs": { + "url": "https://github.com/jsoverson/preprocess/issues" + }, + "licenses": [ + { + "type": "Apache 2.0", + "url": "https://github.com/jsoverson/preprocess/blob/master/LICENSE" + } + ], + "main": "lib/preprocess.js", + "engines": { + "node": ">= 0.10.0" + }, + "scripts": { + "test": "grunt test", + "ci": "grunt ci" + }, + "dependencies": { + "xregexp": "3.1.0" + }, + "devDependencies": { + "chai": "^3.5.0", + "chai-spies": "^0.7.0", + "grunt": "^0.4.5", + "grunt-benchmark": "^0.3.0", + "grunt-cli": "^0.1.13", + "grunt-contrib-clean": "^1.0.0", + "grunt-contrib-copy": "^0.8.0", + "grunt-contrib-jshint": "^1.0.0", + "grunt-contrib-watch": "^0.6.1", + "grunt-coveralls": "^1.0.0", + "grunt-deps-ok": "^0.9.0", + "grunt-mocha-istanbul": "^3.0.1", + "grunt-mocha-test": "^0.12.7", + "istanbul": "^0.4.2", + "load-grunt-tasks": "^3.4.0", + "mocha": "^2.4.5", + "time-grunt": "^1.3.0", + "travis-cov": "^0.2.5" + }, + "keywords": [ + "directive", + "ENV", + "environment", + "ifdef", + "ifndef", + "echo", + "include", + "exclude", + "process", + "preprocess", + "pragma" + ] +} diff --git a/packages/vue-cli-plugin-uni/packages/webpack-scoped-loader/index.js b/packages/vue-cli-plugin-uni/packages/webpack-scoped-loader/index.js new file mode 100644 index 000000000..b24398564 --- /dev/null +++ b/packages/vue-cli-plugin-uni/packages/webpack-scoped-loader/index.js @@ -0,0 +1,15 @@ +const path = require('path') + +const isWin = /^win/.test(process.platform) + +const normalizePath = path => (isWin ? path.replace(/\\/g, '/') : path) + +module.exports = function(content) { + this.cacheable && this.cacheable() + const resourcePath = normalizePath(this.resourcePath) + const inputPath = normalizePath(process.env.UNI_INPUT_DIR) + if (resourcePath !== normalizePath(path.resolve(process.env.UNI_INPUT_DIR, 'App.vue'))) { + return content.replace(/(<]*)>/ig, '$1 scoped>') + } + return content +} diff --git a/packages/vue-cli-plugin-uni/ui-public/h5.png b/packages/vue-cli-plugin-uni/ui-public/h5.png new file mode 100644 index 0000000000000000000000000000000000000000..ace49f6a5f31533e38bb1573e376499b5a3a5d5a GIT binary patch literal 3544 zcmZ`+cR1A#)c@YmwdW-}*X)MNwKvz^BYS1by0(fd+)Fab-ZHM4NFk(%YbD7lk&zK0 ziENp#-}~SD$NQY;oX?rhIe(q!oJ3P&9U4k@N&o<8^mH}NE)oA9lfy1$kBZCSB|tsZ zjMM<2A(iUX<;tavaMLw20sx%gW!?h-IQ}nx4FK+-0bt!302J~7fF-c-?MdAuyKwVM_%7pq|y!RI>=1{!`?O<^0OrAALA{%m7#9 z7o;;}Oa}=3T6$k9=*^~qQp;?1=H{D~Dk>I2jJlRz<26qbR}3m!%qnwg80$V0nRq}@h3pLN%-BYG*$du4Ozda=ccqaaoKi!rjK0W>piYgI!^Ak$0 z&GPrr`r#JH_tjo-oM6~PV`uy1r6@VdJtO&+_T&7dGty|5nX zn?#e&UQZrtf2T#T}d?(=4w){$vc|)X?@4X-4Iu zxx(ja)eit|dKM*&R(w!+0Lm^bmJeS3kj|%*!uh{Sx$P2gb~qdOIswPe@+?l3P3e&gzg`ENIvUTX%Ibnc81GfKBnQ#r?*VWZ(}|FxW;t!oVKem?F&* zSabMZJT0X?k+H9@PjPk3q`JTDZ z$>DfTiKjKB*91r}Gvk4az?Z6p6;Ol9x zaf=H!UIh^s|J3FWC5!n5?R}wMm7M21%5?9wU)2KO`VR9@gFkr5`TXD6Z81NyxMn9M5`He1ZH&#tFh8tGf=;sf%aFXuUMYKWDASnHy z%L0^wzElF)qtS(cJB!2h#fRrE=ERE>N99z zATA9}BNrq+Zdd)I;`gOH=&$1}q%v`I#LjV9DjtVMbWma{`=Pp7S%I-C`1SSShtbY4 z%|1TlM6Hdu*tV71F#sVP(5qTjVF2eLv3_V;;>(R;a!^c@Pm&a#kDbtTd8kA!-kq=R{{z%SQnMV`zD$K?PwjxxWM;{J@Qrm6J zZK6a&GD1*{eE82kB-vK3Oc1^luPyy%K}R7sjQu0VPfOH|N?4b)b&j1+lha_GEu%u08I9Cg6{#!!sX)1oUe2u#@P$!yTYC|Shr?)(MckN# z*8?CbQ{7{w44?P}$R2Bswe)n8CYMlHbGwMW8gDEPYJ7XY-9Jz?W;@8svxak)67+a@ zWoNtQcg?Y4*AcSyXT3O3DCG-WFRzW4mEgGHN>6T5xTiqyxFysQR#zH5e>}?V5@ixO zy;2h07kN6i!bkEly+)dchK6PDF*;8z^~am+zsLioHNKN-$DKCD-i?;gnRZf;4?~WM zi`VAP4*rc7;DyvDUp-k2q1n@qXeMkI;PaosTC@R=I=N8)OhyC=dXyVWQ&9|zRVB%$ zF>EyH;)mrZ(t>E5Q9R?)EEYRYFf|9lrgi&mQXS#IHun`>8AH6yGa8Gys}}tmRc04z z><9$R-Q!mzl^{mTMzpHSV_PJTpdEuD2$HBiLUgZ6;Tx>Dux|XL^)S|bVX{M6TRkg? zeIf*NC+>Gzm8~`hAAWa;yL2v$R{m6I5h1E&yE$;S0?Q;X-kmFArf#Npzc+5g*x z1mEhY3ptwk)hcmvp5Pcwb_FwBsF||yG*XQvE}LU)H@7$79Gs*ES%I`pK9`s1oi{TE znz_Er4-zr0R)*C|4k){r4&05p?*k|_g9R098X2qUjNbiSD90PTE+|=wC0;uTETniM z=3~%Eej!n=!6t||k*<$p#T$Vga@a}GuizsqNNwTeE%Y>0Sf0WC=y~UH38AmFPLTlU zS0H)d(sSqU^0@cPRD-B+LxSTU_pM}evDHIj)Qi_5*|z>twFYeVP%}qzl88Re1GFH` zS^_e{aqz=Q*vOyv5&p7XWX*fHLQ9TOU)9*R{?bTgNtC}*d!|kxT_--mS!_=6;)Uur zrZh5LoPORdFfmE!#jTO#cuv)%h*RY0S;N5gnbGgjT3KSiTtdNX#FPxTQe4E^zX8Xn zqkjW6^XNkgJ7#Dm7Y%VcDI=>b$OXE)E}3Utl5bJ88!_rDQ#$Fd{?djjF2`#bWwP*Y z7uVe7L{bbw7aKD)2_>v;(35&@_-u&$VQY(O_>1Ey?e!?ww!kiFB&g9*2)mA12A=S z_|3J7wzf8&Rg|dVV^$#+-wcw2(^(3Sglr|`jYO0n zr)791NnIctz7PvL=#^#0W&#t2n2I6(FLMjvD&AIsE)-Q2Bfs##H4s$Nd2F>XoMww) z{Xzz($3BheUwKP;m4cX*?;izv$=eE7ujD7xMjuamP<dtgRKJ%7IL8G zDI=uBN_4#?m^E}=8lRUs{?oEfLx}%>+4N#eV9Td(~Za0%44BH!qO)`ac zDzDB;7-MfWI4IUwv;AXCnjy60V;6>R5D?p>v-;c<>p#8Y(4_<=G5vjc?fv}?g~s`n zlaXpGmG3iOcyI@PtSt$yRNYUpsy!QV#u^$;d8d6E?03t4afm(ftUVDKCNKCXQu6Cv zP=4*Q{{s~1J1IMn3S&F<= z%bD#>UH0XI>GY|@I^i5eT6=mN0rlWkqKMLaddIxbxleHAwiGVoa!yHxLd7?J+ak9% zzlA1Bz7ZwdlSDdNt8*80EKcM^3pAI87~>O=bFZ*2aT6oFpQ*4{x?gaL0~;D+o~9E(3^h_1G%8y^n-C35_YBA5tHNkCa%rCCINfDZ_OdEM* z<^-_mxThkU`xm=A_+`C(v`@LmJlB_B-VB?+e0>B$wQNG&T|zw++=4wW0gyn8%c9V7 zC~>p}T2cWmqaYzEj7BS<(PkYji2qaI7vS!FJN*AI;9H`-+#Ud+r)8}9Lftv$e*jNI BU%~(Y literal 0 HcmV?d00001 diff --git a/packages/vue-cli-plugin-uni/ui-public/logo.png b/packages/vue-cli-plugin-uni/ui-public/logo.png new file mode 100755 index 0000000000000000000000000000000000000000..b5771e209bb677e2ebd5ff766ad5ee11790f305a GIT binary patch literal 4023 zcmaJ^c|25Y`#+XyC`+5OUafkYqmlSEl)+V zC53EJB$S8m@9Vz4*Y&-Yb3W(3Y;(d~fM1#)0003Cvn<7K1}HtM`$d{YenwQ;C^-S(Bw!dKGPRQ{5d$=<+Bb^=&62=9 zyT3g7ffNAnXPh^N0JjBz*>4v5+kn2(URc+5KlGCVF`&OikMw zfqqB8XK2+;V}LL3B>(G>)mVo1y5YXue4A!H*}eQbcg`t##g9HFply&`y$2%Ui`qzhj;o^=JbnXrW48s;xu1fDr z0))La)fp=QkX*N#V0eTJXiqO11AyvJlBY^iBrIQo0Kg>g;^BKnJ9a%2Wz`F2Ka;Jl zm*B>3H!<9`zg|z+c>6eWFMqydnvs-!J))2I(LEmNyxo~2!VjOpv<0SyMNVCup-60Z zm&|RDtd8R2HEIU!!OA0Ic6-G4K{`MZ8S%UjEL!s#vj{vLBWeqI(M&DkE;aT|aziV8 zRiTRN#GNwykvPx{R==`-rP>^pa`AyJ&s**Q!zU$j(pO&Q(YolGLT=2o0>3Wlhx?Gs z#|6b*$3F$ofzT`QIA#}2(Cg}Z?5V5KrtX)WrInh*aTCsP#{@V|*7<0lm`r^xmJQm^ z9n0J^3p#yCxWPX>G11)F(iv5vIIHkbqzdH37jX&JZ~&5AV*OAtL}axw*aLAt(b-!Vf)wRw=S8((e`~WLqlDBobRbj)NXB zS>W`fibSDA>uYN*&&Ml75iep!E%^%eV~SElj=}K;6TCNXs2gYG-L`En&3y~H9fP=W z(t?;5Xalv2F5ROUkg3?7C5~z>QYq|tok{Q}toT5u=~a9mBKDc4zfSM=`?OF-lS(V+pE1(m&x$HE_9vj;Cy)b@OiPMS0bs1 zRL9h?)T!I{4m1aY9>(pR_IDhF?wocEy=CU`m(5ry-&^rJJ*Bb^PfNARJ1{|*1e;FV zGljKhHo|}41Rg|1n&m~I3+-_gFQww-#b2u97o3fIsg67|%6`|aJX{~F&RPa;TayWd zp0l(=(QbROypp_fCeOBW3BJ5PJg@UU`&fs3hd{?U6&@7>mHWNEWnN`rWk>r%`fK|= z=BRVxb2I(y07{Nwj&jZtf{0iN;H%QAvaO1&8VKn8tp5f#! zN#ZlRm)#|IR8144l_=#8)5guWCE`B$T_;p_&0iWR+1=_>mDK1{*kw_8pi=2ewD%Z1 zSVG^6Mc(Vd()@@Y^wYz75Yz{X8jD_x*B)w5@yqn8>U#Kw-qzNvJjm)}wamur^knR_o)EvaGVkz%1gB=%{GIq3%OVcBFpT?D{PKZ079tIh|$fvf?svxl^`nuZV1~ zE?xILl^)O*=ufGhDH_pyUfNjteA>xd#yg*uvj~^Cbv&_EBt0-)!j4#crI>Uhq&0Oy z`b$;!qc=;1Sx>VD%ia^;erQ9!2)(mrrJ5zv;`SWLHu^Td;yik`Z7ioatGHn?aSD1m z@U+Y6wVHj_e`PD>_Noz^2O3?6Yg*5_BlMB@A05*?`Y-jlZ-m^4uDw+Y8A8@7g!P7H zgzZ?*UDN&1x{>g`ZiMkweBs14cdln#6I?YHr7!-)nyY$73 zckv0h$WfEY^%7rYR&g4G-pZL>Vy{3sVkc#OsI@6s?(5whAJqvO5)LEZTD6>Rdkl&h zHusOIlp{!GNUVm69y+XkTlKT;Lp%Ce`igQdYushcyC!}iq4eq#-2van)Ie{RuRq2g zH=9+-th`-$F*y3W=|Z{)eb0Wrxy$2?eT~S=V>Iq5|4fbS@l5+PI<90O)5aZFv- z{-7I*`r#90Z5HrSgU=dsgpnk5?TNyom7_`TM^@+iv+q@OQnFLB3o!zOw1-FDsZ|`T zu=YA~Bw1jbF-d$SlN|kOWn5vEwm2Z>A8FZD_z+WWBPebOEjbeGD(MZ=TPSr~@YnLZU)h_#alQiZu;syu@U^WCAXKCKVZHf%!^8wGMR7*MP@UWP13nuk#~M$mU% z$uszs);TA=a{4!`8Qm`Sn+rdD>w9SLzQ0p-yTPboznqn+ASr#=Td7#J^gVESP9li^ zi{+qONJ8-4_1gZ8&pUnyeZKH;^FF?wIQ-qc-o5j=ix69oFFJQK<>#B|k#6%g^Bx5= zg}8(qIXM{t>6)*e9mylb4~qA6z6x{v$(W(tnHt&{T|3_Cyxupzb2YZJuAEW2NM+wC zy^Cm4Xp*b$U?3N6t(SESgt9ByRYOfRav2BL4L5BTyMExBieFo==ue&BT!*e)T3lo5 zDDLL`TT0PQo#}RDFM1G`iU*85$sTyH1rh6w$KbJ^jI%9xJpkZ2Ot5#RJ6l;IaAcw? zc1uS!m`LHE0YJ|nn1aRm;pt!xyf=Y_gs`91LBIr0B*Y1BrDjDz;e80`5Gvj-jfh?28eh%7933UC(#hWNXRd{2+nv*426JysnGq9kiSVeTiJk7WGWsE zSJhI%!8FvtM|D(Ta2<7RO=YmU8cYkSrU`}VsK7K3oKsT`{QH1#yiq;95Ev7)-@Z6A zB*ceKry!uvpr9btAPrSA)tiIW(SfR|L)Fz)I2tN628oUhRw2<8{#Y=<({NM*g-#%o zz*`ov9^?Qz62f8ncL+p^mDN9nNwnXI;-m~3jHN(fs%lUoaVxH0+B7-_|6dyas!g+J zQ1DO;o<-jJ7|Hhj9zgQ@T40Nl&|EJ)8M4T?#8vfJ1oXI~g0G`C@dMc;A zjqo=rI2*RN7A8ja!Tlbd0QX!*+E1x@K*^ZD{)%J_pe^QRp=+j?jCO1cZN?ryPlN&29$7&Ac>xMM*DwQ*NxtIV%NlmI`lJr2JVZ!|SUM)s{m5-r-hrCim zGEunpTX?76P{|0K32-Ym!wnJFjcNAROWZ-AL8+J1F_-(QHNzMCON{8s2|iO0D*vNr zQhflINtwvCi<$Z|n(_I*HbSmD?h6-!bQZ5=hQ8L&m)|I~)%u)gyCW_QRg`w5P~OC1 z%uCbu%`2nB5zR=>{took!+yKEDi`b>pzAf)^KDGtUM8R*t#G@mH2=PKe4(Ipz-y*c zc~Kzl;GA)s+53_RGg-}F1`$4QjX29!BLu$pn{&KmMu86HO}Y2@q{Jb7v=N}{+PQWx zHF2LIb9qiO+DI~r+eb9ubK7oh6KFdUL6e;9wKv_RvXh$HuqHw)inh2kQGM>}%G4V% zmjkEYsw}?{m%gW>#P7wTXwk}cZO--qydYul`!3w~l(JgX@=yG7|6z{6kO^>c^P;zI zAmO}-iEA~6%U7@PbJN4EXW!v;|5owjl2$w4ZZqafWPCshmRxS}7Zwlg(*rDz;hg}s SYs}WS&%*SCNx89m_ v !== undefined +module.exports = api => { + api.describeConfig({ + id: 'dcloudio.uni-app', + name: 'uni-app', + description: '配置 uni-app 项目', + link: 'https://uniapp.dcloud.io/', + icon: '/_plugin/%40dcloudio%2Fvue-cli-plugin-uni/logo.png', + files: { + manifest: { + json: ['src/manifest.json'] + } + }, + onRead: ({ + data: { + manifest: { + name, + h5 = {} + } + } + }) => ({ + tabs: [{ + id: 'h5', + label: 'h5', + icon: '/_plugin/%40dcloudio%2Fvue-cli-plugin-uni/h5.png', + prompts: [{ + name: 'title', + type: 'input', + default: '', + value: name || h5.title, + message: '应用名称', + description: '应用的名称', + group: '基础设置', + link: 'https://uniapp.dcloud.io/collocation/manifest?id=h5' + }, { + name: 'base', + type: 'input', + default: '/', + value: h5.router && h5.router.base, + message: 'Base Url', + description: `应用的部署地址,如 '/my-app/'。如果留空,所有资源将使用相对路径。`, + group: '基础设置', + link: 'https://uniapp.dcloud.io/collocation/manifest?id=h5' + }, { + name: 'mode', + type: 'list', + default: 'hash', + choices: [{ + name: 'hash', + value: 'hash' + }, + { + name: 'history', + value: 'history' + } + ], + value: h5.router && h5.router.mode, + message: '路由模式', + description: '选择路由模式,history 模式需要服务器配置', + group: '基础设置', + link: 'https://uniapp.dcloud.io/collocation/manifest?id=h5' + }, + { + name: 'loading', + type: 'input', + default: 'AsyncLoading', + value: h5['async'] && h5['async'].loading, + message: '加载组件', + description: '页面按需加载时显示的组件(需注册为全局组件)', + group: '页面按需加载配置', + link: 'https://uniapp.dcloud.io/collocation/manifest?id=h5-async' + }, + { + name: 'error', + type: 'input', + default: 'AsyncError', + value: h5['async'] && h5['async'].error, + message: '错误组件', + description: '页面按需加载失败时显示的组件(需注册为全局组件)', + group: '页面按需加载配置', + link: 'https://uniapp.dcloud.io/collocation/manifest?id=h5-async' + }, + { + name: 'delay', + type: 'input', + default: 200, + value: h5['async'] && h5['async'].delay, + message: '延迟时间', + description: '页面按需加载展示 loading 组件的延迟时间(页面 js 若在 delay 时间内加载完成,则不会显示 loading 组件)', + group: '页面按需加载配置', + link: 'https://uniapp.dcloud.io/collocation/manifest?id=h5-async' + }, + { + name: 'timeout', + type: 'input', + default: 3000, + value: h5['async'] && h5['async'].timeout, + message: '超时时间', + description: '页面按需加载超时时间(超时后展示 error 对应的组件)', + group: '页面按需加载配置', + link: 'https://uniapp.dcloud.io/collocation/manifest?id=h5-async' + } + ] + }] + + }), + onWrite: async ({ + api, + prompts + }) => { + const h5 = {} + + const title = await api.getAnswer('title') + if (isDef(title)) { + h5.title = title + } + + const base = await api.getAnswer('base') + const mode = await api.getAnswer('mode') + if (isDef(base) || isDef(mode)) { + h5.router = {} + if (isDef(base)) { + h5.router.base = base + } + if (isDef(mode)) { + h5.router.mode = mode + } + } + + const loading = await api.getAnswer('loading') + const error = await api.getAnswer('error') + const delay = await api.getAnswer('delay') + const timeout = await api.getAnswer('timeout') + if (isDef(loading) || isDef(error) || isDef(delay) || isDef(timeout)) { + h5['async'] = {} + if (isDef(loading)) { + h5['async'].loading = loading + } + if (isDef(error)) { + h5['async'].error = error + } + if (isDef(delay)) { + h5['async'].delay = delay + } + if (isDef(timeout)) { + h5['async'].timeout = timeout + } + } + + api.setData('manifest', { + h5 + }) + } + }) +} diff --git a/packages/vue-cli-plugin-uni/util/format-errors.js b/packages/vue-cli-plugin-uni/util/format-errors.js new file mode 100644 index 000000000..a47531d55 --- /dev/null +++ b/packages/vue-cli-plugin-uni/util/format-errors.js @@ -0,0 +1,134 @@ +const path = require('path') + +const getDependency = err => err.dependencies && err.dependencies.length && err.dependencies[0] + +const LOCAL_RESOURCE_REGEX = /Module parse failed:\s*(.*)\s*Unexpected character/ + +const LINENO_REGEX = /\(([0-9]+):[0-9]+\)/ + +const FILE_REGEX = /in\s(.*)\s\(line\s([0-9]+),\scolumn\s[0-9]+\)/ + +function formatMessage (msg) { + if (msg) { + const matches = msg.match(FILE_REGEX) + if (matches && matches.length === 3) { + const filePath = path.relative(process.env.UNI_INPUT_DIR, path.resolve(matches[1])) + msg = msg.replace(matches[0], 'at ' + filePath.split('?')[0] + ':' + matches[2]) + } + return msg.replace('Module build failed: ', '模块编译失败:') + } + return '' +} + +function ModuleBuildError (err) { + const lines = err.message.split('\n') + let firstLineMessage = lines[0] + if (lines.length > 1) { + firstLineMessage = lines[1] + } + if (~firstLineMessage.indexOf('Module build failed: ModuleBuildError: Module build failed:')) { + // 移除调用栈错误 + return false + } + if (~firstLineMessage.indexOf('Failed to find')) { // css 引用路径错误 + return { + line: 1, + message: '文件查找失败:' + firstLineMessage.split('Failed to find')[1] + } + } else if (~firstLineMessage.indexOf('SyntaxError:') || ~firstLineMessage.indexOf('Syntax Error')) { + if (~firstLineMessage.indexOf('ModuleBuildError: Module build failed: Syntax Error')) { + return false + } + + if (err.error && err.error.loc) { // babel + let message = (err.message + '\n').replace('SyntaxError:', '语法错误:') + message = message.replace(/^\s*at\s.*:\d+:\d+[\s)]*\n/gm, '') + ' ' + return { + line: err.error.loc.line || 1, + message + } + } else { // css + let message = (err.message).replace('Syntax Error', '语法错误:') + message = message.replace(/^\s*at\s.*:\d+:\d+[\s)]*\n/gm, '') + ' ' + const matches = message.match(LINENO_REGEX) + if (matches && matches.length === 2) { + return { + line: matches[1], + message + } + } + } + } else if (~err.message.indexOf('Cannot find module')) { + let builtinCompile = '' + if (~err.message.indexOf('compile-less')) { + builtinCompile = 'less' + } else if (~err.message.indexOf('compile-node-sass')) { + builtinCompile = 'scss/sass' + } else if (~err.message.indexOf('compile-stylus')) { + builtinCompile = 'stylus' + } else if (~err.message.indexOf('compile-typescript')) { + builtinCompile = 'typescript' + } else if (~err.message.indexOf('compile-pug-cli')) { + builtinCompile = 'pug/jade' + } + if (builtinCompile) { + return { + message: '预编译器错误:代码使用了' + builtinCompile + '语言,但未安装相应编译器,请在菜单工具-插件安装里安装相应编译插件' + } + } + } else if (~firstLineMessage.indexOf('Module parse failed')) { + const matches = firstLineMessage.match(LOCAL_RESOURCE_REGEX) + if (matches && matches.length === 2) { + return { + message: '资源引用失败:暂不支持引用本地资源\'' + matches[1].trim() + '\',可更换为网络地址或base64' + } + } + } + return formatMessage(err.message) +} + +function ModuleNotFoundError (err) { + const matches = err.message.match(/Can't resolve '(.*loader)'/) + if (matches && matches.length > 0) { + return { + line: 1, + message: ` +Failed to resolve loader: ${matches[1]} +You may need to install it. +` + } + } + const dependency = getDependency(err) + if (dependency) { + let line = 1 + if (dependency.loc.start && dependency.loc.start.line) { + line = dependency.loc.start.line + } + return { + line: line, + message: '文件查找失败:\'' + dependency.userRequest + '\'' + } + } +} + +function ModuleParseError (err) { + const firstLineMessage = err.message.split('\n')[0] + const matches = firstLineMessage.match(LOCAL_RESOURCE_REGEX) + if (matches && matches.length === 2) { + return { + message: `资源引用失败:暂不支持引用此类型资源(${err.module.rawRequest})` + } + } +} + +module.exports = { + ModuleBuildError, + ModuleNotFoundError, + ModuleParseError + // ChunkRenderError(err) {}, + // EntryModuleNotFoundError(err) {}, + // ModuleDependencyError(err) {}, + // ModuleError(err) {}, + // ModuleDependencyWarning(warn) {}, + // ModuleWarning(warn) {} +} diff --git a/packages/vue-cli-plugin-uni/util/on-errors.js b/packages/vue-cli-plugin-uni/util/on-errors.js new file mode 100644 index 000000000..d12e4cfbe --- /dev/null +++ b/packages/vue-cli-plugin-uni/util/on-errors.js @@ -0,0 +1,35 @@ +const path = require('path') + +const formatErrors = require('./format-errors') + +module.exports = function (errors) { + console.error( + Array.from( + new Set( + errors.map(err => { + const formatError = formatErrors[err.name] + + if (formatError) { + const result = formatError(err) + if (result) { + if (typeof result === 'string') { + return result + } else { + const file = path.relative(process.env.UNI_INPUT_DIR, err.module.resource).split('?')[0] + if (file === 'pages.json') { + result.line = 1 + } + return `${result.message} at ${file}:${result.line || 1}` + } + } else if (result === false) { + return '' // skip + } + } + return err.message + }) + ) + ) + .filter(msg => !!msg) + .join('\n') + ) +} diff --git a/packages/webpack-uni-mp-loader/LICENSE b/packages/webpack-uni-mp-loader/LICENSE new file mode 100755 index 000000000..7a4a3ea24 --- /dev/null +++ b/packages/webpack-uni-mp-loader/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/packages/webpack-uni-mp-loader/__tests__/components.spec.js b/packages/webpack-uni-mp-loader/__tests__/components.spec.js new file mode 100644 index 000000000..277c0bd38 --- /dev/null +++ b/packages/webpack-uni-mp-loader/__tests__/components.spec.js @@ -0,0 +1,92 @@ +const parser = require('@babel/parser') + +const scopedComponentTraverse = require('../lib/babel/scoped-component-traverse') +const globalComponentTraverse = require('../lib/babel/global-component-traverse') + +process.UNI_LIBRARIES = ['@dcloudio/uni-ui'] + +function assertCodegen (content, expectedComponents, isScoped = true) { + const { + state: { + components + } + } = (isScoped ? scopedComponentTraverse : globalComponentTraverse)(parser.parse(content, { + sourceType: 'module', + plugins: [ + 'typescript' + ] + }), { + components: [] + }) + + expect(JSON.stringify(components)).toBe(JSON.stringify(expectedComponents)) +} + +describe('mp:loader', () => { + it('parse scoped component', () => { + assertCodegen( + ` +import mediaList from '@/components/tab-nvue/mediaList.vue'; +import uniLoadMore from '@/components/uni-load-more.vue'; +export default { + components: { + mediaList, + uniLoadMore + } +} +`, + [{ + 'name': 'mediaList', + 'value': 'mediaList', + 'source': '@/components/tab-nvue/mediaList.vue' + }, { + 'name': 'uniLoadMore', + 'value': 'uniLoadMore', + 'source': '@/components/uni-load-more.vue' + }]) + + assertCodegen( + ` + import { uniBadge,uniCard} from '@dcloudio/uni-ui'; + export default { + components: { + 'uni-badge':uniBadge, + 'uni-card':uniCard + } + } + `, + [{ + 'name': 'uni-badge', + 'value': 'uniBadge', + 'source': '@dcloudio/uni-ui/lib/uni-badge/uni-badge' + }, { + 'name': 'uni-card', + 'value': 'uniCard', + 'source': '@dcloudio/uni-ui/lib/uni-card/uni-card' + }]) + }) + + it('parse global component', () => { + assertCodegen( + ` + import { uniBadge,uniCard} from '@dcloudio/uni-ui'; + import mediaList from '@/components/tab-nvue/mediaList.vue'; + Vue.component('uni-badge',uniBadge) + Vue.component('uni-card',uniCard) + Vue.component('media-list',mediaList) + `, + [{ + 'name': 'uni-badge', + 'value': 'uniBadge', + 'source': '@dcloudio/uni-ui/lib/uni-badge/uni-badge' + }, { + 'name': 'uni-card', + 'value': 'uniCard', + 'source': '@dcloudio/uni-ui/lib/uni-card/uni-card' + }, { + 'name': 'media-list', + 'value': 'mediaList', + 'source': '@/components/tab-nvue/mediaList.vue' + }], false) + }) +}) diff --git a/packages/webpack-uni-mp-loader/lib/babel-plugin-global-component.js b/packages/webpack-uni-mp-loader/lib/babel-plugin-global-component.js new file mode 100644 index 000000000..94c3e316a --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/babel-plugin-global-component.js @@ -0,0 +1,67 @@ +function addImportsMap (metadata, name, source) { + if (!metadata.modules) { + metadata.modules = {} + } + metadata.modules[name] = source +} + +module.exports = function babelPluginGlobalComponent ({ + types: t +}) { + return { + visitor: { + Program: { + exit (path) { + path.traverse({ + CallExpression (path) { + if (path.hub) { + const { + callee, + arguments: args + } = path.node + + const { + metadata + } = path.hub.file + + if (!callee.object || !callee.property) { + return + } + if (callee.object.name === 'Vue' && callee.property.name === 'component') { + if (!args[0] || args[0].type !== 'StringLiteral') { + throw new Error('Vue.component()的第一个参数必须为静态字符串') + } + if (!args[1]) { + throw new Error('Vue.component()需要两个参数') + } + if (!metadata.globalComponents) { + metadata.globalComponents = {} + } + metadata.globalComponents[args[0].value] = metadata.modules[args[1].name] + } + } + } + }) + } + }, + ImportDeclaration (path) { + if (path.hub) { + const { + specifiers, + source: { + value + } + } = path.node + + const { + metadata + } = path.hub.file + + specifiers.forEach(specifier => { + addImportsMap(metadata, specifier.local.name, value) + }) + } + } + } + } +} diff --git a/packages/webpack-uni-mp-loader/lib/babel-plugin-scoped-component.js b/packages/webpack-uni-mp-loader/lib/babel-plugin-scoped-component.js new file mode 100644 index 000000000..d4279db61 --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/babel-plugin-scoped-component.js @@ -0,0 +1,89 @@ +const hyphenateRE = /\B([A-Z])/g + +function cached (fn) { + const cache = Object.create(null) + return function cachedFn (str) { + const hit = cache[str] + return hit || (cache[str] = fn(str)) + } +} + +const hyphenate = cached((str) => { + return str.replace(hyphenateRE, '-$1').toLowerCase() +}) + +module.exports = function ({ + types: t +}) { + return { + visitor: { + ExportDefaultDeclaration (path) { + const declaration = path.node.declaration + // export default {components:{}} + if (t.isObjectExpression(declaration)) { + handleObjectExpression(declaration, path) + } + // export default Vue.extend({components:{}}) + if (t.isCallExpression(declaration) && t.isMemberExpression(declaration.callee) && declaration.arguments + .length === 1) { + if (declaration.callee.object.name === 'Vue' && declaration.callee.property.name === 'extend') { + handleObjectExpression(declaration.arguments[0], path) + } + } + // export default @Component({components:{}}) class MyComponent extend Vue + if (t.isClassDeclaration(declaration) && declaration.decorators && declaration.decorators.length) { + const componentDecorator = declaration.decorators[0] + if (t.isCallExpression(componentDecorator.expression)) { + const args = componentDecorator.expression.arguments + if (args && args.length && t.isObjectExpression(args[0])) { + handleObjectExpression(args[0], path) + } + } + } + } + } + } + + function handleObjectExpression (declaration, path) { + const componentsProperty = declaration.properties.filter(prop => { + return t.isObjectProperty(prop) && t.isIdentifier(prop.key) && + prop.key.name === 'components' + })[0] + + if (componentsProperty && t.isObjectExpression(componentsProperty.value)) { + const properties = componentsProperty.value.properties + .filter(prop => t.isObjectProperty(prop) && t.isIdentifier(prop.value)) + + const components = {} + + properties.forEach(prop => { + // prop.key maybe Identifier or StringLiteral + // Identifier use name, StringLiteral use value + const key = prop.key.name || prop.key.value + const value = prop.value.name + const source = findSource(value, path.scope.bindings) + if (!source) { + throw new Error(`组件 ${key} 引用错误`) + } + if (process.UNI_LIBRARIES.includes(source)) { + const componentName = hyphenate(key) + components[key] = source + '/lib/' + componentName + '/' + componentName + } else { + components[key] = source + } + }) + path.hub.file.metadata.components = components + } + } + + function findSource (identifierName, bindings) { + const binding = bindings[identifierName] + if (!binding) { + return + } + + if (t.isImportDeclaration(binding.path.parent)) { + return binding.path.parent.source.value + } + } +} diff --git a/packages/webpack-uni-mp-loader/lib/babel/global-component-traverse.js b/packages/webpack-uni-mp-loader/lib/babel/global-component-traverse.js new file mode 100644 index 000000000..58b88cfd0 --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/babel/global-component-traverse.js @@ -0,0 +1,46 @@ +const t = require('@babel/types') +const babelTraverse = require('@babel/traverse').default + +const { + parseComponents +} = require('./util') + +module.exports = function (ast, state = {}) { + const imports = [] + let bindings = false + let parentPath = false + babelTraverse(ast, { + CallExpression (path) { + const callee = path.node.callee + if (!callee.object || !callee.property) { + return + } + if (callee.object.name === 'Vue' && callee.property.name === 'component') { + parentPath = path.parentPath + bindings = path.scope.bindings + const args = path.node.arguments + const nameNode = args[0] + const valueNode = args[1] + if (!t.isStringLiteral(nameNode)) { + throw new Error('Vue.component()的第一个参数必须为静态字符串') + } + if (!t.isIdentifier(valueNode)) { + throw new Error('Vue.component()需要两个参数') + } + imports.push({ + name: nameNode.value, + value: valueNode.name + }) + } + } + }) + if (imports.length) { + state.components = parseComponents(imports, bindings, parentPath) + } else { + state.components = [] + } + return { + ast, + state + } +} diff --git a/packages/webpack-uni-mp-loader/lib/babel/plugin-create-app.js b/packages/webpack-uni-mp-loader/lib/babel/plugin-create-app.js new file mode 100644 index 000000000..c3fd3be66 --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/babel/plugin-create-app.js @@ -0,0 +1,25 @@ +module.exports = function ({ + types: t +}) { + return { + visitor: { + MemberExpression (path, state) { + if ( + t.isIdentifier(path.node.property) && + path.node.property.name === '$mount' && + !path.node.$createApp + ) { + path.node.$createApp = true + path.get('object').replaceWith( + t.callExpression( + t.identifier('createApp'), + [ + path.node.object + ] + ) + ) + } + } + } + } +} diff --git a/packages/webpack-uni-mp-loader/lib/babel/plugin-dynamic-import.js b/packages/webpack-uni-mp-loader/lib/babel/plugin-dynamic-import.js new file mode 100644 index 000000000..ec7f4391e --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/babel/plugin-dynamic-import.js @@ -0,0 +1,44 @@ +const t = require('@babel/types') +const babelTemplate = require('@babel/template').default + +const buildDynamicImport = babelTemplate(`var IMPORT_NAME = ()=>import(IMPORT_SOURCE)`, { + preserveComments: true, + plugins: [ + 'dynamicImport' + ] +}) +// var test = ()=>import(/* webpackChunkName: "components/test" */'../../components/test') +function getDynamicImport (name, source, chunkName) { + const stringLiteral = t.stringLiteral(source) + const dynamicImportComment = { + type: 'CommentBlock', + value: `webpackChunkName: "${chunkName}"` + } + stringLiteral.leadingComments = [dynamicImportComment] + return buildDynamicImport({ + IMPORT_NAME: t.identifier(name), + IMPORT_SOURCE: stringLiteral + }) +} + +module.exports = function ({ + types: t +}) { + return { + visitor: { + ImportDeclaration (path, state) { + const dynamicImport = state.opts.dynamicImports[path.node.source.value] + if (dynamicImport) { + path.insertBefore( + getDynamicImport( + path.node.specifiers[0].local.name, + dynamicImport.source, + dynamicImport.chunkName + ) + ) + path.remove() + } + } + } + } +} diff --git a/packages/webpack-uni-mp-loader/lib/babel/scoped-component-traverse.js b/packages/webpack-uni-mp-loader/lib/babel/scoped-component-traverse.js new file mode 100644 index 000000000..f29dabe45 --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/babel/scoped-component-traverse.js @@ -0,0 +1,61 @@ +const t = require('@babel/types') +const babelTraverse = require('@babel/traverse').default + +const { + parseComponents +} = require('./util') + +function handleObjectExpression (declaration, path, state) { + const componentsProperty = declaration.properties.filter(prop => { + return t.isObjectProperty(prop) && + t.isIdentifier(prop.key) && + prop.key.name === 'components' + })[0] + + if (componentsProperty && t.isObjectExpression(componentsProperty.value)) { + const properties = componentsProperty.value.properties + .filter(prop => t.isObjectProperty(prop) && t.isIdentifier(prop.value)) + + state.components = parseComponents(properties.map(prop => { + return { + name: prop.key.name || prop.key.value, + value: prop.value.name + } + }), path.scope.bindings, path) + } +} + +module.exports = function (ast, state = { + type: 'Component', + components: [] +}) { + babelTraverse(ast, { + ExportDefaultDeclaration (path) { + const declaration = path.node.declaration + if (t.isObjectExpression(declaration)) { // export default {components:{}} + handleObjectExpression(declaration, path, state) + } else if (t.isCallExpression(declaration) && + t.isMemberExpression(declaration.callee) && + declaration.arguments.length === 1) { // export default Vue.extend({components:{}}) + if (declaration.callee.object.name === 'Vue' && declaration.callee.property.name === + 'extend') { + handleObjectExpression(declaration.arguments[0], path, state) + } + } else if (t.isClassDeclaration(declaration) && + declaration.decorators && + declaration.decorators.length) { // export default @Component({components:{}}) class MyComponent extend Vue + const componentDecorator = declaration.decorators[0] + if (t.isCallExpression(componentDecorator.expression)) { + const args = componentDecorator.expression.arguments + if (args && args.length && t.isObjectExpression(args[0])) { + handleObjectExpression(args[0], path, state) + } + } + } + } + }) + return { + ast, + state + } +} diff --git a/packages/webpack-uni-mp-loader/lib/babel/util.js b/packages/webpack-uni-mp-loader/lib/babel/util.js new file mode 100644 index 000000000..a17f78727 --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/babel/util.js @@ -0,0 +1,85 @@ +const t = require('@babel/types') + +const hyphenateRE = /\B([A-Z])/g + +function cached (fn) { + const cache = Object.create(null) + return function cachedFn (str) { + const hit = cache[str] + return hit || (cache[str] = fn(str)) + } +} + +const hyphenate = cached((str) => { + return str.replace(hyphenateRE, '-$1').toLowerCase() +}) + +function findImportDeclaration (identifierName, bindings) { + const binding = bindings[identifierName] + if (!binding) { + return + } + + if (t.isImportDeclaration(binding.path.parent)) { + return binding.path.parentPath + } +} + +function parseComponents (names, bindings, path) { + const components = [] + const dynamicImportMap = new Map() + names.forEach(({ + name, + value + }) => { + const importDeclaration = findImportDeclaration(value, bindings) + if (!importDeclaration) { + throw new Error(`组件 ${name} 引用错误,仅支持 import 方式引入组件`) + } + let source = importDeclaration.node.source.value + if (process.UNI_LIBRARIES && process.UNI_LIBRARIES.includes(source)) { + const componentName = hyphenate(name) + source = source + '/lib/' + componentName + '/' + componentName + } + const dynamicImportArray = dynamicImportMap.get(importDeclaration) || [] + dynamicImportArray.push({ + name, + value, + source + }) + dynamicImportMap.set(importDeclaration, dynamicImportArray) + }) + + const importDeclarations = dynamicImportMap.keys() + for (let importDeclaration of importDeclarations) { + const dynamicImportArray = dynamicImportMap.get(importDeclaration) + dynamicImportArray.forEach((dynamicImport) => { + components.push(dynamicImport) + }) + importDeclaration.remove() + } + return components +} + +function findBabelLoader (loaders) { + return loaders.find(loader => loader.path.indexOf('babel-loader') !== -1) +} + +const babelPluginDynamicImport = require.resolve('./plugin-dynamic-import') + +function addDynamicImport (babelLoader, resourcePath, dynamicImports) { + babelLoader.options = babelLoader.options || {} + if (!babelLoader.options.plugins) { + babelLoader.options.plugins = [] + } + babelLoader.options.plugins.push([babelPluginDynamicImport, { + resourcePath, + dynamicImports + }]) +} + +module.exports = { + addDynamicImport, + findBabelLoader, + parseComponents +} diff --git a/packages/webpack-uni-mp-loader/lib/main-new.js b/packages/webpack-uni-mp-loader/lib/main-new.js new file mode 100644 index 000000000..36545b8a6 --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/main-new.js @@ -0,0 +1,143 @@ +const fs = require('fs') +const path = require('path') + +const loaderUtils = require('loader-utils') + +const parser = require('@babel/parser') + +const { + removeExt, + hyphenate, + normalizePath, + getComponentName, + jsPreprocessOptions +} = require('@dcloudio/uni-cli-shared') + +const { + updateUsingComponents +} = require('@dcloudio/uni-cli-shared/lib/cache') + +const preprocessor = require('@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader/preprocess') + +const { + resolve, + normalizeNodeModules +} = require('./shared') + +const { + findBabelLoader, + addDynamicImport +} = require('./babel/util') + +const traverse = require('./babel/global-component-traverse') + +const babelPluginCreateApp = require.resolve('./babel/plugin-create-app') + +function addCreateApp (babelLoader) { + babelLoader.options = babelLoader.options || {} + if (!babelLoader.options.plugins) { + babelLoader.options.plugins = [] + } + babelLoader.options.plugins.push([babelPluginCreateApp]) +} + +module.exports = function (content) { + this.cacheable && this.cacheable() + + if (this.resourceQuery) { + const params = loaderUtils.parseQuery(this.resourceQuery) + if (params && params.page) { + params.page = decodeURIComponent(params.page) + // import Vue from 'vue'是为了触发 vendor 合并 + let ext = '.vue' + // nvue 跨平台编译,理论上不需要这么麻烦,直接不指定后缀即可,但可能开发者有同名 js 文件,导致引用错误 + if (process.env.UNI_USING_NVUE_COMPILER) { + const vuePagePath = path.resolve(process.env.UNI_INPUT_DIR, normalizePath(params.page) + '.vue') + if (!fs.existsSync(vuePagePath)) { + const nvuePagePath = path.resolve(process.env.UNI_INPUT_DIR, normalizePath(params.page) + + '.nvue') + if (fs.existsSync(nvuePagePath)) { + ext = '.nvue' + } + } + } + return ` +import Vue from 'vue' +import Page from './${normalizePath(params.page)}${ext}' +createPage(Page) +` + } + } else { + content = preprocessor.preprocess(content, jsPreprocessOptions.context, { + type: jsPreprocessOptions.type + }) + + const resourcePath = 'app' + + const { + state: { + components + } + } = traverse(parser.parse(content, { + sourceType: 'module', + plugins: [ + 'typescript', + ['decorators', { + decoratorsBeforeExport: true + }], + 'classProperties' + ] + }), { + components: [] + }) + + const babelLoader = findBabelLoader(this.loaders) + if (!babelLoader) { + throw new Error('babel-loader 查找失败') + } else { + addCreateApp(babelLoader) + } + + if (!components.length) { + // 防止组件从有到无 + updateUsingComponents(resourcePath, Object.create(null), 'App') + return content + } + + const callback = this.async() + + const dynamicImports = Object.create(null) + + Promise.all(components.map(component => { + return resolve.call(this, component.source).then(resolved => { + component.name = getComponentName(hyphenate(component.name)) + const source = component.source + component.source = normalizeNodeModules(removeExt(path.relative(process.env.UNI_INPUT_DIR, + resolved))) + // 非页面组件才需要 dynamic import + if (!process.UNI_ENTRY[component.source]) { + dynamicImports[source] = { + identifier: component.value, + chunkName: component.source, + source + } + } + }) + })).then(() => { + const usingComponents = Object.create(null) + components.forEach(({ + name, + source + }) => { + usingComponents[name] = `/${source}` + }) + + addDynamicImport(babelLoader, resourcePath, dynamicImports) + + updateUsingComponents(resourcePath, usingComponents, 'App') + callback(null, content) + }, err => { + callback(err, content) + }) + } +} diff --git a/packages/webpack-uni-mp-loader/lib/main.js b/packages/webpack-uni-mp-loader/lib/main.js new file mode 100644 index 000000000..20ac59a5b --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/main.js @@ -0,0 +1,94 @@ +const path = require('path') + +const babel = require('@babel/core') + +const loaderUtils = require('loader-utils') + +const { + hashify, + hasModule, + removeExt, + normalizePath +} = require('@dcloudio/uni-cli-shared') + +const { + resolve, + getPlatformExts, + cacheGlobalComponents, + normalizeNodeModules +} = require('./shared') + +const babelPluginGlobalComponent = require('./babel-plugin-global-component') + +const templateExt = getPlatformExts().template + +function getNormalMainJsCode (params) { + return `import App from './${normalizePath(params.page)}.vue' +import Vue from 'vue' +App.mpType='page' +const app = new Vue(App) +app.$mount()` +} + +function getMPVuePageFactoryMainJsCode (params) { + return `import pageFactory from 'mpvue-page-factory' + import App from './${normalizePath(params.page)}.vue' + Page(pageFactory(App))` +} + +module.exports = function (content) { + if (process.env.UNI_USING_COMPONENTS) { + return require('./main-new').call(this, content) + } + this.cacheable && this.cacheable() + if (this.resourceQuery) { + const params = loaderUtils.parseQuery(this.resourceQuery) + if (params && params.page) { + params.page = decodeURIComponent(params.page) + return (process.env.UNI_PLATFORM === 'mp-weixin' || process.env.UNI_PLATFORM === 'app-plus') + ? getMPVuePageFactoryMainJsCode(params) : getNormalMainJsCode(params) + } + } else { + // 解析全局组件 + const plugins = [] + if (hasModule('@babel/plugin-syntax-typescript')) { + plugins.push('@babel/plugin-syntax-typescript') + plugins.push([ + '@babel/plugin-proposal-decorators', + { + 'legacy': true + } + ]) + } + plugins.push(babelPluginGlobalComponent) + const ast = babel.transform(content, { + root: process.env.UNI_CLI_CONTEXT, + plugins + }) + + const globalComponents = {} + + const callback = this.async() + + if (!ast.metadata.globalComponents) { + ast.metadata.globalComponents = {} + } + + Promise.all(Object.keys(ast.metadata.globalComponents).map(name => { + return resolve.call(this, ast.metadata.globalComponents[name]).then(resolved => { + resolved = path.relative(process.env.UNI_INPUT_DIR, resolved) + const hashed = hashify(resolved) + globalComponents[name] = { + name: hashed, + src: '/' + normalizeNodeModules(removeExt(resolved)) + '.vue' + + templateExt + } + }) + })).then(() => { + cacheGlobalComponents(globalComponents) + callback(null, content) + }, err => { + callback(err, content) + }) + } +} diff --git a/packages/webpack-uni-mp-loader/lib/plugin/compile-to-template.js b/packages/webpack-uni-mp-loader/lib/plugin/compile-to-template.js new file mode 100644 index 000000000..b8c5d72fa --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/plugin/compile-to-template.js @@ -0,0 +1,71 @@ +const { + hyphenate, + getPlatformCompiler +} = require('@dcloudio/uni-cli-shared') + +const SRC_REGEX = /src="([^"]+)"/g +module.exports = function compile (source, options) { + const { + compileToWxml, + compileToTemplate + } = getPlatformCompiler() + if (typeof compileToWxml === 'function') { + const components = { + 'slots': { + src: '/common/slots.wxml', + name: 'slots' + } + } + + Object.keys(options.imports).forEach(name => { + if (name !== '_slots_') { + components[hyphenate(name)] = options.imports[name] + } + }) + + const compiled = options.compiled + + const { + code, + // compiled, + slots: mpvueSlots, + importCode + } = compileToWxml(compiled, { + name: options.name, + components, + moduleId: options.scopeId || ('M' + options.name) + }) + + const deps = [] + if (importCode) { + let match + /* eslint-disable no-cond-assign */ + while (match = SRC_REGEX.exec(importCode)) { + deps.push(match[1]) + } + } + + const slots = Object.keys(mpvueSlots).map(slotName => { + const slot = mpvueSlots[slotName] + return { + name: slot.name, + slotName, + body: slot.code, + dependencies: deps + } + }) + + return { + body: code, + slots, + deps, + mpvue: true + } + } + + return compileToTemplate(source, Object.assign(options, { + htmlParse: { + templateName: 'octoParse' + } + })) +} diff --git a/packages/webpack-uni-mp-loader/lib/plugin/generate-app.js b/packages/webpack-uni-mp-loader/lib/plugin/generate-app.js new file mode 100644 index 000000000..8b2ce6924 --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/plugin/generate-app.js @@ -0,0 +1,97 @@ +const { + getPlatformExts +} = require('../shared') + +const { + getShadowCss, + getPlatformGlobal +} = require('@dcloudio/uni-cli-shared') + +const { + getSpecialMethods +} = require('@dcloudio/uni-cli-shared/lib/cache') + +module.exports = function generateApp (compilation) { + const ext = getPlatformExts().style + + let importMainCss = '' + let importVendorCss = '' + + if ( + process.env.NODE_ENV === 'production' && + process.env.UNI_PLATFORM !== 'app-plus' + ) { + const entryPage = Object.keys(process.UNI_ENTRY)[1] + const targetCssName = entryPage ? (entryPage + ext) : `common/main${ext}` + + if (!compilation.assets[targetCssName]) { + compilation.assets[targetCssName] = { + size () { + return Buffer.byteLength(getShadowCss(), 'utf8') + }, + source () { + return getShadowCss() + } + } + } else { + const source = compilation.assets[targetCssName].source() + getShadowCss() + compilation.assets[targetCssName] = { + size () { + return Buffer.byteLength(source, 'utf8') + }, + source () { + return source + } + } + } + } + + if (compilation.assets[`common/main${ext}`]) { // 是否存在 main.css + importMainCss = `@import './common/main${ext}';` + } + + if (compilation.assets[`common/vendor${ext}`]) { // 是否存在 vendor.css + importVendorCss += `@import './common/vendor${ext}';` + } + + const runtimeJsPath = 'common/runtime.js' + + if ( // app 和 baidu 不需要 + process.env.UNI_PLATFORM !== 'app-plus' && + process.env.UNI_PLATFORM !== 'mp-baidu' && + compilation.assets[runtimeJsPath] + ) { + const source = + ` + !function(){try{var r=Function("return this")();r&&!r.Math&&Object.assign(r,{Array:Array,Date:Date,Error:Error,Function:Function,Math:Math,Object:Object,RegExp:RegExp,String:String,TypeError:TypeError,setTimeout:setTimeout,clearTimeout:clearTimeout,setInterval:setInterval,clearInterval:clearInterval})}catch(r){}}(); + ${compilation.assets[runtimeJsPath].source()} + ` + compilation.assets[runtimeJsPath] = { + size () { + return Buffer.byteLength(source, 'utf8') + }, + source () { + return source + } + } + } + + const specialMethods = getSpecialMethods() + + let beforeCode = '' + if (Object.keys(specialMethods).length) { + beforeCode = `${getPlatformGlobal()}.specialMethods = ${JSON.stringify(specialMethods)}` + } + + return [{ + file: 'app.js', + source: `${beforeCode} +require('./common/runtime.js') +require('./common/vendor.js') +require('./common/main.js')` + }, { + file: 'app' + ext, + source: `${importMainCss} +${importVendorCss}` + }] +} diff --git a/packages/webpack-uni-mp-loader/lib/plugin/generate-component.js b/packages/webpack-uni-mp-loader/lib/plugin/generate-component.js new file mode 100644 index 000000000..60058d8b7 --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/plugin/generate-component.js @@ -0,0 +1,92 @@ +const path = require('path') +const { + removeExt, + normalizePath +} = require('@dcloudio/uni-cli-shared') +const { + getComponentSet +} = require('@dcloudio/uni-cli-shared/lib/cache') + +const { + restoreNodeModules +} = require('../shared') + +const uniPath = normalizePath(require.resolve('@dcloudio/uni-' + process.env.UNI_PLATFORM)) +// TODO 解决方案不太理想 +module.exports = function generateComponent (compilation) { + const components = getComponentSet() + if (components.size) { + const assets = compilation.assets + const modules = compilation.modules + + const uniModuleId = modules.find(module => module.resource && normalizePath(module.resource) === uniPath).id + + Object.keys(assets).forEach(name => { + if (components.has(name.replace('.js', ''))) { + const chunkName = name.replace('.js', '-create-component') + + let moduleId = '' + if (name.indexOf('node-modules') === 0) { + const modulePath = removeExt(restoreNodeModules(name)) + const resource = normalizePath(path.resolve(process.env.UNI_INPUT_DIR, '..', modulePath)) + const altResource = normalizePath(path.resolve(process.env.UNI_INPUT_DIR, modulePath)) + moduleId = modules.find( + module => { + if (module.resource) { + const moduleResource = removeExt(module.resource) + return ( + module.resource.indexOf('.vue') !== -1 || + module.resource.indexOf('.nvue') !== -1 + ) && + ( + moduleResource === resource || + moduleResource === altResource + ) + } + }).id + } else { + const resource = removeExt(path.resolve(process.env.UNI_INPUT_DIR, name)) + moduleId = modules.find( + module => { + return module.resource && + ( + module.resource.indexOf('.vue') !== -1 || + module.resource.indexOf('.nvue') !== -1 + ) && + removeExt(module.resource) === resource + }).id + } + + const origSource = assets[name].source() + if (origSource.length !== `Component({})`.length) { // 不是空组件 + const globalVar = process.env.UNI_PLATFORM === 'mp-alipay' ? 'my' : 'global' + // 主要是为了解决支付宝旧版本, Component 方法只在组件 js 里有,需要挂在 my.defineComponent + let beforeCode = '' + if (process.env.UNI_PLATFORM === 'mp-alipay') { + beforeCode = ';my.defineComponent || (my.defineComponent = Component);' + } + const source = beforeCode + origSource + + ` +;(${globalVar}["webpackJsonp"] = ${globalVar}["webpackJsonp"] || []).push([ + '${chunkName}', + { + '${chunkName}':(function(module, exports, __webpack_require__){ + __webpack_require__('${uniModuleId}')['createComponent'](__webpack_require__(${JSON.stringify(moduleId)})) + }) + }, + [['${chunkName}']] +]); +` + assets[name] = { + size () { + return Buffer.byteLength(source, 'utf8') + }, + source () { + return source + } + } + } + } + }) + } +} diff --git a/packages/webpack-uni-mp-loader/lib/plugin/generate-components-wxml.js b/packages/webpack-uni-mp-loader/lib/plugin/generate-components-wxml.js new file mode 100644 index 000000000..ec51d483d --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/plugin/generate-components-wxml.js @@ -0,0 +1,221 @@ +const { + md5 +} = require('@dcloudio/uni-cli-shared') + +const { + getSlotsPath +} = require('./util') + +const { + getRoot, + getPlatformExts, + getGlobalComponents, + normalizeNodeModules, + getCompiledComponentTemplate, + cacheCompiledComponentTemplates +} = require('../shared') + +const compileToTemplate = require('./compile-to-template') + +const templateExt = getPlatformExts().template + +function normalizeImports (imports = {}, componentPath, subPackages) { + const res = {} + Object.keys(imports).forEach(key => { + const { + name, + src + } = imports[key] + res[key] = { + name, + src: '/' + normalizeNodeModules(src) + '.vue' + templateExt + } + }) + + return res +} + +function generateSlotsWxml ({ + imports, + contents +}) { + let slotsOutput = '' + imports.forEach(im => { + slotsOutput = slotsOutput + `\n` + }) + + slotsOutput = slotsOutput + `\n` + + contents.forEach(b => { + slotsOutput = slotsOutput + b + `\n\n` + }) + + return slotsOutput +} + +module.exports = function generateComponentsWxml (templates, allCompilerOptions, subPackages) { + const mainSlots = { + imports: new Set(), + contents: new Set() + } + + const subPackageSlots = {} + + const files = [] + + const allDeps = new Set() // only for mpvue + + const globalComponents = getGlobalComponents() + + let isMPVue = false + + Object.keys(templates).forEach(filePath => { + const source = templates[filePath] + const compilerOptions = allCompilerOptions[filePath] + + if (!compilerOptions) { + throw new Error(filePath + ' error ') + } + + const root = getRoot(filePath, subPackages) + + const imports = normalizeImports(compilerOptions.imports, filePath, subPackages) + + // add slots + imports['_slots_'] = { + name: '', + src: getSlotsPath(root) + } + + const emitFilePath = filePath + '.vue' + templateExt + // 全局组件 + Object.keys(globalComponents).forEach(name => { + imports[name] = globalComponents[name] + }) + + const componentMD5 = md5(source + compilerOptions.scopeId + JSON.stringify(imports)) + + const compiledComponentTemplate = getCompiledComponentTemplate(filePath) + + let currentSlots = [] + + if (!subPackageSlots[root] && root) { + subPackageSlots[root] = { + imports: new Set(), + contents: new Set() + } + } + + if (compiledComponentTemplate.md5 !== componentMD5) { + const result = compileToTemplate(source, Object.assign({}, compilerOptions, { + imports + })) + let body = result.body + const { + slots, + deps = [], + mpvue, + needHtmlParse + } = result + + if (mpvue) { + isMPVue = true + deps.forEach(dep => { + allDeps.add(dep) + }) + } + + if (needHtmlParse) { + body = ` + ${body}` + } + + cacheCompiledComponentTemplates(filePath, { + md5: componentMD5, + body, + slots + }) + + currentSlots = slots || [] + + files.push({ + file: emitFilePath, + source: body + }) + } else { + currentSlots = compiledComponentTemplate.slots || [] + } + + let collector + if (root) { + collector = subPackageSlots[root] + } else { + collector = mainSlots + } + + currentSlots.forEach(slot => { + const dependencies = slot.dependencies || [] + const body = slot.body + dependencies.forEach(d => collector.imports.add(d)) + collector.contents.add(body) + + if (collector !== mainSlots) { // TODO 待优化,把分包内容全部写入主包 slots 中 + dependencies.forEach(d => mainSlots.imports.add(d)) + mainSlots.contents.add(body) + } + }) + }) + + if (!isMPVue) { + // subPackage slots + Object.keys(subPackageSlots) + .forEach(root => { + const { + imports, + contents + } = subPackageSlots[root] || {} + // subpackage slots + files.push({ + file: getSlotsPath(root), + source: generateSlotsWxml({ + imports, + contents + }) + }) + }) + } else { // merge + Object.keys(subPackageSlots) + .forEach(root => { + const { + imports, + contents + } = subPackageSlots[root] || {} + if (imports && imports.size) { + mainSlots.imports = new Set([...mainSlots.imports, ...imports]) + } + if (contents && contents.size) { + mainSlots.contents = new Set([...mainSlots.contents, ...contents]) + } + }) + // mpvue slots add all imports + allDeps.forEach(dep => { + mainSlots.imports.add(dep) + }) + } + // main slots + files.push({ + file: getSlotsPath(''), + source: generateSlotsWxml({ + imports: mainSlots.imports, + contents: mainSlots.contents + }) + }) + // TODO 遗留问题:当subPackage 引用 main 中的组件时,slots 被放在 subPackage 的 slots 中,导致 main 中的组件访问不到该 slots + + // 格式化node_modules,在微信小程序中,node_modules目录会被过滤掉,cli时 node_modules 在外层,也要转移到根目录 + files.forEach(file => { + file.file = normalizeNodeModules(file.file) + }) + + return files +} diff --git a/packages/webpack-uni-mp-loader/lib/plugin/generate-json.js b/packages/webpack-uni-mp-loader/lib/plugin/generate-json.js new file mode 100644 index 000000000..148ff8454 --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/plugin/generate-json.js @@ -0,0 +1,174 @@ +const path = require('path') + +const { + normalizePath +} = require('@dcloudio/uni-cli-shared') + +const { + getPageSet, + getJsonFileMap, + getChangedJsonFileMap +} = require('@dcloudio/uni-cli-shared/lib/cache') + +// 主要解决 extends 且未实际引用的组件 +const EMPTY_COMPONENT = `Component({})` + +const usingComponentsMap = {} + +function analyzeUsingComponents () { + if (!process.env.UNI_OPT_SUBPACKAGES) { + return + } + const pageSet = getPageSet() + const jsonFileMap = getJsonFileMap() + + // 生成所有组件引用关系 + for (let name of jsonFileMap.keys()) { + const jsonObj = JSON.parse(jsonFileMap.get(name)) + const usingComponents = jsonObj.usingComponents + if (!usingComponents || !pageSet.has(name)) { + continue + } + // usingComponentsMap[name] = {} + + Object.keys(usingComponents).forEach(componentName => { + const componentPath = usingComponents[componentName].slice(1) + if (!usingComponentsMap[componentPath]) { + usingComponentsMap[componentPath] = new Set() + } + usingComponentsMap[componentPath].add(name) + }) + } + + const subPackageRoots = Object.keys(process.UNI_SUBPACKAGES) + + const findSubPackage = function (pages) { + const pkgs = new Set() + for (let i = 0; i < pages.length; i++) { + const pagePath = pages[i] + const pkgRoot = subPackageRoots.find(root => pagePath.indexOf(root) === 0) + if (!pkgRoot) { // 被非分包引用 + return false + } + pkgs.add(pkgRoot) + if (pkgs.length > 1) { // 被多个分包引用 + return false + } + } + return [...pkgs][0] + } + + Object.keys(usingComponentsMap).forEach(componentName => { + const subPackage = findSubPackage([...usingComponentsMap[componentName]]) + if (subPackage && componentName.indexOf(subPackage) !== 0) { // 仅存在一个子包引用且未在该子包 + console.warn(`自定义组件 ${componentName} 建议移动到子包 ${subPackage} 内`) + } + }) + + // 生成所有组件递归引用关系 + // Object.keys(usingComponentsMap).forEach(name => { + // Object.keys(usingComponentsMap[name]).forEach(componentName => { + // const usingComponents = usingComponentsMap[componentName.slice(1)] + // if (usingComponents) { + // usingComponentsMap[name][componentName] = usingComponents + // } + // }) + // }) + // + // // 生成页面组件引用关系 + // const pageSet = getPageSet() + // const pagesUsingComponents = Object.keys(usingComponentsMap).reduce((pages, name) => { + // if (pageSet.has(name)) { + // pages[name] = usingComponentsMap[name] + // } + // return pages + // }, {}) +} + +module.exports = function generateJson (compilation) { + analyzeUsingComponents() + + const jsonFileMap = getChangedJsonFileMap() + for (let name of jsonFileMap.keys()) { + const jsonObj = JSON.parse(jsonFileMap.get(name)) + + // customUsingComponents + if (jsonObj.customUsingComponents && Object.keys(jsonObj.customUsingComponents)) { + jsonObj.usingComponents = Object.assign(jsonObj.customUsingComponents, jsonObj.usingComponents) + } + delete jsonObj.customUsingComponents + // usingGlobalComponents + if (jsonObj.usingGlobalComponents && Object.keys(jsonObj.usingGlobalComponents)) { + jsonObj.usingComponents = Object.assign(jsonObj.usingGlobalComponents, jsonObj.usingComponents) + } + delete jsonObj.usingGlobalComponents + + if (jsonObj.genericComponents && jsonObj.genericComponents.length) { // scoped slots + // 生成genericComponents json + const genericComponents = Object.create(null) + + const scopedSlotComponents = [] + jsonObj.genericComponents.forEach(genericComponentName => { + const genericComponentFile = normalizePath( + path.join(path.dirname(name), genericComponentName + '.json') + ) + genericComponents[genericComponentName] = '/' + + genericComponentFile.replace( + path.extname(genericComponentFile), '' + ) + scopedSlotComponents.push(genericComponentFile) + }) + + jsonObj.usingComponents = Object.assign(genericComponents, jsonObj.usingComponents) + + const scopedSlotComponentJson = { + component: true, + usingComponents: jsonObj.usingComponents + } + + const scopedSlotComponentJsonSource = JSON.stringify(scopedSlotComponentJson, null, 2) + + scopedSlotComponents.forEach(scopedSlotComponent => { + compilation.assets[scopedSlotComponent] = { + size () { + return Buffer.byteLength(scopedSlotComponentJsonSource, 'utf8') + }, + source () { + return scopedSlotComponentJsonSource + } + } + }) + } + + delete jsonObj.genericComponents + + if (process.env.UNI_PLATFORM !== 'app-plus' && process.env.UNI_PLATFORM !== 'h5') { + delete jsonObj.navigationBarShadow + } + + const source = JSON.stringify(jsonObj, null, 2) + + const jsFile = name.replace('.json', '.js') + if ( + !['app.js', 'manifest.js', 'project.config.js', 'project.swan.js'].includes(jsFile) && + !compilation.assets[jsFile] + ) { + compilation.assets[jsFile] = { + size () { + return Buffer.byteLength(EMPTY_COMPONENT, 'utf8') + }, + source () { + return EMPTY_COMPONENT + } + } + } + compilation.assets[name] = { + size () { + return Buffer.byteLength(source, 'utf8') + }, + source () { + return source + } + } + } +} diff --git a/packages/webpack-uni-mp-loader/lib/plugin/generate-pages-wxml.js b/packages/webpack-uni-mp-loader/lib/plugin/generate-pages-wxml.js new file mode 100644 index 000000000..2294ea309 --- /dev/null +++ b/packages/webpack-uni-mp-loader/lib/plugin/generate-pages-wxml.js @@ -0,0 +1,28 @@ +const path = require('path') + +const { + getPlatformExts +} = require('../shared') + +const ROOT_DATA_VAR = '$root' + +function generatePageWxml (name, importee) { + if (process.env.UNI_PLATFORM === 'mp-baidu') { + return ` +