From 13cfa70088d3506d752a4eae0fbc1c1765ad2454 Mon Sep 17 00:00:00 2001 From: yuche Date: Mon, 17 Dec 2018 17:31:50 +0800 Subject: [PATCH 001/126] =?UTF-8?q?feat(transformer):=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=BF=AB=E5=BA=94=E7=94=A8=E9=80=82=E9=85=8D=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/adapter.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/taro-transformer-wx/src/adapter.ts b/packages/taro-transformer-wx/src/adapter.ts index 97bd3340d207..f7e3f8349e44 100644 --- a/packages/taro-transformer-wx/src/adapter.ts +++ b/packages/taro-transformer-wx/src/adapter.ts @@ -61,6 +61,17 @@ const ttAdapter: Adapter = { type: Adapters.tt } +const quickappAdapter: Adapter = { + if: 'if', + else: 'else', + elseif: 'elif', + for: 'for', + forItem: 'for-item', + forIndex: 'for-index', + key: 'key', + type: Adapters.quickapp +} + export let Adapter: Adapter = weixinAdapter export function setAdapter (adapter: Adapters) { @@ -74,6 +85,9 @@ export function setAdapter (adapter: Adapters) { case Adapters.tt: Adapter = ttAdapter break + case Adapters.quickapp: + Adapter = quickappAdapter + break default: Adapter = weixinAdapter break From 9a9e9b419f74ecbc08dd648ffde4788412cd964e Mon Sep 17 00:00:00 2001 From: yuche Date: Mon, 17 Dec 2018 18:12:01 +0800 Subject: [PATCH 002/126] =?UTF-8?q?feat(transformer):=20=E6=94=B9=E5=8F=98?= =?UTF-8?q?=E5=BF=AB=E5=BA=94=E7=94=A8=E7=9A=84=E5=BE=AA=E7=8E=AF=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/jsx.ts | 28 +++++++------ packages/taro-transformer-wx/src/render.ts | 48 +++++++++++++++++----- 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/packages/taro-transformer-wx/src/jsx.ts b/packages/taro-transformer-wx/src/jsx.ts index edb59d7bcc60..f57c08067ccc 100644 --- a/packages/taro-transformer-wx/src/jsx.ts +++ b/packages/taro-transformer-wx/src/jsx.ts @@ -94,6 +94,20 @@ export function setJSXAttr ( } } +export function generateJSXAttr (ast: t.Node) { + return decodeUnicode( + generate(ast, { + quotes: 'single', + jsonCompatibleStrings: true + }) + .code + ) + .replace(/(this\.props\.)|(this\.state\.)/g, '') + .replace(/(props\.)|(state\.)/g, '') + .replace(/this\./g, '') + .replace(/ t.isLiteral(p)) } @@ -135,19 +149,7 @@ function parseJSXChildren ( if (t.isJSXElement(child.expression)) { return str + parseJSXElement(child.expression) } - return str + `{${ - decodeUnicode( - generate(child, { - quotes: 'single', - jsonCompatibleStrings: true - }) - .code - ) - .replace(/(this\.props\.)|(this\.state\.)/g, '') - .replace(/(props\.)|(state\.)/g, '') - .replace(/this\./g, '') - .replace(/ isArrayMapCallExpression(c)) From f1907b6edd5994da5f0275af01ef0ae8ace54882 Mon Sep 17 00:00:00 2001 From: yuche Date: Mon, 17 Dec 2018 19:42:53 +0800 Subject: [PATCH 003/126] =?UTF-8?q?feat(transformer):=20JSX=20=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E4=B8=B2=E5=92=8C=20JSX=20=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E5=9C=A8=E5=BF=AB=E5=BA=94=E7=94=A8=E9=83=BD=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E7=94=A8=20Text=20=E5=8C=85=E8=A3=B9=E8=B5=B7=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/index.ts | 21 ++++++++++++++++++++- packages/taro-transformer-wx/src/jsx.ts | 2 +- packages/taro-transformer-wx/src/render.ts | 15 ++++++++++++++- packages/taro-transformer-wx/src/utils.ts | 11 +++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/packages/taro-transformer-wx/src/index.ts b/packages/taro-transformer-wx/src/index.ts index c91529dd03ec..c8ea0d121a05 100644 --- a/packages/taro-transformer-wx/src/index.ts +++ b/packages/taro-transformer-wx/src/index.ts @@ -4,7 +4,15 @@ import { prettyPrint } from 'html' import { transform as parse } from 'babel-core' import * as ts from 'typescript' import { Transformer } from './class' -import { setting, findFirstIdentifierFromMemberExpression, isContainJSXElement, codeFrameError, isArrayMapCallExpression, getSuperClassCode } from './utils' +import { + setting, + findFirstIdentifierFromMemberExpression, + isContainJSXElement, + codeFrameError, + isArrayMapCallExpression, + replaceJSXTextWithTextComponent, + getSuperClassCode +} from './utils' import * as t from 'babel-types' import { DEFAULT_Component_SET, @@ -201,6 +209,17 @@ export default function transform (options: Options): TransformResult { let renderMethod!: NodePath let isImportTaro = false traverse(ast, { + JSXText (path) { + if (Adapter.type !== Adapters.quickapp) { + return + } + const value = path.node.value + if (!value.trim()) { + return + } + + replaceJSXTextWithTextComponent(path) + }, TemplateLiteral (path) { const nodes: t.Expression[] = [] const { quasis, expressions } = path.node diff --git a/packages/taro-transformer-wx/src/jsx.ts b/packages/taro-transformer-wx/src/jsx.ts index f57c08067ccc..a58bb56a4be9 100644 --- a/packages/taro-transformer-wx/src/jsx.ts +++ b/packages/taro-transformer-wx/src/jsx.ts @@ -149,7 +149,7 @@ function parseJSXChildren ( if (t.isJSXElement(child.expression)) { return str + parseJSXElement(child.expression) } - return str + generateJSXAttr(child) + return str + `{${generateJSXAttr(child)}}` } return str }, '') diff --git a/packages/taro-transformer-wx/src/render.ts b/packages/taro-transformer-wx/src/render.ts index 6d56fcc0991f..328a81609a09 100644 --- a/packages/taro-transformer-wx/src/render.ts +++ b/packages/taro-transformer-wx/src/render.ts @@ -27,7 +27,8 @@ import { noop, genCompid, findParentLoops, - setAncestorCondition + setAncestorCondition, + replaceJSXTextWithTextComponent } from './utils' import { difference, get as safeGet, cloneDeep } from 'lodash' import { @@ -1437,6 +1438,9 @@ export class RenderParser { this.handleLoopComponents() if (Adapter.type === Adapters.weapp || Adapter.type === Adapters.swan || Adapter.type === Adapters.tt) this.handleComponents(renderBody) renderBody.traverse(this.visitors) + if (Adapter.type === Adapters.quickapp) { + renderBody.traverse(this.quickappVistor) + } this.setOutputTemplate() this.checkDuplicateName() this.removeJSXStatement() @@ -1447,6 +1451,15 @@ export class RenderParser { this.setLoopRefFlag() } + private quickappVistor: Visitor = { + JSXExpressionContainer (path) { + if (path.parentPath.isJSXAttribute() || isContainJSXElement(path)) { + return + } + replaceJSXTextWithTextComponent(path) + } + } + checkDuplicateData () { this.initState.forEach((stateName) => { if (this.templates.has(stateName)) { diff --git a/packages/taro-transformer-wx/src/utils.ts b/packages/taro-transformer-wx/src/utils.ts index d934daefbd48..cc60d9b52348 100644 --- a/packages/taro-transformer-wx/src/utils.ts +++ b/packages/taro-transformer-wx/src/utils.ts @@ -11,6 +11,17 @@ import { Adapter } from './adapter' import { transformOptions } from './options' const template = require('babel-template') +export function replaceJSXTextWithTextComponent (path: NodePath) { + const parent = path.findParent(p => p.isJSXElement()) + if (parent && parent.isJSXElement() && t.isJSXIdentifier(parent.node.openingElement.name) && parent.node.openingElement.name.name !== 'Text') { + path.replaceWith(t.jSXElement( + t.jSXOpeningElement(t.jSXIdentifier('Text'), []), + t.jSXClosingElement(t.jSXIdentifier('Text')), + [path.isJSXText() ? t.jSXText(path.node.value) : path.node] + )) + } +} + export const incrementId = () => { let id = 0 return () => id++ From 9510a7e13da47ff7ae70e03876c710aa30937a36 Mon Sep 17 00:00:00 2001 From: Alan Zhang Date: Mon, 29 Oct 2018 11:40:48 +0800 Subject: [PATCH 004/126] =?UTF-8?q?feat(doctor):=20=E5=A2=9E=E5=8A=A0=20do?= =?UTF-8?q?ctor=20=E5=AD=90=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/eslint-config-taro/rules/jsx.js | 4 + packages/taro-cli/bin/taro | 1 + packages/taro-cli/bin/taro-doctor | 65 ++++++++++ packages/taro-cli/package.json | 9 ++ packages/taro-cli/src/doctor/configSchema.js | 103 ++++++++++++++++ .../taro-cli/src/doctor/configValidator.js | 33 +++++ .../taro-cli/src/doctor/eslintValidator.js | 26 ++++ packages/taro-cli/src/doctor/index.js | 8 ++ packages/taro-cli/src/doctor/joi2desc.js | 113 ++++++++++++++++++ .../taro-cli/src/doctor/packageValidator.js | 59 +++++++++ .../taro-cli/src/doctor/recommandValidator.js | 70 +++++++++++ .../taro-cli/src/doctor/validatorEslintrc.js | 9 ++ 12 files changed, 500 insertions(+) create mode 100755 packages/taro-cli/bin/taro-doctor create mode 100644 packages/taro-cli/src/doctor/configSchema.js create mode 100644 packages/taro-cli/src/doctor/configValidator.js create mode 100644 packages/taro-cli/src/doctor/eslintValidator.js create mode 100644 packages/taro-cli/src/doctor/index.js create mode 100644 packages/taro-cli/src/doctor/joi2desc.js create mode 100644 packages/taro-cli/src/doctor/packageValidator.js create mode 100644 packages/taro-cli/src/doctor/recommandValidator.js create mode 100644 packages/taro-cli/src/doctor/validatorEslintrc.js diff --git a/packages/eslint-config-taro/rules/jsx.js b/packages/eslint-config-taro/rules/jsx.js index 1250cbe45364..8bdbc1e05e8f 100644 --- a/packages/eslint-config-taro/rules/jsx.js +++ b/packages/eslint-config-taro/rules/jsx.js @@ -226,10 +226,14 @@ module.exports = { // beforeSelfClosing: 'always', // afterOpening: 'never' // }], + 'react/jsx-tag-spacing': ['error', { beforeSelfClosing: 'always' }], // Enforce spaces before the closing bracket of self-closing JSX elements // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-tag-spacing.md 'react/jsx-tag-spacing': ["error", { "beforeSelfClosing": "always" }], + // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-space-before-closing.md + // Deprecated in favor of jsx-tag-spacing + // 'react/jsx-space-before-closing': ['error', 'always'], // // Prevent usage of Array index in keys // // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-array-index-key.md diff --git a/packages/taro-cli/bin/taro b/packages/taro-cli/bin/taro index 8fd4125daa72..e4117d5ee517 100755 --- a/packages/taro-cli/bin/taro +++ b/packages/taro-cli/bin/taro @@ -21,4 +21,5 @@ program .command('update', 'Update packages of taro') .command('convert', 'Convert weapp to taro') .command('info', 'Diagnostics Taro env info') + .command('doctor', 'Diagnose taro project') .parse(process.argv) diff --git a/packages/taro-cli/bin/taro-doctor b/packages/taro-cli/bin/taro-doctor new file mode 100755 index 000000000000..771a7d6e0293 --- /dev/null +++ b/packages/taro-cli/bin/taro-doctor @@ -0,0 +1,65 @@ +#!/usr/bin/env node + +const path = require('path') +const program = require('commander') +const _ = require('lodash/fp') +const ora = require('ora') +const chalk = require('chalk') +const fs = require('fs-extra') +const { PROJECT_CONFIG } = require('../src/util') +const PROJECT_CONF_PATH = path.join(process.cwd(), PROJECT_CONFIG) + +if (!fs.existsSync(PROJECT_CONF_PATH)) { + console.log(chalk.red(`找不到项目配置文件${PROJECT_CONFIG},请确定当前目录是Taro项目根目录!`)) + process.exit(1) +} + +const { validators } = require('../src/doctor') + +const NOTE_ALL_RIGHT = chalk.green('[✓] ') +const NOTE_VALID = chalk.yellow('[!] ') +const NOTE_INVALID = chalk.red('[✗] ') + +const titleChalk = chalk.hex('#aaa') +const lineChalk = chalk.hex('#fff') +const solutionChalk = chalk.hex('#999') + +function printReport (reports) { + _.forEach(report => { + console.log('\n' + titleChalk(report.desc)) + + if (report.raw) { + console.log(report.raw) + return + } + + if (_.getOr(0, 'lines.length', report) === 0) { + console.log(` ${NOTE_ALL_RIGHT}没有发现问题`) + return + } + + _.forEach(line => { + console.log( + ' ' + + (line.valid ? NOTE_VALID : NOTE_INVALID) + + lineChalk(line.desc) + ) + if (line.solution) { + console.log(' ' + solutionChalk(line.solution)) + } + }, report.lines) + }, reports) +} + +program + .option('-v --verbose', 'Print all message') + .parse(process.argv) + +async function diagnose () { + const spinner = ora('正在诊断项目...').start() + const reportsP = _.invokeMap(_.call, validators) + const reports = await Promise.all(reportsP) + spinner.succeed('诊断完成') + printReport(reports) +} +diagnose() diff --git a/packages/taro-cli/package.json b/packages/taro-cli/package.json index 2002446e5e48..b6f4a4c214a7 100644 --- a/packages/taro-cli/package.json +++ b/packages/taro-cli/package.json @@ -47,16 +47,25 @@ "ejs": "^2.6.1", "envinfo": "^6.0.1", "fbjs": "^1.0.0", + "babel-eslint": "^8.2.3", + "eslint": "^4.15.0", + "eslint-config-taro": "^1.1.4", + "eslint-plugin-taro": "^1.1.4", + "eslint-plugin-import": "^2.8.0", + "eslint-plugin-react": "^7.4.0", + "eslint-plugin-typescript": "^0.12.0", "fs-extra": "^5.0.0", "generic-names": "^2.0.1", "glob": "^7.1.2", "inquirer": "^5.2.0", + "joi": "^14.0.6", "klaw": "^2.1.1", "latest-version": "^4.0.0", "lodash": "^4.17.5", "mem-fs": "^1.1.3", "mem-fs-editor": "^4.0.0", "minimatch": "^3.0.4", + "npm-check": "^5.9.0", "ora": "^2.0.0", "postcss": "^6.0.22", "postcss-modules-extract-imports": "^1.1.0", diff --git a/packages/taro-cli/src/doctor/configSchema.js b/packages/taro-cli/src/doctor/configSchema.js new file mode 100644 index 000000000000..51441b227109 --- /dev/null +++ b/packages/taro-cli/src/doctor/configSchema.js @@ -0,0 +1,103 @@ +const Joi = require('joi'); + +const schema = Joi.object().keys({ + 'projectName': Joi.string().required(), + 'date': Joi.date(), + 'designWidth': Joi.number().integer(), + 'deviceRatio': Joi.object().pattern( + Joi.number(), Joi.number() + ), + 'sourceRoot': Joi.string().required(), + 'outputRoot': Joi.string().required(), + + // NOTE: 考虑是否增加第三方模块的配置检查 + 'plugins': Joi.object().pattern( + Joi.string(), Joi.object() + ), + + 'env': Joi.object().pattern( + Joi.string(), Joi.string() + ), + + 'defineConstants': Joi.object().pattern( + Joi.string(), Joi.string() + ), + + 'copy': Joi.object().keys({ + 'patterns': Joi.array().items(Joi.object().keys({ + 'from': Joi.string().required(), + 'to': Joi.string().required(), + 'ignore': Joi.string() + })), + + 'options': Joi.object().keys({ + 'ignore': Joi.array().items(Joi.string()) + }) + }), + + 'weapp': Joi.object().keys({ + 'compile': Joi.object().keys({ + 'exclude': Joi.array().items(Joi.string()) + }), + 'module': Joi.object() // 第三方配置 + }), + + 'h5': Joi.object().keys({ + 'devServer': Joi.object(), // 第三方配置 + 'publicPath': Joi.string(), + 'staticDirectory': Joi.string(), + 'chunkDirectory': Joi.string(), + 'webpackChain': Joi.func(), + + // DEPRECATED: https://nervjs.github.io/taro/docs/config-detail.html#deprecated-h5webpack + 'webpack': Joi.forbidden(), + + // https://webpack.js.org/configuration/resolve/#resolve-alias + 'alias': Joi.object().pattern( + Joi.string(), Joi.string().strict() + ), + + // https://webpack.js.org/configuration/entry-context/#entry + 'entry': Joi.alternatives( + Joi.string(), + Joi.array().items(Joi.alternatives( + Joi.string(), + Joi.object().pattern( + Joi.string(), + Joi.alternatives( + Joi.string(), + Joi.array().items(Joi.string()) + ) + ) + )), + Joi.func() + ), + 'enableSourceMap': Joi.bool(), + 'enableExtract': Joi.bool(), + 'cssLoaderOption': Joi.object(), // 第三方配置 + 'styleLoaderOption': Joi.object(), // 第三方配置 + 'sassLoaderOption': Joi.object(), // 第三方配置 + 'lessLoaderOption': Joi.object(), // 第三方配置 + 'stylusLoaderOption': Joi.object(), // 第三方配置 + 'mediaUrlLoaderOption': Joi.object(), // 第三方配置 + 'fontUrlLoaderOption': Joi.object(), // 第三方配置 + 'imageUrlLoaderOption': Joi.object(), // 第三方配置 + 'miniCssExtractPluginOption': Joi.object(), // 第三方配置 + + 'module': Joi.object().keys({ + 'postcss': Joi.object().keys({ + 'autoprefixer': Joi.object().keys({ + 'enable': Joi.bool(), + 'config': Joi.object() // 第三方配置 + }), + 'pxtransform': Joi.object().keys({ + 'enable': Joi.bool(), + 'config': Joi.object() + }), + 'plugins': Joi.array() // 第三方配置 + }) + }) + }) +}) + +module.exports = schema diff --git a/packages/taro-cli/src/doctor/configValidator.js b/packages/taro-cli/src/doctor/configValidator.js new file mode 100644 index 000000000000..41e6a402b5ea --- /dev/null +++ b/packages/taro-cli/src/doctor/configValidator.js @@ -0,0 +1,33 @@ +const configSchema = require('./configSchema') +const Joi = require('joi') +const _ = require('lodash/fp') +const path = require('path') +const joi2desc = require('./joi2desc') + +const { PROJECT_CONFIG } = require('../util') +const PROJECT_CONF_PATH = path.join(process.cwd(), PROJECT_CONFIG) +const PROJECT_CONF = require(PROJECT_CONF_PATH)(_.merge) + +function buildDesc (error) { + return error.path.join('.') + ' ' + joi2desc(error) +} + +function buildLine (error) { + return { + desc: buildDesc(error), + valid: false + } +} + +function buildReport (errors) { + const errorLines = _.compose(_.map(buildLine), _.get('details'))(errors) + return { + desc: `检查 Taro 配置 (${PROJECT_CONF_PATH})`, + lines: errorLines + } +} + +module.exports = async function () { + const { error } = Joi.validate(PROJECT_CONF, configSchema, { abortEarly: false }) + return buildReport(error) +} diff --git a/packages/taro-cli/src/doctor/eslintValidator.js b/packages/taro-cli/src/doctor/eslintValidator.js new file mode 100644 index 000000000000..c2b03be66cea --- /dev/null +++ b/packages/taro-cli/src/doctor/eslintValidator.js @@ -0,0 +1,26 @@ +const path = require('path') +const _ = require('lodash') +const { CLIEngine } = require('eslint') + +const { PROJECT_CONFIG } = require('../util') +const projectConfPath = path.join(process.cwd(), PROJECT_CONFIG) +const projectConf = require(projectConfPath)(_.merge) + +const ESLINT_CONFIG_PATH = path.join(__dirname, 'validatorEslintrc.js') + +module.exports = function () { + const eslintCli = new CLIEngine({ + cwd: process.cwd(), + useEslintrc: false, + configFile: ESLINT_CONFIG_PATH + }) + + const sourceFiles = path.join(process.cwd(), projectConf.sourceRoot, '**/*.{js,ts,jsx,tsx}') + const report = eslintCli.executeOnFiles([sourceFiles]) + const formatter = eslintCli.getFormatter() + + return { + desc: '检查 ESLint (以下为 ESLint 的输出)', + raw: formatter(report.results) + } +} diff --git a/packages/taro-cli/src/doctor/index.js b/packages/taro-cli/src/doctor/index.js new file mode 100644 index 000000000000..bab3d7b8109c --- /dev/null +++ b/packages/taro-cli/src/doctor/index.js @@ -0,0 +1,8 @@ +module.exports = { + validators: [ + require('./configValidator'), + require('./packageValidator'), + require('./recommandValidator'), + require('./eslintValidator') + ] +} diff --git a/packages/taro-cli/src/doctor/joi2desc.js b/packages/taro-cli/src/doctor/joi2desc.js new file mode 100644 index 000000000000..7f43c13af799 --- /dev/null +++ b/packages/taro-cli/src/doctor/joi2desc.js @@ -0,0 +1,113 @@ +const joi2desc = { + 'alternatives.base': '不符合任何一个可选项', + 'any.empty': '不允许为空', + 'any.required': '必须填写', + 'any.unknown': '', + 'array.base': '应该为数组类型', + 'any.allowOnly': '', + 'any.default': '', + 'any.invalid': '', + 'array.excludes': '', + 'array.excludesSingle': '', + 'array.includesRequiredBoth': '', + 'array.includesRequiredKnowns': '', + 'array.includesRequiredUnknowns': '', + 'array.includes': '', + 'array.includesSingle': '', + 'array.length': '', + 'array.max': '', + 'array.min': '', + 'array.orderedLength': '', + 'array.ref': '', + 'array.sparse': '', + 'array.unique': '', + 'binary.base': '', + 'binary.length': '', + 'binary.max': '', + 'binary.min': '', + 'boolean.base': '应该为布尔值', + 'date.base': '应该为一个日期', + 'date.greater': '', + 'date.isoDate': '', + 'date.less': '', + 'date.max': '', + 'date.min': '', + 'date.ref': '', + 'date.strict': '', + 'date.timestamp.javascript': '', + 'date.timestamp.unix': '', + 'function.arity': '', + 'function.base': '应该为一个函数', + 'function.class': '', + 'function.maxArity': '', + 'function.minArity': '', + 'function.ref': '', + 'lazy.base': '', + 'lazy.schema': '', + 'number.base': '应该为一个数字', + 'number.greater': '', + 'number.integer': '', + 'number.less': '', + 'number.max': '', + 'number.min': '', + 'number.multiple': '', + 'number.negative': '', + 'number.port': '', + 'number.positive': '', + 'number.precision': '', + 'number.ref': '', + 'number.unsafe': '', + 'object.allowUnknown': '', + 'object.and': '', + 'object.assert': '', + 'object.base': '应该为一个对象', + 'object.length': '', + 'object.max': '', + 'object.min': '', + 'object.missing': '', + 'object.nand': '', + 'object.rename.multiple': '', + 'object.rename.override': '', + 'object.rename.regex.multiple': '', + 'object.rename.regex.override': '', + 'object.schema': '', + 'object.type': '', + 'object.with': '', + 'object.without': '', + 'object.xor': '', + 'string.alphanum': '', + 'string.base64': '', + 'string.base': '应该为一个字符串', + 'string.creditCard': '', + 'string.dataUri': '', + 'string.email': '', + 'string.guid': '', + 'string.hexAlign': '', + 'string.hex': '', + 'string.hostname': '', + 'string.ipVersion': '', + 'string.ip': '', + 'string.isoDate': '', + 'string.length': '', + 'string.lowercase': '', + 'string.max': '', + 'string.min': '', + 'string.normalize': '', + 'string.ref': '', + 'string.regex.base': '', + 'string.regex.name': '', + 'string.regex.invert.base': '', + 'string.regex.invert.name': '', + 'string.token': '', + 'string.trim': '', + 'string.uppercase': '', + 'string.uri': '', + 'string.uriCustomScheme': '', + 'string.uriRelativeOnly': '', + 'symbol.base': '', + 'symbol.map': '' +} + +module.exports = function (error) { + return joi2desc[error.type] || error.message +} diff --git a/packages/taro-cli/src/doctor/packageValidator.js b/packages/taro-cli/src/doctor/packageValidator.js new file mode 100644 index 000000000000..5a9c7f4f5934 --- /dev/null +++ b/packages/taro-cli/src/doctor/packageValidator.js @@ -0,0 +1,59 @@ +const _ = require('lodash/fp') +const npmCheck = require('npm-check') +const cliPkg = require('../../package.json') + +const isTaroPkg = pkg => /^@tarojs\//.test(pkg.moduleName) +const isCliVersionNotMatch = _.compose(_.negate(_.equals(cliPkg.version)), _.get('installed')) +const isPkgInstalled = _.get('isInstalled') +const isPkgNotInstalled = _.negate(isPkgInstalled) + +async function checkPkgs () { + let errorLines = [] + const pkgs = await npmCheck() + .then(_.invoke('all')) + .then(_.get('packages')) + const taroPkgs = _.filter(isTaroPkg, pkgs) + + errorLines = _.concat(errorLines, pkgsNotInstalled(pkgs)) + errorLines = _.concat(errorLines, taroShouldUpdate(taroPkgs)) + errorLines = _.concat(errorLines, taroCliVersionNotMatch(taroPkgs)) + errorLines = _.compact(errorLines) + + return { + desc: '检查依赖', + lines: errorLines + } +} + +function taroCliVersionNotMatch (pkgs) { + const pkgsNotMatch = _.filter(pkg => isPkgInstalled(pkg) && isCliVersionNotMatch(pkg), pkgs) + const lines = _.map(pkg => Object({ + desc: `${pkg.moduleName} (${pkg.installed}) 与当前使用的 @tarojs/cli (${cliPkg.version}) 版本不一致, 请更新为统一的版本`, + valid: false + }), pkgsNotMatch) + return lines +} + +function taroShouldUpdate (pkgs) { + // 未安装的依赖的情况下查找更新没有意义 + const taroPkg = _.find(isPkgInstalled, pkgs) + if (!taroPkg || taroPkg.latest === taroPkg.installed) return [] + + return [{ + // 需要正确设置 next 版本以使 npm-check 在判定最新版本时将 rc 版本也算在内 + desc: `检测到最新稳定版本 Taro ${taroPkg.latest} , 当前 cli 版本 ${cliPkg.version}`, + valid: true, // 并非错误,仅提示即可 + solution: `前往 https://github.com/NervJS/taro/releases 了解详情` + }] +} + +function pkgsNotInstalled (pkgs) { + const uninstalledPkgs = _.filter(isPkgNotInstalled, pkgs) + const lines = _.map(pkg => Object({ + desc: `使用到的依赖 ${pkg.moduleName} 还没有安装`, + valid: false + }), uninstalledPkgs) + return lines +} + +module.exports = checkPkgs diff --git a/packages/taro-cli/src/doctor/recommandValidator.js b/packages/taro-cli/src/doctor/recommandValidator.js new file mode 100644 index 000000000000..d3e036ad4cd5 --- /dev/null +++ b/packages/taro-cli/src/doctor/recommandValidator.js @@ -0,0 +1,70 @@ +const _ = require('lodash/fp') +const fs = require('fs-extra') +const path = require('path') +const chalk = require('chalk') + +const PROJECT_PACKAGE_PATH = path.join(process.cwd(), 'package.json') +const PROJECT_FOLDER_FILES = fs.readdirSync('./') +const TEST_FRAMEWORKS = ['jest', 'mocha', 'ava', 'tape', 'jesmine', 'karma'] +const LINTERS = ['eslint', 'jslint', 'tslint', 'jshint'] +const README = ['readme', 'readme.md', 'readme.markdown'] +const GITIGNORE = ['.gitignore'] +const EDITORCONFIG = ['.editorconfig'] + +if (!fs.existsSync(PROJECT_PACKAGE_PATH)) { + console.log(chalk.red(`找不到${PROJECT_PACKAGE_PATH},请确定当前目录是Taro项目根目录!`)) + process.exit(1) +} +const projectPackage = require(PROJECT_PACKAGE_PATH) +const devDependencies = _.keysIn(_.get('devDependencies', projectPackage)) + +const inDevDependencies = dependencies => (_.intersectionBy(_.toLower, devDependencies, dependencies)).length > 0 +const hasRecommandTestFrameworks = inDevDependencies(TEST_FRAMEWORKS) +const hasRecommandLinters = inDevDependencies(LINTERS) + +const inProjectFolder = filenames => (_.intersectionBy(_.toLower, PROJECT_FOLDER_FILES, filenames)).length > 0 +const hasReadme = inProjectFolder(README) +const hasGitignore = inProjectFolder(GITIGNORE) +const hasEditorconfig = inProjectFolder(EDITORCONFIG) + +module.exports = async function () { + const errorLines = [] + + if (!hasRecommandTestFrameworks) { + errorLines.push({ + desc: '没有检查到常见的测试依赖(jest/mocha/ava/tape/jesmine/karma), 配置测试可以帮助提升项目质量', + valid: true, + solution: '可以参考 https://github.com/NervJS/taro-ui-sample 项目, 其中已经包含了完整的测试配置与范例' + }) + } + if (!hasRecommandLinters) { + errorLines.push({ + desc: '没有检查到常见的 linter (eslint/jslint/jshint/tslint), 配置 linter 可以帮助提升项目质量', + valid: true, + solution: 'Taro 还提供了定制的 ESLint 规则, 可以帮助开发者避免一些常见的问题. 使用 taro cli 创建新项目即可体验' + }) + } + if (!hasReadme) { + errorLines.push({ + desc: '没有检查到 Readme (readme/readme.md/readme.markdown), 编写 Readme 可以方便其他人了解项目', + valid: true + }) + } + if (!hasGitignore) { + errorLines.push({ + desc: '没有检查到 .gitignore 配置, 配置 .gitignore 以避免将敏感信息或不必要的内容提交到代码仓库', + valid: true + }) + } + if (!hasEditorconfig) { + errorLines.push({ + desc: '没有检查到 .editconfig 配置, 配置 editconfig 以统一项目成员编辑器的代码风格', + valid: true + }) + } + + return { + desc: '检查推荐内容', + lines: errorLines + } +} diff --git a/packages/taro-cli/src/doctor/validatorEslintrc.js b/packages/taro-cli/src/doctor/validatorEslintrc.js new file mode 100644 index 000000000000..521a005d3929 --- /dev/null +++ b/packages/taro-cli/src/doctor/validatorEslintrc.js @@ -0,0 +1,9 @@ +module.exports = { + 'extends': ['taro'], + 'rules': { + 'no-unused-vars': ['error', { 'varsIgnorePattern': 'Taro' }], + 'react/jsx-filename-extension': [1, { 'extensions': ['.js', '.jsx', '.tsx'] }] + }, + 'parser': 'babel-eslint', + 'plugins': ['typescript'] +} From 905ab903ad02c951a71dd9211d9295d7dda3c767 Mon Sep 17 00:00:00 2001 From: yuche Date: Tue, 25 Dec 2018 17:14:29 +0800 Subject: [PATCH 005/126] =?UTF-8?q?refactor(transformer):=20=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E9=9C=80=E8=A6=81=E6=A0=87=E8=AE=B0=E5=BE=AA=E7=8E=AF?= =?UTF-8?q?=E7=9A=84=E5=8F=98=E9=87=8F=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/class.ts | 2 -- packages/taro-transformer-wx/src/render.ts | 21 +-------------------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/packages/taro-transformer-wx/src/class.ts b/packages/taro-transformer-wx/src/class.ts index 0f99afd2d64c..7a7c3fd02605 100644 --- a/packages/taro-transformer-wx/src/class.ts +++ b/packages/taro-transformer-wx/src/class.ts @@ -121,7 +121,6 @@ class Transformer { private classPath: NodePath private customComponentNames = new Set() private usedState = new Set() - private loopStateName: Map, string> = new Map() private customComponentData: Array = [] private componentProperies: Set private sourcePath: string @@ -806,7 +805,6 @@ class Transformer { this.initState, this.jsxReferencedIdentifiers, this.usedState, - this.loopStateName, this.customComponentNames, this.customComponentData, this.componentProperies, diff --git a/packages/taro-transformer-wx/src/render.ts b/packages/taro-transformer-wx/src/render.ts index 328a81609a09..8946f8fe227a 100644 --- a/packages/taro-transformer-wx/src/render.ts +++ b/packages/taro-transformer-wx/src/render.ts @@ -135,7 +135,6 @@ export class RenderParser { private referencedIdentifiers: Set private renderScope: Scope private usedState: Set - private loopStateName: Map, string> private customComponentData: Array private componentProperies: Set private loopRefs: Map @@ -1405,7 +1404,6 @@ export class RenderParser { initState: Set, referencedIdentifiers: Set, usedState: Set, - loopStateName: Map, string>, customComponentNames: Set, customComponentData: Array, componentProperies: Set, @@ -1415,7 +1413,6 @@ export class RenderParser { this.methods = methods this.initState = initState this.referencedIdentifiers = referencedIdentifiers - this.loopStateName = loopStateName this.usedState = usedState this.customComponentNames = customComponentNames this.customComponentData = customComponentData @@ -1816,23 +1813,7 @@ export class RenderParser { body.push(returnStatement) } else { body.push(returnStatement) - const stateName = this.loopComponentNames.get(callee) as string - this.loopStateName.forEach((newName, callExpr) => { - if (callExpr === callee) { - const classBody = this.renderPath.parent as t.ClassBody - for (const property of classBody.body) { - if (t.isClassProperty(property) && property.key.name === '$dynamicComponents') { - const objects = property.value as t.ObjectExpression - for (const objProp of objects.properties) { - if (t.isObjectProperty(objProp) && t.isIdentifier(objProp.key, { name: newName })) { - const func = objProp.value as any - func.body.body[0] = buildConstVariableDeclaration('stateName', t.stringLiteral(stateName)) - } - } - } - } - } - }) + const stateName = 'loopArray' + this.loopArrayId() // setJSXAttr(returned, Adapter.for, t.identifier(stateName)) this.addRefIdentifier(callee, t.identifier(stateName)) // this.referencedIdentifiers.add(t.identifier(stateName)) From 800f4985abeedb3c1c8081148e2dc0d6337b3f66 Mon Sep 17 00:00:00 2001 From: yuche Date: Tue, 25 Dec 2018 21:25:31 +0800 Subject: [PATCH 006/126] =?UTF-8?q?refactor(transformer):=20=E6=AF=8F?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E5=8C=85=E5=90=AB=20JSX=20=E7=9A=84=E7=B1=BB?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E9=83=BD=E6=9C=89=E7=8B=AC=E7=AB=8B=E7=9A=84?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=92=8C=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/class.ts | 51 +++++++++++++++------- packages/taro-transformer-wx/src/render.ts | 12 ++--- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/packages/taro-transformer-wx/src/class.ts b/packages/taro-transformer-wx/src/class.ts index 7a7c3fd02605..c0014e71f0b8 100644 --- a/packages/taro-transformer-wx/src/class.ts +++ b/packages/taro-transformer-wx/src/class.ts @@ -112,16 +112,15 @@ class Transformer { componentProperies: [] } private methods: ClassMethodsMap = new Map() + private renderJSX: Map> = new Map() + private refIdMap: Map, Set> = new Map() private initState: Set = new Set() - private jsxReferencedIdentifiers = new Set() private customComponents: Map = new Map() private anonymousMethod: Map = new Map() - private renderMethod: null | NodePath = null private moduleNames: string[] private classPath: NodePath private customComponentNames = new Set() private usedState = new Set() - private customComponentData: Array = [] private componentProperies: Set private sourcePath: string private refs: Ref[] = [] @@ -291,7 +290,7 @@ class Transformer { self.methods.set(name, path) if (name === 'render') { hasRender = true - self.renderMethod = path + self.renderJSX.set('render', path) path.traverse({ ReturnStatement (returnPath) { const arg = returnPath.node.argument @@ -306,6 +305,10 @@ class Transformer { } }) } + if (name.startsWith('render')) { + self.renderJSX.set(name, path) + self.refIdMap.set(path, new Set([])) + } if (name === 'constructor') { path.traverse({ AssignmentExpression (p) { @@ -336,12 +339,17 @@ class Transformer { } } }, - IfStatement (path) { + IfStatement: (path) => { const test = path.get('test') as NodePath const consequent = path.get('consequent') if (isContainJSXElement(consequent) && hasComplexExpression(test)) { - const scope = self.renderMethod && self.renderMethod.scope || path.scope - generateAnonymousState(scope, test, self.jsxReferencedIdentifiers, true) + this.renderJSX.forEach(method => { + const renderMethod = path.findParent(p => method === p) + if (renderMethod && renderMethod.isClassMethod()) { + const scope = renderMethod && renderMethod.scope || path.scope + generateAnonymousState(scope, test, this.refIdMap.get(renderMethod)!, true) + } + }) } }, ClassProperty (path) { @@ -362,6 +370,13 @@ class Transformer { JSXExpressionContainer (path) { const attr = path.findParent(p => p.isJSXAttribute()) as NodePath const isFunctionProp = attr && typeof attr.node.name.name === 'string' && attr.node.name.name.startsWith('on') + let renderMethod: NodePath + self.renderJSX.forEach(method => { + renderMethod = path.findParent(p => method === p) as NodePath + }) + + const jsxReferencedIdentifiers = self.refIdMap.get(renderMethod!)! + path.traverse({ MemberExpression (path) { const sibling = path.getSibling('property') @@ -378,9 +393,10 @@ class Transformer { }) const expression = path.get('expression') as NodePath - const scope = self.renderMethod && self.renderMethod.scope || path.scope + const scope = renderMethod! && renderMethod!.scope || path.scope const calleeExpr = expression.get('callee') const parentPath = path.parentPath + if ( hasComplexExpression(expression) && !isFunctionProp && @@ -389,11 +405,11 @@ class Transformer { calleeExpr.get('object').isMemberExpression() && calleeExpr.get('property').isIdentifier({ name: 'bind' })) // is not bind ) { - generateAnonymousState(scope, expression, self.jsxReferencedIdentifiers) + generateAnonymousState(scope, expression, jsxReferencedIdentifiers) } else { if (parentPath.isJSXAttribute()) { if (!(expression.isMemberExpression() || expression.isIdentifier()) && parentPath.node.name.name === 'key') { - generateAnonymousState(scope, expression, self.jsxReferencedIdentifiers) + generateAnonymousState(scope, expression, jsxReferencedIdentifiers) } } } @@ -524,7 +540,7 @@ class Transformer { if (!t.isJSXIdentifier(jsxName)) return if (expression.isJSXElement()) return if (DEFAULT_Component_SET.has(jsxName.name) || expression.isIdentifier() || expression.isMemberExpression() || expression.isLiteral() || expression.isLogicalExpression() || expression.isConditionalExpression() || key.name.startsWith('on') || expression.isCallExpression()) return - generateAnonymousState(scope, expression, self.jsxReferencedIdentifiers) + generateAnonymousState(scope, expression, jsxReferencedIdentifiers) }, JSXElement (path) { const id = path.node.openingElement.name @@ -797,19 +813,22 @@ class Transformer { } parseRender () { - if (this.renderMethod) { - this.result.template = this.result.template + if (this.renderJSX.size) { + this.renderJSX.forEach((method) => { + this.result.template = this.result.template + new RenderParser( - this.renderMethod, + method, this.methods, this.initState, - this.jsxReferencedIdentifiers, + this.refIdMap.get(method)!, this.usedState, this.customComponentNames, - this.customComponentData, this.componentProperies, this.loopRefs ).outputTemplate + }) + } else { + throw codeFrameError(this.classPath.node.loc, '没有定义 render 方法') } } diff --git a/packages/taro-transformer-wx/src/render.ts b/packages/taro-transformer-wx/src/render.ts index 8946f8fe227a..a3f3ad2d7fb6 100644 --- a/packages/taro-transformer-wx/src/render.ts +++ b/packages/taro-transformer-wx/src/render.ts @@ -135,7 +135,6 @@ export class RenderParser { private referencedIdentifiers: Set private renderScope: Scope private usedState: Set - private customComponentData: Array private componentProperies: Set private loopRefs: Map @@ -1398,6 +1397,12 @@ export class RenderParser { JSXExpressionContainer: this.replaceIdWithTemplate(true) } + /** + * + * @param renderPath + * @param referencedIdentifiers + * 这三个属性是需要单独传入的 + */ constructor ( renderPath: NodePath, methods: ClassMethodsMap, @@ -1405,7 +1410,6 @@ export class RenderParser { referencedIdentifiers: Set, usedState: Set, customComponentNames: Set, - customComponentData: Array, componentProperies: Set, loopRefs: Map ) { @@ -1415,7 +1419,6 @@ export class RenderParser { this.referencedIdentifiers = referencedIdentifiers this.usedState = usedState this.customComponentNames = customComponentNames - this.customComponentData = customComponentData this.componentProperies = componentProperies this.loopRefs = loopRefs const renderBody = renderPath.get('body') @@ -2014,9 +2017,6 @@ export class RenderParser { .filter(i => !i.startsWith('_$indexKey')) .filter(i => !this.loopRefIdentifiers.has(i)) let properties = propertyKeys.map(i => t.objectProperty(t.identifier(i), t.identifier(i))) - if (this.customComponentData.length > 0) { - properties = properties.concat(this.customComponentData) - } const pendingState = t.objectExpression( properties.concat( Array.from(this.classComputedState).filter(i => { From 61beca51104a62de477b4d4dfb526442afb059f2 Mon Sep 17 00:00:00 2001 From: yuche Date: Wed, 26 Dec 2018 11:38:06 +0800 Subject: [PATCH 007/126] =?UTF-8?q?refactor(transformer):=20=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=20render=20=E5=87=BD=E6=95=B0=E4=B8=8E?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E7=B1=BB=E9=9D=99=E6=80=81=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E7=9A=84=E8=81=94=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/class.ts | 7 ++-- packages/taro-transformer-wx/src/render.ts | 45 +++++++++++++++++++--- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/packages/taro-transformer-wx/src/class.ts b/packages/taro-transformer-wx/src/class.ts index c0014e71f0b8..d6be9e07fae7 100644 --- a/packages/taro-transformer-wx/src/class.ts +++ b/packages/taro-transformer-wx/src/class.ts @@ -814,7 +814,7 @@ class Transformer { parseRender () { if (this.renderJSX.size) { - this.renderJSX.forEach((method) => { + this.renderJSX.forEach((method, methodName) => { this.result.template = this.result.template + new RenderParser( method, @@ -824,8 +824,9 @@ class Transformer { this.usedState, this.customComponentNames, this.componentProperies, - this.loopRefs - ).outputTemplate + this.loopRefs, + methodName + ).outputTemplate + '\n' }) } else { throw codeFrameError(this.classPath.node.loc, '没有定义 render 方法') diff --git a/packages/taro-transformer-wx/src/render.ts b/packages/taro-transformer-wx/src/render.ts index a3f3ad2d7fb6..d3da763711de 100644 --- a/packages/taro-transformer-wx/src/render.ts +++ b/packages/taro-transformer-wx/src/render.ts @@ -30,7 +30,7 @@ import { setAncestorCondition, replaceJSXTextWithTextComponent } from './utils' -import { difference, get as safeGet, cloneDeep } from 'lodash' +import { difference, get as safeGet, cloneDeep, uniq } from 'lodash' import { setJSXAttr, buildBlockElement, @@ -128,6 +128,7 @@ export class RenderParser { private loopCallees = new Set() private loopIfStemComponentMap = new Map, t.JSXElement>() private hasNoReturnLoopStem = false + private isDefaultRender: boolean = false private renderPath: NodePath private methods: ClassMethodsMap @@ -336,6 +337,28 @@ export class RenderParser { } } + setProperies () { + if (!this.isDefaultRender) { + return + } + const properties: t.ObjectProperty[] = [] + this.componentProperies.forEach((propName) => { + properties.push( + t.objectProperty(t.stringLiteral(propName), t.objectExpression([ + t.objectProperty(t.stringLiteral('type'), t.nullLiteral()), + t.objectProperty(t.stringLiteral('value'), t.nullLiteral()) + ])) + ) + }) + let classProp = t.classProperty( + t.identifier('properties'), + t.objectExpression(properties) + ) as any + classProp.static = true + const classPath = this.renderPath.findParent(isClassDcl) as NodePath + Adapter.type !== Adapters.alipay && classPath.node.body.body.unshift(classProp) + } + setLoopRefFlag () { if (this.loopRefs.size) { const classPath = this.renderPath.findParent(isClassDcl) as NodePath @@ -1411,7 +1434,8 @@ export class RenderParser { usedState: Set, customComponentNames: Set, componentProperies: Set, - loopRefs: Map + loopRefs: Map, + methodName: string ) { this.renderPath = renderPath this.methods = methods @@ -1423,6 +1447,7 @@ export class RenderParser { this.loopRefs = loopRefs const renderBody = renderPath.get('body') this.renderScope = renderBody.scope + this.isDefaultRender = methodName === 'render' const [, error] = renderPath.node.body.body.filter(s => t.isReturnStatement(s)) if (error) { @@ -1928,12 +1953,22 @@ export class RenderParser { setCustomEvent () { const classPath = this.renderPath.findParent(isClassDcl) as NodePath - let classProp = t.classProperty(t.identifier('$$events'), t.arrayExpression(Array.from(this.usedEvents).map(s => t.stringLiteral(s)))) as any // babel 6 typing 没有 static - classProp.static = true - classPath.node.body.body.unshift(classProp) + const eventPropName = '$$events' + const body = classPath.node.body.body.find(b => t.isClassProperty(b) && b.key.name === eventPropName) as t.ClassProperty + const usedEvents = Array.from(this.usedEvents).map(s => t.stringLiteral(s)) + if (body && t.isArrayExpression(body.value)) { + body.value = t.arrayExpression(uniq(body.value.elements.concat(usedEvents))) + } else { + let classProp = t.classProperty(t.identifier('$$events'), t.arrayExpression(usedEvents)) as any // babel 6 typing 没有 static + classProp.static = true + classPath.node.body.body.unshift(classProp) + } } setUsedState () { + if (!this.isDefaultRender) { + return + } for (const [ key, method ] of this.methods) { if (method) { if (method.isClassMethod()) { From 5f95a55ca62c31b0dceb8f37d139cdad33e9b80f Mon Sep 17 00:00:00 2001 From: yuche Date: Thu, 27 Dec 2018 10:43:46 +0800 Subject: [PATCH 008/126] =?UTF-8?q?refactor(transformer):=20=E7=B1=BB?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E7=BB=84=E4=BB=B6=E7=9A=84=20createData=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/render.ts | 87 ++++++++++++++++++---- 1 file changed, 74 insertions(+), 13 deletions(-) diff --git a/packages/taro-transformer-wx/src/render.ts b/packages/taro-transformer-wx/src/render.ts index d3da763711de..69b6e067594e 100644 --- a/packages/taro-transformer-wx/src/render.ts +++ b/packages/taro-transformer-wx/src/render.ts @@ -129,6 +129,7 @@ export class RenderParser { private loopIfStemComponentMap = new Map, t.JSXElement>() private hasNoReturnLoopStem = false private isDefaultRender: boolean = false + private renderArg: t.Identifier | t.ObjectPattern | null = null private renderPath: NodePath private methods: ClassMethodsMap @@ -1466,6 +1467,23 @@ export class RenderParser { if (Adapter.type === Adapters.quickapp) { renderBody.traverse(this.quickappVistor) } + + const renderMethodArgs = this.renderPath.node.params + if (!this.isDefaultRender) { + const len = renderMethodArgs.length + if (len === 0) { + // + } else if (len === 1) { + const renderArg = renderMethodArgs[0] + if (t.isRestElement(renderArg)) { + throw codeFrameError(renderMethodArgs, '类函数式组件只能传入一个参数,如果需要传入更多参数可以考虑传入一个对象。') + } + this.renderArg = renderArg as any + } else { + throw codeFrameError(renderMethodArgs, '类函数式组件只能传入一个参数,如果需要传入更多参数可以考虑传入一个对象。') + } + } + this.setOutputTemplate() this.checkDuplicateName() this.removeJSXStatement() @@ -2026,7 +2044,7 @@ export class RenderParser { } setPendingState () { - const propertyKeys = Array.from( + let propertyKeys = Array.from( new Set(Array.from(this.referencedIdentifiers) .map(i => i.name)) ) @@ -2044,13 +2062,17 @@ export class RenderParser { return !this.methods.has(i) || isGet }) .filter(i => !this.loopScopes.has(i)) - .filter(i => !this.initState.has(i)) .filter(i => !this.templates.has(i)) .filter(i => isVarName(i)) .filter(i => i !== MAP_CALL_ITERATOR && !this.reserveStateWords.has(i)) .filter(i => !i.startsWith('$$')) .filter(i => !i.startsWith('_$indexKey')) .filter(i => !this.loopRefIdentifiers.has(i)) + + if (this.isDefaultRender) { + propertyKeys = propertyKeys.filter(i => !this.initState.has(i)) + } + let properties = propertyKeys.map(i => t.objectProperty(t.identifier(i), t.identifier(i))) const pendingState = t.objectExpression( properties.concat( @@ -2064,21 +2086,60 @@ export class RenderParser { }) ) ) - - const propsStatement: t.ExpressionStatement | t.VariableDeclaration[] = [...this.propsSettingExpressions].map(expr => { - if (typeof expr === 'function') return expr() - return expr - }) - this.renderPath.node.body.body = this.renderPath.node.body.body.concat( - ...propsStatement, - buildAssignState(pendingState), - t.returnStatement( - t.memberExpression(t.thisExpression(), t.identifier('state')) + if (this.isDefaultRender) { + this.renderPath.node.body.body = this.renderPath.node.body.body.concat( + buildAssignState(pendingState), + t.returnStatement( + t.memberExpression(t.thisExpression(), t.identifier('state')) + ) ) - ) + } else { + const usedState = Array.from(this.usedThisState).map(s => t.objectProperty(t.identifier(s), t.memberExpression(t.thisExpression(), t.identifier(s)))) + if (this.renderArg) { + if (t.isIdentifier(this.renderArg)) { + const renderArgName = this.renderArg.name + const shadowArgName = this.renderPath.scope.generateUid(renderArgName) + const renderBody = this.renderPath.get('body') + renderBody.traverse({ + Scope ({ scope }) { + scope.rename(renderArgName, shadowArgName) + } + }) + this.renderPath.node.body.body.unshift( + t.expressionStatement(t.assignmentExpression('=', t.identifier(renderArgName), t.objectExpression([ + t.objectProperty( + t.identifier(shadowArgName), + t.identifier(shadowArgName) + ) + ]))) + ) + usedState.push(t.objectProperty( + t.identifier(shadowArgName), + t.identifier(shadowArgName) + )) + } else { + // TODO + // usedState.push() + } + } + this.renderPath.node.body.body.push( + t.returnStatement(t.objectExpression(pendingState.properties.concat(usedState))) + ) + + if (t.isIdentifier(this.renderPath.node.key)) { + this.renderPath.node.key.name = this.getCreateJSXMethodName(name) + } else { + throw codeFrameError(this.renderPath.node, '类函数对象必须指明函数名') + } + } } + getCreateJSXMethodName = (name: string) => `_create${name}Data` + createData () { + if (!this.isDefaultRender) { + return + } const renderBody = this.renderPath.get('body') renderBody.traverse({ ThisExpression (path) { From 330ca404e696b27b2a0ff036467644aa9547eeba Mon Sep 17 00:00:00 2001 From: yuche Date: Thu, 27 Dec 2018 11:08:40 +0800 Subject: [PATCH 009/126] =?UTF-8?q?refactor(eslint):=20=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E6=8E=89=E6=97=A0=E6=B3=95=E5=9C=A8=E7=B1=BB=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E4=B8=AD=E4=BD=BF=E7=94=A8=20JSX=20=E7=9A=84=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/eslint-plugin-taro/rules/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin-taro/rules/index.js b/packages/eslint-plugin-taro/rules/index.js index 869b1a270461..edce1cbfa959 100644 --- a/packages/eslint-plugin-taro/rules/index.js +++ b/packages/eslint-plugin-taro/rules/index.js @@ -3,8 +3,8 @@ const has = require('has') const allRules = { // 'if-statement-in-map-loop': require('./if-statement-in-map-loop'), 'manipulate-jsx-as-array': require('./manipulate-jsx-as-array'), - // 'no-anonymous-function-in-props': require('./no-anonymous-function-in-props'), - 'no-jsx-in-class-method': require('./no-jsx-in-class-method'), + //'no-anonymous-function-in-props': require('./no-anonymous-function-in-props'), + // 'no-jsx-in-class-method': require('./no-jsx-in-class-method'), 'no-spread-in-props': require('./no-spread-in-props'), 'no-stateless-component': require('./no-stateless-component'), // 'jsx-handler-names': require('./jsx-handler-names'), From b58df6f4259f9474b289a1f7e76f0948bd5814ca Mon Sep 17 00:00:00 2001 From: yuche Date: Thu, 27 Dec 2018 17:00:13 +0800 Subject: [PATCH 010/126] =?UTF-8?q?feat(transformer):=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=B1=BB=E5=87=BD=E6=95=B0=E5=BC=8F=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/class.ts | 38 ++++++++-- packages/taro-transformer-wx/src/constant.ts | 3 +- packages/taro-transformer-wx/src/jsx.ts | 3 +- packages/taro-transformer-wx/src/render.ts | 78 +++++++++++--------- 4 files changed, 78 insertions(+), 44 deletions(-) diff --git a/packages/taro-transformer-wx/src/class.ts b/packages/taro-transformer-wx/src/class.ts index d6be9e07fae7..f1779bd2dba2 100644 --- a/packages/taro-transformer-wx/src/class.ts +++ b/packages/taro-transformer-wx/src/class.ts @@ -288,9 +288,10 @@ class Transformer { if (t.isIdentifier(node.key)) { const name = node.key.name self.methods.set(name, path) - if (name === 'render') { + if (name.startsWith('render')) { hasRender = true - self.renderJSX.set('render', path) + self.renderJSX.set(name, path) + self.refIdMap.set(path, new Set([])) path.traverse({ ReturnStatement (returnPath) { const arg = returnPath.node.argument @@ -302,13 +303,38 @@ class Transformer { returnPath.get('argument').replaceWith(t.nullLiteral()) } } + }, + CallExpression (callPath) { + const callee = callPath.get('callee') + if (!callee.isMemberExpression()) { + return + } + const args = callPath.node.arguments + const { object, property } = callee.node + if (t.isThisExpression(object) && t.isIdentifier(property) && property.name.startsWith('render')) { + if (args.length > 1) { + // @TODO: 加入文档地址 + throw codeFrameError(args[0], '类属性函数只能传入一个参数,如果你需要传入多个参数,考虑传入一个对象并使用解构语法,参考:') + } + const name = property.name + callPath.replaceWith(t.jSXElement( + t.jSXOpeningElement(t.jSXIdentifier('Template'), [ + t.jSXAttribute(t.jSXIdentifier('is'), t.stringLiteral(name)), + t.jSXAttribute(t.jSXIdentifier('data'), t.jSXExpressionContainer( + t.callExpression(t.memberExpression( + t.thisExpression(), + t.identifier(`_create${name.slice(6)}Data`) + ), args) + )) + ]), + t.jSXClosingElement(t.jSXIdentifier('Template')), + [], + false + )) + } } }) } - if (name.startsWith('render')) { - self.renderJSX.set(name, path) - self.refIdMap.set(path, new Set([])) - } if (name === 'constructor') { path.traverse({ AssignmentExpression (p) { diff --git a/packages/taro-transformer-wx/src/constant.ts b/packages/taro-transformer-wx/src/constant.ts index 2bfa4088dc3d..1a7deb47c48b 100644 --- a/packages/taro-transformer-wx/src/constant.ts +++ b/packages/taro-transformer-wx/src/constant.ts @@ -46,7 +46,8 @@ export const DEFAULT_Component_SET = new Set([ 'Ad', 'Block', 'Import', - 'OfficialAccount' + 'OfficialAccount', + 'Template' ]) export const INTERNAL_SAFE_GET = 'internal_safe_get' diff --git a/packages/taro-transformer-wx/src/jsx.ts b/packages/taro-transformer-wx/src/jsx.ts index a58bb56a4be9..c54fbb9cb99a 100644 --- a/packages/taro-transformer-wx/src/jsx.ts +++ b/packages/taro-transformer-wx/src/jsx.ts @@ -167,6 +167,7 @@ export function parseJSXElement (element: t.JSXElement): string { const componentSpecialProps = SPECIAL_COMPONENT_PROPS.get(componentName) const componentTransfromProps = TRANSFORM_COMPONENT_PROPS.get(Adapter.type) let hasElseAttr = false + const isJSXMetHod = componentName === 'Template' && attributes.some(a => a.name.name === 'is' && t.isStringLiteral(a.value) && a.value.value.startsWith('render')) attributes.forEach((a, index) => { if (t.isJSXAttribute(a) && a.name.name === Adapter.else && !['block', 'Block'].includes(componentName) && !isDefaultComponent) { hasElseAttr = true @@ -228,7 +229,7 @@ export function parseJSXElement (element: t.JSXElement): string { value = code } } else { - value = isBindEvent || isAlipayEvent ? code : `{{${code}}}` + value = isBindEvent || isAlipayEvent ? code : `{{${isJSXMetHod && name === 'data' ? '...' : ''}${code}}}` } } if (Adapter.type === Adapters.swan && name === Adapter.for) { diff --git a/packages/taro-transformer-wx/src/render.ts b/packages/taro-transformer-wx/src/render.ts index 69b6e067594e..27c7bf067a44 100644 --- a/packages/taro-transformer-wx/src/render.ts +++ b/packages/taro-transformer-wx/src/render.ts @@ -129,7 +129,8 @@ export class RenderParser { private loopIfStemComponentMap = new Map, t.JSXElement>() private hasNoReturnLoopStem = false private isDefaultRender: boolean = false - private renderArg: t.Identifier | t.ObjectPattern | null = null + // private renderArg: t.Identifier | t.ObjectPattern | null = null + private renderMethodName: string = '' private renderPath: NodePath private methods: ClassMethodsMap @@ -1478,12 +1479,19 @@ export class RenderParser { if (t.isRestElement(renderArg)) { throw codeFrameError(renderMethodArgs, '类函数式组件只能传入一个参数,如果需要传入更多参数可以考虑传入一个对象。') } - this.renderArg = renderArg as any + // this.renderArg = renderArg as any } else { throw codeFrameError(renderMethodArgs, '类函数式组件只能传入一个参数,如果需要传入更多参数可以考虑传入一个对象。') } } + if (t.isIdentifier(this.renderPath.node.key)) { + this.renderMethodName = this.renderPath.node.key.name + this.renderPath.node.key.name = this.getCreateJSXMethodName(this.renderMethodName) + } else { + throw codeFrameError(this.renderPath.node, '类函数对象必须指明函数名') + } + this.setOutputTemplate() this.checkDuplicateName() this.removeJSXStatement() @@ -1907,6 +1915,9 @@ export class RenderParser { setOutputTemplate () { this.outputTemplate = parseJSXElement(this.finalReturnElement) + if (!this.isDefaultRender) { + this.outputTemplate = `` + } } removeJSXStatement () { @@ -2095,46 +2106,41 @@ export class RenderParser { ) } else { const usedState = Array.from(this.usedThisState).map(s => t.objectProperty(t.identifier(s), t.memberExpression(t.thisExpression(), t.identifier(s)))) - if (this.renderArg) { - if (t.isIdentifier(this.renderArg)) { - const renderArgName = this.renderArg.name - const shadowArgName = this.renderPath.scope.generateUid(renderArgName) - const renderBody = this.renderPath.get('body') - renderBody.traverse({ - Scope ({ scope }) { - scope.rename(renderArgName, shadowArgName) - } - }) - this.renderPath.node.body.body.unshift( - t.expressionStatement(t.assignmentExpression('=', t.identifier(renderArgName), t.objectExpression([ - t.objectProperty( - t.identifier(shadowArgName), - t.identifier(shadowArgName) - ) - ]))) - ) - usedState.push(t.objectProperty( - t.identifier(shadowArgName), - t.identifier(shadowArgName) - )) - } else { - // TODO - // usedState.push() - } - } + // if (this.renderArg) { + // if (t.isIdentifier(this.renderArg)) { + // const renderArgName = this.renderArg.name + // const shadowArgName = this.renderPath.scope.generateUid(renderArgName) + // const renderBody = this.renderPath.get('body') + // renderBody.traverse({ + // Scope ({ scope }) { + // scope.rename(renderArgName, shadowArgName) + // } + // }) + // this.renderPath.node.body.body.unshift( + // // t.expressionStatement(t.assignmentExpression('=', t.identifier(renderArgName), t.objectExpression([ + // // t.objectProperty( + // // t.identifier(shadowArgName), + // // t.identifier(shadowArgName) + // // ) + // // ]))) + // buildConstVariableDeclaration(shadowArgName, t.identifier(renderArgName)) + // ) + // usedState.push(t.objectProperty( + // t.identifier(shadowArgName), + // t.identifier(shadowArgName) + // )) + // } else { + // // TODO + // // usedState.push() + // } + // } this.renderPath.node.body.body.push( t.returnStatement(t.objectExpression(pendingState.properties.concat(usedState))) ) - - if (t.isIdentifier(this.renderPath.node.key)) { - this.renderPath.node.key.name = this.getCreateJSXMethodName(name) - } else { - throw codeFrameError(this.renderPath.node, '类函数对象必须指明函数名') - } } } - getCreateJSXMethodName = (name: string) => `_create${name}Data` + getCreateJSXMethodName = (name: string) => `_create${name.slice(6)}Data` createData () { if (!this.isDefaultRender) { From 482754939e30e4197190e09eb8762d701a018dbd Mon Sep 17 00:00:00 2001 From: luckyadam Date: Wed, 2 Jan 2019 00:33:03 +0800 Subject: [PATCH 011/126] =?UTF-8?q?feat(cli):=20=E4=BD=BF=E7=94=A8=20types?= =?UTF-8?q?cript=20=E9=87=8D=E6=9E=84=20cli=20=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/bin/taro | 10 +- packages/taro-cli/bin/taro-build | 4 +- packages/taro-cli/bin/taro-convert | 2 +- packages/taro-cli/bin/taro-doctor | 4 +- packages/taro-cli/bin/taro-info | 4 +- packages/taro-cli/bin/taro-init | 4 +- packages/taro-cli/bin/taro-update | 9 +- packages/taro-cli/bin/year.txt | 9 - packages/taro-cli/global.d.ts | 4 + packages/taro-cli/package.json | 37 +- packages/taro-cli/src/build.js | 108 - packages/taro-cli/src/build.ts | 108 + .../src/config/{babel.js => babel.ts} | 10 +- .../src/config/{babylon.js => babylon.ts} | 2 +- .../{browser_list.js => browser_list.ts} | 2 +- .../src/config/{index.js => index.ts} | 2 +- packages/taro-cli/src/config/uglify.js | 3 - packages/taro-cli/src/config/uglify.ts | 1 + packages/taro-cli/src/convertor/helper.ts | 66 + .../src/{convertor.js => convertor/index.ts} | 289 ++- packages/taro-cli/src/creator.js | 86 - packages/taro-cli/src/creator.ts | 118 + .../{configSchema.js => configSchema.ts} | 4 +- ...{configValidator.js => configValidator.ts} | 15 +- ...{eslintValidator.js => eslintValidator.ts} | 11 +- .../src/doctor/{index.js => index.ts} | 2 +- packages/taro-cli/src/doctor/interface.ts | 5 + .../src/doctor/{joi2desc.js => joi2desc.ts} | 2 +- ...ackageValidator.js => packageValidator.ts} | 18 +- ...mandValidator.js => recommandValidator.ts} | 14 +- ...idatorEslintrc.js => validatorEslintrc.ts} | 2 +- packages/taro-cli/src/extra/util_wxs | 11 - packages/taro-cli/src/{h5.js => h5.ts} | 168 +- ...rt_to_jdreact.js => convert_to_jdreact.ts} | 31 +- packages/taro-cli/src/mini/astProcess.ts | 882 +++++++ packages/taro-cli/src/mini/compileScript.ts | 157 ++ packages/taro-cli/src/mini/compileStyle.ts | 255 ++ packages/taro-cli/src/mini/component.ts | 331 +++ packages/taro-cli/src/mini/constants.ts | 18 + packages/taro-cli/src/mini/copy.ts | 20 + packages/taro-cli/src/mini/entry.ts | 181 ++ packages/taro-cli/src/mini/helper.ts | 334 +++ packages/taro-cli/src/mini/index.ts | 153 ++ packages/taro-cli/src/mini/interface.ts | 29 + packages/taro-cli/src/mini/native.ts | 106 + packages/taro-cli/src/mini/npmExact.ts | 69 + packages/taro-cli/src/mini/page.ts | 220 ++ packages/taro-cli/src/mini/watch.ts | 203 ++ .../taro-cli/src/{plugin.js => plugin.ts} | 237 +- .../taro-cli/src/{project.js => project.ts} | 47 +- packages/taro-cli/src/{rn.js => rn.ts} | 101 +- .../{ColorPropType.js => ColorPropType.ts} | 4 +- ...{ImageResizeMode.js => ImageResizeMode.ts} | 6 +- ...ylePropTypes.js => ImageStylePropTypes.ts} | 14 +- ...{LayoutPropTypes.js => LayoutPropTypes.ts} | 6 +- ...wPropTypesIOS.js => ShadowPropTypesIOS.ts} | 8 +- ...tValidation.js => StyleSheetValidation.ts} | 14 +- ...tylePropTypes.js => TextStylePropTypes.ts} | 8 +- ...formPropTypes.js => TransformPropTypes.ts} | 6 +- ...tylePropTypes.js => ViewStylePropTypes.ts} | 12 +- ...catedPropType.js => deprecatedPropType.ts} | 6 +- packages/taro-cli/src/rn/StyleSheet/index.js | 3 - packages/taro-cli/src/rn/StyleSheet/index.ts | 5 + .../{normalizeColor.js => normalizeColor.ts} | 5 +- .../rn/{styleProcess.js => styleProcess.ts} | 42 +- .../src/rn/{transformJS.js => transformJS.ts} | 125 +- packages/taro-cli/src/{ui.js => ui.ts} | 84 +- .../util/{ast_convert.js => astConvert.ts} | 56 +- packages/taro-cli/src/util/constants.ts | 259 ++ packages/taro-cli/src/util/index.js | 625 ----- packages/taro-cli/src/util/index.ts | 406 +++ packages/taro-cli/src/util/{npm.js => npm.ts} | 60 +- ...olve_npm_files.js => resolve_npm_files.ts} | 145 +- packages/taro-cli/src/util/types.ts | 182 ++ packages/taro-cli/src/weapp.js | 2275 ----------------- packages/taro-cli/tsconfig.json | 26 + packages/taro-cli/tslint.json | 31 + packages/taro-cli/yarn.lock | 1054 +++++++- packages/taro/types/index.d.ts | 5 +- 79 files changed, 6017 insertions(+), 3963 deletions(-) delete mode 100644 packages/taro-cli/bin/year.txt create mode 100644 packages/taro-cli/global.d.ts delete mode 100644 packages/taro-cli/src/build.js create mode 100644 packages/taro-cli/src/build.ts rename packages/taro-cli/src/config/{babel.js => babel.ts} (57%) rename packages/taro-cli/src/config/{babylon.js => babylon.ts} (93%) rename packages/taro-cli/src/config/{browser_list.js => browser_list.ts} (74%) rename packages/taro-cli/src/config/{index.js => index.ts} (83%) delete mode 100644 packages/taro-cli/src/config/uglify.js create mode 100644 packages/taro-cli/src/config/uglify.ts create mode 100644 packages/taro-cli/src/convertor/helper.ts rename packages/taro-cli/src/{convertor.js => convertor/index.ts} (74%) delete mode 100644 packages/taro-cli/src/creator.js create mode 100644 packages/taro-cli/src/creator.ts rename packages/taro-cli/src/doctor/{configSchema.js => configSchema.ts} (98%) rename packages/taro-cli/src/doctor/{configValidator.js => configValidator.ts} (70%) rename packages/taro-cli/src/doctor/{eslintValidator.js => eslintValidator.ts} (78%) rename packages/taro-cli/src/doctor/{index.js => index.ts} (89%) create mode 100644 packages/taro-cli/src/doctor/interface.ts rename packages/taro-cli/src/doctor/{joi2desc.js => joi2desc.ts} (98%) rename packages/taro-cli/src/doctor/{packageValidator.js => packageValidator.ts} (81%) rename packages/taro-cli/src/doctor/{recommandValidator.js => recommandValidator.ts} (92%) rename packages/taro-cli/src/doctor/{validatorEslintrc.js => validatorEslintrc.ts} (92%) delete mode 100644 packages/taro-cli/src/extra/util_wxs rename packages/taro-cli/src/{h5.js => h5.ts} (90%) rename packages/taro-cli/src/jdreact/{convert_to_jdreact.js => convert_to_jdreact.ts} (77%) create mode 100644 packages/taro-cli/src/mini/astProcess.ts create mode 100644 packages/taro-cli/src/mini/compileScript.ts create mode 100644 packages/taro-cli/src/mini/compileStyle.ts create mode 100644 packages/taro-cli/src/mini/component.ts create mode 100644 packages/taro-cli/src/mini/constants.ts create mode 100644 packages/taro-cli/src/mini/copy.ts create mode 100644 packages/taro-cli/src/mini/entry.ts create mode 100644 packages/taro-cli/src/mini/helper.ts create mode 100644 packages/taro-cli/src/mini/index.ts create mode 100644 packages/taro-cli/src/mini/interface.ts create mode 100644 packages/taro-cli/src/mini/native.ts create mode 100644 packages/taro-cli/src/mini/npmExact.ts create mode 100644 packages/taro-cli/src/mini/page.ts create mode 100644 packages/taro-cli/src/mini/watch.ts rename packages/taro-cli/src/{plugin.js => plugin.ts} (65%) rename packages/taro-cli/src/{project.js => project.ts} (84%) rename packages/taro-cli/src/{rn.js => rn.ts} (76%) rename packages/taro-cli/src/rn/StyleSheet/{ColorPropType.js => ColorPropType.ts} (95%) rename packages/taro-cli/src/rn/StyleSheet/{ImageResizeMode.js => ImageResizeMode.ts} (93%) rename packages/taro-cli/src/rn/StyleSheet/{ImageStylePropTypes.js => ImageStylePropTypes.ts} (82%) rename packages/taro-cli/src/rn/StyleSheet/{LayoutPropTypes.js => LayoutPropTypes.ts} (99%) rename packages/taro-cli/src/rn/StyleSheet/{ShadowPropTypesIOS.js => ShadowPropTypesIOS.ts} (89%) rename packages/taro-cli/src/rn/StyleSheet/{StyleSheetValidation.js => StyleSheetValidation.ts} (85%) rename packages/taro-cli/src/rn/StyleSheet/{TextStylePropTypes.js => TextStylePropTypes.ts} (93%) rename packages/taro-cli/src/rn/StyleSheet/{TransformPropTypes.js => TransformPropTypes.ts} (95%) rename packages/taro-cli/src/rn/StyleSheet/{ViewStylePropTypes.js => ViewStylePropTypes.ts} (86%) rename packages/taro-cli/src/rn/StyleSheet/{deprecatedPropType.js => deprecatedPropType.ts} (90%) delete mode 100644 packages/taro-cli/src/rn/StyleSheet/index.js create mode 100644 packages/taro-cli/src/rn/StyleSheet/index.ts rename packages/taro-cli/src/rn/StyleSheet/{normalizeColor.js => normalizeColor.ts} (99%) rename packages/taro-cli/src/rn/{styleProcess.js => styleProcess.ts} (69%) rename packages/taro-cli/src/rn/{transformJS.js => transformJS.ts} (82%) rename packages/taro-cli/src/{ui.js => ui.ts} (87%) rename packages/taro-cli/src/util/{ast_convert.js => astConvert.ts} (62%) create mode 100644 packages/taro-cli/src/util/constants.ts delete mode 100644 packages/taro-cli/src/util/index.js create mode 100644 packages/taro-cli/src/util/index.ts rename packages/taro-cli/src/util/{npm.js => npm.ts} (71%) rename packages/taro-cli/src/util/{resolve_npm_files.js => resolve_npm_files.ts} (70%) create mode 100644 packages/taro-cli/src/util/types.ts delete mode 100644 packages/taro-cli/src/weapp.js create mode 100644 packages/taro-cli/tsconfig.json create mode 100644 packages/taro-cli/tslint.json diff --git a/packages/taro-cli/bin/taro b/packages/taro-cli/bin/taro index e4117d5ee517..94234368074f 100755 --- a/packages/taro-cli/bin/taro +++ b/packages/taro-cli/bin/taro @@ -1,18 +1,10 @@ #! /usr/bin/env node const program = require('commander') -const { getPkgVersion, printPkgVersion } = require('../src/util') +const { getPkgVersion, printPkgVersion } = require('../dist/util') printPkgVersion() -const startTime = new Date('2019-1-1 00:00').getTime() -const endTime = new Date('2019-1-2 00:00').getTime() -const nowTime = Date.now() -if (nowTime >= startTime && nowTime <= endTime) { - const yearTxt = String(require('fs-extra').readFileSync(require('path').resolve(__dirname, 'year.txt'))) - console.log(require('chalk').rgb(255, 87, 34)(yearTxt)) -} - program .version(getPkgVersion()) .usage(' [options]') diff --git a/packages/taro-cli/bin/taro-build b/packages/taro-cli/bin/taro-build index 5adf0879e6ce..1d91fdd009e8 100755 --- a/packages/taro-cli/bin/taro-build +++ b/packages/taro-cli/bin/taro-build @@ -5,8 +5,8 @@ const program = require('commander') const chalk = require('chalk') const _ = require('lodash') -const build = require('../src/build') -const { PROJECT_CONFIG, BUILD_TYPES } = require('../src/util') +const build = require('../dist/build').default +const { PROJECT_CONFIG, BUILD_TYPES } = require('../dist/util/constants') const projectConfPath = path.join(process.cwd(), PROJECT_CONFIG) program diff --git a/packages/taro-cli/bin/taro-convert b/packages/taro-cli/bin/taro-convert index 28bba8f4f202..aac8fd0c6410 100755 --- a/packages/taro-cli/bin/taro-convert +++ b/packages/taro-cli/bin/taro-convert @@ -2,7 +2,7 @@ const program = require('commander') -const Convertor = require('../src/convertor') +const Convertor = require('../dist/convertor') program .parse(process.argv) diff --git a/packages/taro-cli/bin/taro-doctor b/packages/taro-cli/bin/taro-doctor index 771a7d6e0293..a0b60c550d83 100755 --- a/packages/taro-cli/bin/taro-doctor +++ b/packages/taro-cli/bin/taro-doctor @@ -6,7 +6,7 @@ const _ = require('lodash/fp') const ora = require('ora') const chalk = require('chalk') const fs = require('fs-extra') -const { PROJECT_CONFIG } = require('../src/util') +const { PROJECT_CONFIG } = require('../dist/util') const PROJECT_CONF_PATH = path.join(process.cwd(), PROJECT_CONFIG) if (!fs.existsSync(PROJECT_CONF_PATH)) { @@ -14,7 +14,7 @@ if (!fs.existsSync(PROJECT_CONF_PATH)) { process.exit(1) } -const { validators } = require('../src/doctor') +const { validators } = require('../dist/doctor') const NOTE_ALL_RIGHT = chalk.green('[✓] ') const NOTE_VALID = chalk.yellow('[!] ') diff --git a/packages/taro-cli/bin/taro-info b/packages/taro-cli/bin/taro-info index 8adfb457f934..b6f928ed26a4 100755 --- a/packages/taro-cli/bin/taro-info +++ b/packages/taro-cli/bin/taro-info @@ -2,7 +2,7 @@ const fs = require('fs') const path = require('path') const envinfo = require('envinfo') -const {getPkgVersion, UPDATE_PACKAGE_LIST} = require('../src/util') +const { getPkgVersion, UPDATE_PACKAGE_LIST } = require('../dist/util') const process = require('process') const program = require('commander') @@ -37,7 +37,7 @@ function rnInfo (options) { } async function info (options) { - let info = await envinfo.run(Object.assign({}, { + const info = await envinfo.run(Object.assign({}, { System: ['OS', 'Shell'], Binaries: ['Node', 'Yarn', 'npm'], npmPackages, diff --git a/packages/taro-cli/bin/taro-init b/packages/taro-cli/bin/taro-init index 739ca6784990..181a7fb2a37c 100755 --- a/packages/taro-cli/bin/taro-init +++ b/packages/taro-cli/bin/taro-init @@ -2,7 +2,7 @@ const program = require('commander') -const Project = require('../src/project') +const Project = require('../dist/project').default program .option('--name [name]', '项目名称') @@ -15,7 +15,7 @@ program const args = program.args const { template, description, name, css } = program -let typescript = '' +let typescript = false /** * 非标准做法 diff --git a/packages/taro-cli/bin/taro-update b/packages/taro-cli/bin/taro-update index 157aeb2a8c8a..475119914d96 100755 --- a/packages/taro-cli/bin/taro-update +++ b/packages/taro-cli/bin/taro-update @@ -3,14 +3,13 @@ const path = require('path') const fs = require('fs-extra') const program = require('commander') const chalk = require('chalk') -const { getPkgItemByKey } = require('../src/util') +const { getPkgItemByKey, shouldUseYarn, shouldUseCnpm } = require('../dist/util') const ora = require('ora') const exec = require('child_process').exec const getLatestVersion = require('latest-version') -const { PROJECT_CONFIG, UPDATE_PACKAGE_LIST} = require('../src/util') +const { PROJECT_CONFIG, UPDATE_PACKAGE_LIST } = require('../dist/util/constants') const projectConfPath = path.join(process.cwd(), PROJECT_CONFIG) const pkgPath = path.join(process.cwd(), 'package.json') -const { shouldUseYarn, shouldUseCnpm } = require('../src/util') const pkgName = getPkgItemByKey('name') @@ -50,7 +49,7 @@ function updateSelf () { command = 'npm i -g @tarojs/cli@latest' } - let child = exec(command) + const child = exec(command) const spinner = ora('即将将 Taro 开发工具 taro-cli 更新到最新版本...').start() @@ -103,7 +102,7 @@ async function updateProject () { command = 'npm install' } - let child = exec(command) + const child = exec(command) const spinner = ora('即将将项目所有 Taro 相关依赖更新到最新版本...').start() diff --git a/packages/taro-cli/bin/year.txt b/packages/taro-cli/bin/year.txt deleted file mode 100644 index dc47403739fa..000000000000 --- a/packages/taro-cli/bin/year.txt +++ /dev/null @@ -1,9 +0,0 @@ -🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 -🎉 _ _ _ _ _____ _____ __ _____ _ 🎉 -🏮 | | | | | | | / __ | _ / || _ | | | 🏮 -🎉 | |_| | ___| | | ___ `' / /| |/' `| || |_| | | | 🎉 -🏮 | _ |/ _ | | |/ _ \ / / | /| || |\____ | | | 🏮 -🎉 | | | | __| | | (_) | ./ /__\ |_/ _| |.___/ / |_| 🎉 -🏮 \_| |_/\___|_|_|\___/ \_____/\___/\___\____/ (_) 🏮 -🎉 🎉 -🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 🎉 🏮 diff --git a/packages/taro-cli/global.d.ts b/packages/taro-cli/global.d.ts new file mode 100644 index 000000000000..6568666452a0 --- /dev/null +++ b/packages/taro-cli/global.d.ts @@ -0,0 +1,4 @@ +declare module '*.json' { + const value: any + export default value +} diff --git a/packages/taro-cli/package.json b/packages/taro-cli/package.json index b6f4a4c214a7..041ba2b55bda 100644 --- a/packages/taro-cli/package.json +++ b/packages/taro-cli/package.json @@ -4,7 +4,14 @@ "description": "cli tool for taro", "main": "index.js", "scripts": { - "test": "jest" + "test": "jest", + "build": "run-s clean prod", + "dev": "tsc -w", + "prod": "tsc", + "clean": "rimraf dist", + "lint": "tslint src/**/*.ts --fix", + "lint:typecheck": "tslint -p tsconfig.json src/**/*.ts --fix", + "prepack": "npm run build" }, "repository": { "type": "git", @@ -27,6 +34,7 @@ "@tarojs/transformer-wx": "1.2.27-beta.0", "autoprefixer": "^8.4.1", "babel-core": "^6.26.3", + "babel-eslint": "^8.2.3", "babel-generator": "^6.26.1", "babel-plugin-danger-remove-unused-import": "^1.1.1", "babel-plugin-remove-dead-code": "^1.3.2", @@ -47,12 +55,11 @@ "ejs": "^2.6.1", "envinfo": "^6.0.1", "fbjs": "^1.0.0", - "babel-eslint": "^8.2.3", "eslint": "^4.15.0", "eslint-config-taro": "^1.1.4", - "eslint-plugin-taro": "^1.1.4", "eslint-plugin-import": "^2.8.0", "eslint-plugin-react": "^7.4.0", + "eslint-plugin-taro": "^1.1.4", "eslint-plugin-typescript": "^0.12.0", "fs-extra": "^5.0.0", "generic-names": "^2.0.1", @@ -77,8 +84,8 @@ "postcss-reporter": "^6.0.1", "postcss-taro-unit-transform": "1.2.15", "postcss-url": "^7.3.2", - "prettier": "^1.14.3", - "prop-types": "^15.6.1", + "prettier": "^1.15.3", + "prop-types": "^15.6.2", "resolve": "^1.6.0", "semver": "^5.5.0", "shelljs": "^0.8.1", @@ -90,6 +97,19 @@ "vinyl-fs": "^3.0.2" }, "devDependencies": { + "@types/autoprefixer": "^9.1.1", + "@types/klaw": "^3.0.0", + "@types/shelljs": "^0.8.5", + "@types/ejs": "^2.6.3", + "@tarojs/taro": "^1.2.2", + "@types/babel-core": "^6.25.5", + "@types/babel-generator": "^6.25.2", + "@types/babel-traverse": "^6.25.4", + "@types/babel-types": "^6.25.2", + "@types/fs-extra": "^5.0.4", + "@types/jest": "^23.3.10", + "@types/lodash": "^4.14.119", + "@types/node": "^10.12.18", "babel-jest": "^23.6.0", "babel-plugin-transform-class-properties": "^6.24.1", "babel-preset-env": "^1.7.0", @@ -97,6 +117,11 @@ "babel-preset-stage-0": "^6.24.1", "jest": "^23.6.0", "jest-react-native": "^18.0.0", - "react-native": "0.55.4" + "npm-run-all": "^4.1.5", + "react-native": "^0.55.4", + "tslint": "^5.12.0", + "tslint-config-prettier": "^1.17.0", + "tslint-config-standard": "^8.0.1", + "typescript": "^3.2.2" } } diff --git a/packages/taro-cli/src/build.js b/packages/taro-cli/src/build.js deleted file mode 100644 index 0cb2182b43a0..000000000000 --- a/packages/taro-cli/src/build.js +++ /dev/null @@ -1,108 +0,0 @@ -const fs = require('fs-extra') -const path = require('path') -const chalk = require('chalk') -const _ = require('lodash') - -const Util = require('./util') -const CONFIG = require('./config') - -const appPath = process.cwd() - -function build (args, buildConfig) { - const { type, watch } = buildConfig - const configDir = require(path.join(appPath, Util.PROJECT_CONFIG))(_.merge) - const outputPath = path.join(appPath, configDir.outputRoot || CONFIG.OUTPUT_DIR) - if (!fs.existsSync(outputPath)) { - fs.ensureDirSync(outputPath) - } else { - if (type !== Util.BUILD_TYPES.H5) { - Util.emptyDirectory(outputPath) - } - } - switch (type) { - case Util.BUILD_TYPES.H5: - buildForH5({ watch }) - break - case Util.BUILD_TYPES.WEAPP: - buildForWeapp({ watch }) - break - case Util.BUILD_TYPES.SWAN: - buildForSwan({ watch }) - break - case Util.BUILD_TYPES.ALIPAY: - buildForAlipay({ watch }) - break - case Util.BUILD_TYPES.TT: - buildForTt({ watch }) - break - case Util.BUILD_TYPES.RN: - buildForRN({ watch }) - break - case Util.BUILD_TYPES.UI: - buildForUILibrary({ watch }) - break - case Util.BUILD_TYPES.PLUGIN: - buildForPlugin({ - watch, - platform: buildConfig.platform - }) - break - default: - console.log(chalk.red('输入类型错误,目前只支持 weapp/h5/rn/swan/alipay/tt 六端类型')) - } -} - -function buildForWeapp ({ watch }) { - require('./weapp').build({ - watch, - adapter: Util.BUILD_TYPES.WEAPP - }) -} - -function buildForSwan ({ watch }) { - require('./weapp').build({ - watch, - adapter: Util.BUILD_TYPES.SWAN - }) -} - -function buildForAlipay ({ watch }) { - require('./weapp').build({ - watch, - adapter: Util.BUILD_TYPES.ALIPAY - }) -} - -function buildForTt ({ watch }) { - require('./weapp').build({ - watch, - adapter: Util.BUILD_TYPES.TT - }) -} - -function buildForH5 (buildConfig) { - require('./h5').build(buildConfig) -} - -function buildForRN ({ watch }) { - require('./rn').build({ watch }) -} - -function buildForUILibrary ({ watch }) { - require('./ui').build({ watch }) -} - -function buildForPlugin ({ watch, platform }) { - const typeMap = { - [Util.BUILD_TYPES.WEAPP]: '微信', - [Util.BUILD_TYPES.ALIPAY]: '支付宝' - } - if (platform !== Util.BUILD_TYPES.WEAPP && platform !== Util.BUILD_TYPES.ALIPAY) { - console.log(chalk.red('目前插件编译仅支持 微信/支付宝 小程序!')) - return - } - console.log(chalk.green(`开始编译${typeMap[platform]}小程序插件`)) - require('./plugin').build({ watch, platform }) -} - -module.exports = build diff --git a/packages/taro-cli/src/build.ts b/packages/taro-cli/src/build.ts new file mode 100644 index 000000000000..b738d2ddba0a --- /dev/null +++ b/packages/taro-cli/src/build.ts @@ -0,0 +1,108 @@ +import * as path from 'path' +import * as fs from 'fs-extra' +import chalk from 'chalk' +import * as _ from 'lodash' + +import * as Util from './util' +import CONFIG from './config' +import { BUILD_TYPES, PROJECT_CONFIG } from './util/constants' +import { IBuildConfig } from './util/types' + +const appPath = process.cwd() + +export default function build (args, buildConfig: IBuildConfig) { + const { type, watch, platform } = buildConfig + const configDir = require(path.join(appPath, PROJECT_CONFIG))(_.merge) + const outputPath = path.join(appPath, configDir.outputRoot || CONFIG.OUTPUT_DIR) + if (!fs.existsSync(outputPath)) { + fs.ensureDirSync(outputPath) + } else { + if (type !== BUILD_TYPES.H5) { + Util.emptyDirectory(outputPath) + } + } + switch (type) { + case BUILD_TYPES.H5: + buildForH5({ watch }) + break + case BUILD_TYPES.WEAPP: + buildForWeapp({ watch }) + break + case BUILD_TYPES.SWAN: + buildForSwan({ watch }) + break + case BUILD_TYPES.ALIPAY: + buildForAlipay({ watch }) + break + case BUILD_TYPES.TT: + buildForTt({ watch }) + break + case BUILD_TYPES.RN: + buildForRN({ watch }) + break + case BUILD_TYPES.UI: + buildForUILibrary({ watch }) + break + case BUILD_TYPES.PLUGIN: + buildForPlugin({ + watch, + platform + }) + break + default: + console.log(chalk.red('输入类型错误,目前只支持 weapp/h5/rn/swan/alipay/tt 六端类型')) + } +} + +function buildForWeapp ({ watch }: IBuildConfig) { + require('./mini').build({ + watch, + adapter: BUILD_TYPES.WEAPP + }) +} + +function buildForSwan ({ watch }: IBuildConfig) { + require('./mini').build({ + watch, + adapter: BUILD_TYPES.SWAN + }) +} + +function buildForAlipay ({ watch }: IBuildConfig) { + require('./mini').build({ + watch, + adapter: BUILD_TYPES.ALIPAY + }) +} + +function buildForTt ({ watch }: IBuildConfig) { + require('./mini').build({ + watch, + adapter: BUILD_TYPES.TT + }) +} + +function buildForH5 (buildConfig: IBuildConfig) { + require('./h5').build(buildConfig) +} + +function buildForRN ({ watch }: IBuildConfig) { + require('./rn').build({ watch }) +} + +function buildForUILibrary ({ watch }: IBuildConfig) { + require('./ui').build({ watch }) +} + +function buildForPlugin ({ watch, platform }) { + const typeMap = { + [BUILD_TYPES.WEAPP]: '微信', + [BUILD_TYPES.ALIPAY]: '支付宝' + } + if (platform !== BUILD_TYPES.WEAPP && platform !== BUILD_TYPES.ALIPAY) { + console.log(chalk.red('目前插件编译仅支持 微信/支付宝 小程序!')) + return + } + console.log(chalk.green(`开始编译${typeMap[platform]}小程序插件`)) + require('./plugin').build({ watch, platform }) +} diff --git a/packages/taro-cli/src/config/babel.js b/packages/taro-cli/src/config/babel.ts similarity index 57% rename from packages/taro-cli/src/config/babel.js rename to packages/taro-cli/src/config/babel.ts index 3b2e56859fb0..aba848350e57 100644 --- a/packages/taro-cli/src/config/babel.js +++ b/packages/taro-cli/src/config/babel.ts @@ -1,4 +1,4 @@ -module.exports = { +const babelOptions: IBabelOptions = { sourceMap: true, presets: [ 'env' @@ -10,3 +10,11 @@ module.exports = { 'transform-object-rest-spread' ] } + +export default babelOptions + +export interface IBabelOptions { + sourceMap: boolean, + presets: string[], + plugins: any[] +} diff --git a/packages/taro-cli/src/config/babylon.js b/packages/taro-cli/src/config/babylon.ts similarity index 93% rename from packages/taro-cli/src/config/babylon.js rename to packages/taro-cli/src/config/babylon.ts index 015dd1180141..1c1e778de91d 100644 --- a/packages/taro-cli/src/config/babylon.js +++ b/packages/taro-cli/src/config/babylon.ts @@ -1,4 +1,4 @@ -module.exports = { +export default { sourceType: 'module', plugins: [ 'typescript', diff --git a/packages/taro-cli/src/config/browser_list.js b/packages/taro-cli/src/config/browser_list.ts similarity index 74% rename from packages/taro-cli/src/config/browser_list.js rename to packages/taro-cli/src/config/browser_list.ts index afdd1afc81e4..cf45da8e1957 100644 --- a/packages/taro-cli/src/config/browser_list.js +++ b/packages/taro-cli/src/config/browser_list.ts @@ -1,4 +1,4 @@ -module.exports = [ +export default [ 'last 3 versions', 'Android >= 4.1', 'ios >= 8' diff --git a/packages/taro-cli/src/config/index.js b/packages/taro-cli/src/config/index.ts similarity index 83% rename from packages/taro-cli/src/config/index.js rename to packages/taro-cli/src/config/index.ts index e341dd8e7666..677c1b768226 100644 --- a/packages/taro-cli/src/config/index.js +++ b/packages/taro-cli/src/config/index.ts @@ -1,4 +1,4 @@ -module.exports = { +export default { OUTPUT_DIR: 'dist', SOURCE_DIR: 'src', TEMP_DIR: '.temp', diff --git a/packages/taro-cli/src/config/uglify.js b/packages/taro-cli/src/config/uglify.js deleted file mode 100644 index 7acaac2b6a15..000000000000 --- a/packages/taro-cli/src/config/uglify.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - -} diff --git a/packages/taro-cli/src/config/uglify.ts b/packages/taro-cli/src/config/uglify.ts new file mode 100644 index 000000000000..43ea6b431bb8 --- /dev/null +++ b/packages/taro-cli/src/config/uglify.ts @@ -0,0 +1 @@ +export default { } diff --git a/packages/taro-cli/src/convertor/helper.ts b/packages/taro-cli/src/convertor/helper.ts new file mode 100644 index 000000000000..542d4dbc7820 --- /dev/null +++ b/packages/taro-cli/src/convertor/helper.ts @@ -0,0 +1,66 @@ +import path from 'path' +import fs from 'fs-extra' +import * as t from 'babel-types' + +import { + printLog, + promoteRelativePath, + resolveScriptPath +} from '../util' + +import { + processTypeEnum, + REG_SCRIPT, + REG_TYPESCRIPT +} from '../util/constants' + +export function analyzeImportUrl ( + sourceFilePath: string, + scriptFiles: Set, + source: t.StringLiteral, + value: string +) { + const valueExtname = path.extname(value) + if (path.isAbsolute(value)) { + printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 是绝对路径!`) + return + } + if (value.indexOf('.') === 0) { + if (REG_SCRIPT.test(valueExtname) || REG_TYPESCRIPT.test(valueExtname)) { + const vpath = path.resolve(sourceFilePath, '..', value) + let fPath = value + if (fs.existsSync(vpath)) { + fPath = vpath + } else { + printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) + } + scriptFiles.add(fPath) + } else { + let vpath = resolveScriptPath(path.resolve(sourceFilePath, '..', value)) + if (vpath) { + if (!fs.existsSync(vpath)) { + printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) + } else { + if (fs.lstatSync(vpath).isDirectory()) { + if (fs.existsSync(path.join(vpath, 'index.js'))) { + vpath = path.join(vpath, 'index.js') + } else { + printLog(processTypeEnum.ERROR, '引用目录', `文件 ${sourceFilePath} 中引用了目录 ${value}!`) + return + } + } + let relativePath = path.relative(sourceFilePath, vpath) + const relativePathExtname = path.extname(relativePath) + scriptFiles.add(vpath) + relativePath = promoteRelativePath(relativePath) + if (/\.wxs/.test(relativePathExtname)) { + relativePath += '.js' + } else { + relativePath = relativePath.replace(relativePathExtname, '.js') + } + source.value = relativePath + } + } + } + } +} diff --git a/packages/taro-cli/src/convertor.js b/packages/taro-cli/src/convertor/index.ts similarity index 74% rename from packages/taro-cli/src/convertor.js rename to packages/taro-cli/src/convertor/index.ts index ded7251c9dcf..5ae48db0c410 100644 --- a/packages/taro-cli/src/convertor.js +++ b/packages/taro-cli/src/convertor/index.ts @@ -1,39 +1,43 @@ -const fs = require('fs-extra') -const path = require('path') - -const chalk = require('chalk') -const prettier = require('prettier') -const traverse = require('babel-traverse').default -const t = require('babel-types') -const template = require('babel-template') -const taroize = require('@tarojs/taroize') -const wxTransformer = require('@tarojs/transformer-wx') -const postcss = require('postcss') -const unitTransform = require('postcss-taro-unit-transform') - -const { - BUILD_TYPES, - MINI_APP_FILES, +import * as fs from 'fs-extra' +import * as path from 'path' + +import { AppConfig, TabBar } from '@tarojs/taro' +import chalk from 'chalk' +import * as prettier from 'prettier' +import traverse, { NodePath } from 'babel-traverse' +import * as t from 'babel-types' +import * as taroize from '@tarojs/taroize' +import * as wxTransformer from '@tarojs/transformer-wx' +import * as postcss from 'postcss' +import * as unitTransform from 'postcss-taro-unit-transform' + +import { printLog, - pocessTypeEnum, promoteRelativePath, resolveScriptPath, - REG_SCRIPT, - REG_TYPESCRIPT, processStyleImports, getPkgVersion, pascalCase, - emptyDirectory, + emptyDirectory +} from '../util' +import { + BUILD_TYPES, + MINI_APP_FILES, + processTypeEnum, + REG_TYPESCRIPT, REG_URL, - REG_IMAGE -} = require('./util') - -const { generateMinimalEscapeCode } = require('./util/ast_convert') + REG_IMAGE, + IMINI_APP_FILE_TYPE +} from '../util/constants' +import { generateMinimalEscapeCode } from '../util/astConvert' +import Creator from '../creator' +import babylonConfig from '../config/babylon' +import { IPrettierConfig } from '../util/types' +import { analyzeImportUrl } from './helper' -const Creator = require('./creator') -const babylonConfig = require('./config/babylon') +const template = require('babel-template') -const prettierJSConfig = { +const prettierJSConfig: IPrettierConfig = { semi: false, singleQuote: true, parser: 'babel' @@ -41,66 +45,64 @@ const prettierJSConfig = { const OUTPUT_STYLE_EXTNAME = '.scss' -const WX_GLOBAL_FN = ['getApp', 'getCurrentPages', 'requirePlugin'] +const WX_GLOBAL_FN = new Set(['getApp', 'getCurrentPages', 'requirePlugin']) -function analyzeImportUrl (sourceFilePath, scriptFiles, source, value) { - const valueExtname = path.extname(value) - if (path.isAbsolute(value)) { - printLog(pocessTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 是绝对路径!`) - return - } - if (value.indexOf('.') === 0) { - if (REG_SCRIPT.test(valueExtname) || REG_TYPESCRIPT.test(valueExtname)) { - const vpath = path.resolve(sourceFilePath, '..', value) - let fPath = value - if (fs.existsSync(vpath)) { - fPath = vpath - } else { - printLog(pocessTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) - } - scriptFiles.add(fPath) - } else { - let vpath = resolveScriptPath(path.resolve(sourceFilePath, '..', value)) - if (vpath) { - if (!fs.existsSync(vpath)) { - printLog(pocessTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) - } else { - if (fs.lstatSync(vpath).isDirectory()) { - if (fs.existsSync(path.join(vpath, 'index.js'))) { - vpath = path.join(vpath, 'index.js') - } else { - printLog(pocessTypeEnum.ERROR, '引用目录', `文件 ${sourceFilePath} 中引用了目录 ${value}!`) - return - } - } - let relativePath = path.relative(sourceFilePath, vpath) - const relativePathExtname = path.extname(relativePath) - scriptFiles.add(vpath) - relativePath = promoteRelativePath(relativePath) - if (/\.wxs/.test(relativePathExtname)) { - relativePath += '.js' - } else { - relativePath = relativePath.replace(relativePathExtname, '.js') - } - source.value = relativePath - } - } - } - } +interface IComponent { + name: string, + path: string +} + +interface IImport { + ast: t.File, + name: string, + wxs?: boolean +} + +interface IParseAstOptions { + ast: t.File, + sourceFilePath: string, + outputFilePath: string, + importStylePath?: string | null, + depComponents?: Set, + imports?: IImport[], + isApp?: boolean } -class Convertor { +interface ITaroizeOptions { + json?: string, + script?: string, + wxml?: string, + path?: string +} + +export default class Convertor { + root: string + convertRoot: string + convertDir: string + importsDir: string + fileTypes: IMINI_APP_FILE_TYPE + pages: Set + components: Set + hadBeenCopyedFiles: Set + hadBeenBuiltComponents: Set + hadBeenBuiltImports: Set + entryJSPath: string + entryJSONPath: string + entryStylePath: string + entryJSON: AppConfig + entryStyle: string + constructor () { this.root = process.cwd() this.convertRoot = path.join(this.root, 'taroConvert') this.convertDir = path.join(this.convertRoot, 'src') this.importsDir = path.join(this.convertDir, 'imports') this.fileTypes = MINI_APP_FILES[BUILD_TYPES.WEAPP] - this.pages = new Set() - this.components = new Set() - this.hadBeenCopyedFiles = new Set() - this.hadBeenBuiltComponents = new Set() - this.hadBeenBuiltImports = new Set() + this.pages = new Set() + this.components = new Set() + this.hadBeenCopyedFiles = new Set() + this.hadBeenBuiltComponents = new Set() + this.hadBeenBuiltImports = new Set() this.init() } @@ -120,10 +122,18 @@ class Convertor { } } - parseAst ({ ast, sourceFilePath, outputFilePath, importStylePath, depComponents, imports = [], isApp = false }) { - const scriptFiles = new Set() + parseAst ({ + ast, + sourceFilePath, + outputFilePath, + importStylePath, + depComponents, + imports = [], + isApp = false + }: IParseAstOptions): { ast: t.File, scriptFiles: Set } { + const scriptFiles = new Set() const self = this - let componentClassName = null + let componentClassName: string let needInsertImportTaro = false traverse(ast, { Program: { @@ -167,9 +177,9 @@ class Convertor { }) if (isTaroComponent) { if (node.id === null) { - const parentNode = astPath.parentPath.node + const parentNode = astPath.parentPath.node as t.VariableDeclarator if (t.isVariableDeclarator(astPath.parentPath)) { - componentClassName = parentNode.id.name + componentClassName = (parentNode.id as t.Identifier).name } } else { componentClassName = node.id.name @@ -216,19 +226,19 @@ class Convertor { const callee = calleePath.node if (callee.type === 'Identifier') { if (callee.name === 'require') { - const args = node.arguments + const args = node.arguments as Array const value = args[0].value analyzeImportUrl(sourceFilePath, scriptFiles, args[0], value) - } else if (WX_GLOBAL_FN.includes(callee.name)) { + } else if (WX_GLOBAL_FN.has(callee.name)) { calleePath.replaceWith( - t.memberExpression(t.identifier('Taro'), callee) + t.memberExpression(t.identifier('Taro'), callee as t.Identifier) ) needInsertImportTaro = true } } else if (callee.type === 'MemberExpression') { - const object = callee.object + const object = callee.object as t.Identifier if (object.name === 'wx') { - calleePath.get('object').replaceWith(t.identifier('Taro')) + (calleePath.get('object') as NodePath).replaceWith(t.identifier('Taro')) needInsertImportTaro = true } } @@ -236,10 +246,11 @@ class Convertor { }) }, exit (astPath) { - const lastImport = astPath.get('body').filter(p => p.isImportDeclaration()).pop() - const hasTaroImport = astPath.get('body').some(p => p.isImportDeclaration() && p.node.source.value === '@tarojs/taro') + const bodyNode = astPath.get('body') as NodePath[] + const lastImport = bodyNode.filter(p => p.isImportDeclaration()).pop() + const hasTaroImport = bodyNode.some(p => p.isImportDeclaration() && p.node.source.value === '@tarojs/taro') if (needInsertImportTaro && !hasTaroImport) { - astPath.node.body.unshift( + (astPath.node as t.Program).body.unshift( t.importDeclaration( [t.importDefaultSpecifier(t.identifier('Taro'))], t.stringLiteral('@tarojs/taro') @@ -251,9 +262,9 @@ class Convertor { const value = astPath.node.value const extname = path.extname(value) if (extname && REG_IMAGE.test(extname) && !REG_URL.test(value)) { - let imageRelativePath = null - let sourceImagePath = null - let outputImagePath = null + let imageRelativePath: string + let sourceImagePath: string + let outputImagePath: string if (path.isAbsolute(value)) { sourceImagePath = path.join(self.root, value) } else { @@ -263,9 +274,9 @@ class Convertor { outputImagePath = self.getDistFilePath(sourceImagePath) if (fs.existsSync(sourceImagePath)) { self.copyFileToTaro(sourceImagePath, outputImagePath) - printLog(pocessTypeEnum.COPY, '图片', self.generateShowPath(outputImagePath)) + printLog(processTypeEnum.COPY, '图片', self.generateShowPath(outputImagePath)) } else { - printLog(pocessTypeEnum.ERROR, '图片不存在', self.generateShowPath(sourceImagePath)) + printLog(processTypeEnum.ERROR, '图片不存在', self.generateShowPath(sourceImagePath)) } if (astPath.parentPath.isVariableDeclarator()) { astPath.replaceWith(t.callExpression(t.identifier('require'), [t.stringLiteral(imageRelativePath)])) @@ -302,7 +313,7 @@ class Convertor { } if (isApp) { - astPath.node.body.push(template(`Taro.render(, document.getElementById('app'))`, babylonConfig)()) + (astPath.node as t.Program).body.push(template(`Taro.render(, document.getElementById('app'))`, babylonConfig)()) } } } @@ -321,11 +332,11 @@ class Convertor { this.entryStylePath = path.join(this.root, `app${this.fileTypes.STYLE}`) try { this.entryJSON = JSON.parse(String(fs.readFileSync(this.entryJSONPath))) - printLog(pocessTypeEnum.CONVERT, '入口文件', this.generateShowPath(this.entryJSPath)) - printLog(pocessTypeEnum.CONVERT, '入口配置', this.generateShowPath(this.entryJSONPath)) + printLog(processTypeEnum.CONVERT, '入口文件', this.generateShowPath(this.entryJSPath)) + printLog(processTypeEnum.CONVERT, '入口配置', this.generateShowPath(this.entryJSONPath)) if (fs.existsSync(this.entryStylePath)) { this.entryStyle = String(fs.readFileSync(this.entryStylePath)) - printLog(pocessTypeEnum.CONVERT, '入口样式', this.generateShowPath(this.entryStylePath)) + printLog(processTypeEnum.CONVERT, '入口样式', this.generateShowPath(this.entryStylePath)) } } catch (err) { this.entryJSON = {} @@ -360,7 +371,7 @@ class Convertor { }) } - generateScriptFiles (files) { + generateScriptFiles (files: Set) { if (!files) { return } @@ -389,19 +400,19 @@ class Convertor { }) const jsCode = generateMinimalEscapeCode(ast) this.writeFileToTaro(outputFilePath, prettier.format(jsCode, prettierJSConfig)) - printLog(pocessTypeEnum.COPY, 'JS 文件', this.generateShowPath(outputFilePath)) + printLog(processTypeEnum.COPY, 'JS 文件', this.generateShowPath(outputFilePath)) this.hadBeenCopyedFiles.add(file) this.generateScriptFiles(scriptFiles) }) } } - writeFileToTaro (dist, code) { + writeFileToTaro (dist: string, code: string) { fs.ensureDirSync(path.dirname(dist)) fs.writeFileSync(dist, code) } - copyFileToTaro (from, to, options) { + copyFileToTaro (from: string, to: string, options?: fs.CopyOptionsSync) { const filename = path.basename(from) if (fs.statSync(from).isFile() && !path.extname(to)) { fs.ensureDir(to) @@ -411,12 +422,12 @@ class Convertor { return fs.copySync(from, to, options) } - getDistFilePath (src, extname) { + getDistFilePath (src: string, extname?: string): string { if (!extname) return src.replace(this.root, this.convertDir) return src.replace(this.root, this.convertDir).replace(path.extname(src), extname) } - generateShowPath (filePath) { + generateShowPath (filePath: string): string { return filePath.replace(path.join(this.root, '/'), '').split(path.sep).join('/') } @@ -439,7 +450,7 @@ class Convertor { }) const jsCode = generateMinimalEscapeCode(ast) this.writeFileToTaro(entryDistJSPath, prettier.format(jsCode, prettierJSConfig)) - printLog(pocessTypeEnum.GENERATE, '入口文件', this.generateShowPath(entryDistJSPath)) + printLog(processTypeEnum.GENERATE, '入口文件', this.generateShowPath(entryDistJSPath)) if (this.entryStyle) { this.traverseStyle(this.entryStylePath, this.entryStyle) } @@ -452,7 +463,7 @@ class Convertor { } } - generateTabBarIcon (tabBar) { + generateTabBarIcon (tabBar: TabBar) { const { list = [] } = tabBar const icons = new Set() if (Array.isArray(list) && list.length) { @@ -466,7 +477,7 @@ class Convertor { .forEach(iconPath => { const iconDistPath = this.getDistFilePath(iconPath) this.copyFileToTaro(iconPath, iconDistPath) - printLog(pocessTypeEnum.COPY, 'TabBar 图标', this.generateShowPath(iconDistPath)) + printLog(processTypeEnum.COPY, 'TabBar 图标', this.generateShowPath(iconDistPath)) }) } } @@ -482,15 +493,15 @@ class Convertor { const pageTemplPath = pagePath + this.fileTypes.TEMPL try { - const param = {} const depComponents = new Set() if (!fs.existsSync(pageJSPath)) { throw new Error(`页面 ${page} 没有 JS 文件!`) } - printLog(pocessTypeEnum.CONVERT, '页面文件', this.generateShowPath(pageJSPath)) + const param: ITaroizeOptions = {} + printLog(processTypeEnum.CONVERT, '页面文件', this.generateShowPath(pageJSPath)) if (fs.existsSync(pageConfigPath)) { - printLog(pocessTypeEnum.CONVERT, '页面配置', this.generateShowPath(pageConfigPath)) + printLog(processTypeEnum.CONVERT, '页面配置', this.generateShowPath(pageConfigPath)) const pageConfigStr = String(fs.readFileSync(pageConfigPath)) const pageConfig = JSON.parse(pageConfigStr) const pageUsingComponnets = pageConfig.usingComponents @@ -512,12 +523,12 @@ class Convertor { } param.script = String(fs.readFileSync(pageJSPath)) if (fs.existsSync(pageTemplPath)) { - printLog(pocessTypeEnum.CONVERT, '页面模板', this.generateShowPath(pageTemplPath)) + printLog(processTypeEnum.CONVERT, '页面模板', this.generateShowPath(pageTemplPath)) param.wxml = String(fs.readFileSync(pageTemplPath)) } - let pageStyle = null + let pageStyle: string | null = null if (fs.existsSync(pageStylePath)) { - printLog(pocessTypeEnum.CONVERT, '页面样式', this.generateShowPath(pageStylePath)) + printLog(processTypeEnum.CONVERT, '页面样式', this.generateShowPath(pageStylePath)) pageStyle = String(fs.readFileSync(pageStylePath)) } param.path = path.dirname(pageJSPath) @@ -532,20 +543,20 @@ class Convertor { }) const jsCode = generateMinimalEscapeCode(ast) this.writeFileToTaro(pageDistJSPath, prettier.format(jsCode, prettierJSConfig)) - printLog(pocessTypeEnum.GENERATE, '页面文件', this.generateShowPath(pageDistJSPath)) + printLog(processTypeEnum.GENERATE, '页面文件', this.generateShowPath(pageDistJSPath)) if (pageStyle) { this.traverseStyle(pageStylePath, pageStyle) } this.generateScriptFiles(scriptFiles) this.traverseComponents(depComponents) } catch (err) { - printLog(pocessTypeEnum.ERROR, '页面转换', this.generateShowPath(pageJSPath)) + printLog(processTypeEnum.ERROR, '页面转换', this.generateShowPath(pageJSPath)) console.log(err) } }) } - traverseComponents (components) { + traverseComponents (components: Set) { if (!components || !components.size) { return } @@ -561,14 +572,14 @@ class Convertor { const componentTemplPath = component + this.fileTypes.TEMPL try { - const param = {} + const param: ITaroizeOptions = {} const depComponents = new Set() if (!fs.existsSync(componentJSPath)) { throw new Error(`组件 ${component} 没有 JS 文件!`) } - printLog(pocessTypeEnum.CONVERT, '组件文件', this.generateShowPath(componentJSPath)) + printLog(processTypeEnum.CONVERT, '组件文件', this.generateShowPath(componentJSPath)) if (fs.existsSync(componentConfigPath)) { - printLog(pocessTypeEnum.CONVERT, '组件配置', this.generateShowPath(componentConfigPath)) + printLog(processTypeEnum.CONVERT, '组件配置', this.generateShowPath(componentConfigPath)) const componentConfigStr = String(fs.readFileSync(componentConfigPath)) const componentConfig = JSON.parse(componentConfigStr) const componentUsingComponnets = componentConfig.usingComponents @@ -590,12 +601,12 @@ class Convertor { } param.script = String(fs.readFileSync(componentJSPath)) if (fs.existsSync(componentTemplPath)) { - printLog(pocessTypeEnum.CONVERT, '组件模板', this.generateShowPath(componentTemplPath)) + printLog(processTypeEnum.CONVERT, '组件模板', this.generateShowPath(componentTemplPath)) param.wxml = String(fs.readFileSync(componentTemplPath)) } - let componentStyle = null + let componentStyle: string | null = null if (fs.existsSync(componentStylePath)) { - printLog(pocessTypeEnum.CONVERT, '组件样式', this.generateShowPath(componentStylePath)) + printLog(processTypeEnum.CONVERT, '组件样式', this.generateShowPath(componentStylePath)) componentStyle = String(fs.readFileSync(componentStylePath)) } param.path = path.dirname(componentJSPath) @@ -610,20 +621,20 @@ class Convertor { }) const jsCode = generateMinimalEscapeCode(ast) this.writeFileToTaro(componentDistJSPath, prettier.format(jsCode, prettierJSConfig)) - printLog(pocessTypeEnum.GENERATE, '组件文件', this.generateShowPath(componentDistJSPath)) + printLog(processTypeEnum.GENERATE, '组件文件', this.generateShowPath(componentDistJSPath)) if (componentStyle) { this.traverseStyle(componentStylePath, componentStyle) } this.generateScriptFiles(scriptFiles) this.traverseComponents(depComponents) } catch (err) { - printLog(pocessTypeEnum.ERROR, '组件转换', this.generateShowPath(componentJSPath)) + printLog(processTypeEnum.ERROR, '组件转换', this.generateShowPath(componentJSPath)) console.log(err) } }) } - async styleUnitTransform (filePath, content) { + async styleUnitTransform (filePath: string, content: string) { const postcssResult = await postcss([ unitTransform() ]).process(content, { @@ -632,7 +643,7 @@ class Convertor { return postcssResult } - async traverseStyle (filePath, style) { + async traverseStyle (filePath: string, style: string) { const { imports, content } = processStyleImports(style, BUILD_TYPES.WEAPP, (str, stylePath) => { let relativePath = stylePath if (path.isAbsolute(relativePath)) { @@ -644,7 +655,7 @@ class Convertor { const styleDist = this.getDistFilePath(filePath, OUTPUT_STYLE_EXTNAME) const { css } = await this.styleUnitTransform(filePath, content) this.writeFileToTaro(styleDist, css) - printLog(pocessTypeEnum.GENERATE, '样式文件', this.generateShowPath(styleDist)) + printLog(processTypeEnum.GENERATE, '样式文件', this.generateShowPath(styleDist)) if (imports && imports.length) { imports.forEach(importItem => { const importPath = path.isAbsolute(importItem) @@ -698,15 +709,15 @@ class Convertor { spaces: 2, EOL: '\n' }) - printLog(pocessTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(configDir, 'index.js'))) - printLog(pocessTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(configDir, 'dev.js'))) - printLog(pocessTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(configDir, 'prod.js'))) - printLog(pocessTypeEnum.GENERATE, '文件', this.generateShowPath(pkgPath)) - printLog(pocessTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(this.convertRoot, 'project.config.json'))) - printLog(pocessTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(this.convertRoot, '.gitignore'))) - printLog(pocessTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(this.convertRoot, '.editorconfig'))) - printLog(pocessTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(this.convertRoot, '.eslintrc'))) - printLog(pocessTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(this.convertDir, 'index.html'))) + printLog(processTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(configDir, 'index.js'))) + printLog(processTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(configDir, 'dev.js'))) + printLog(processTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(configDir, 'prod.js'))) + printLog(processTypeEnum.GENERATE, '文件', this.generateShowPath(pkgPath)) + printLog(processTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(this.convertRoot, 'project.config.json'))) + printLog(processTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(this.convertRoot, '.gitignore'))) + printLog(processTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(this.convertRoot, '.editorconfig'))) + printLog(processTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(this.convertRoot, '.eslintrc'))) + printLog(processTypeEnum.GENERATE, '文件', this.generateShowPath(path.join(this.convertDir, 'index.html'))) }) } @@ -716,5 +727,3 @@ class Convertor { this.generateConfigFiles() } } - -module.exports = Convertor diff --git a/packages/taro-cli/src/creator.js b/packages/taro-cli/src/creator.js deleted file mode 100644 index 86e8b846b37e..000000000000 --- a/packages/taro-cli/src/creator.js +++ /dev/null @@ -1,86 +0,0 @@ -const path = require('path') -const fs = require('fs-extra') -const memFs = require('mem-fs') -const editor = require('mem-fs-editor') - -const { - getRootPath -} = require('./util') - -class Creator { - constructor () { - const store = memFs.create() - this.fs = editor.create(store) - this.sourceRoot(path.join(getRootPath())) - this.init() - } - - init () {} - - sourceRoot (rootPath) { - if (typeof rootPath === 'string') { - this._rootPath = path.resolve(rootPath) - } - if (!fs.existsSync(this._rootPath)) { - fs.ensureDirSync(this._rootPath) - } - return this._rootPath - } - - templatePath () { - let filepath = path.join.apply(path, arguments) - if (!path.isAbsolute(filepath)) { - filepath = path.join(this._rootPath, 'templates', filepath) - } - return filepath - } - - destinationRoot (rootPath) { - if (typeof rootPath === 'string') { - this._destinationRoot = path.resolve(rootPath) - if (!fs.existsSync(rootPath)) { - fs.ensureDirSync(rootPath) - } - process.chdir(rootPath) - } - return this._destinationRoot || process.cwd() - } - - destinationPath () { - let filepath = path.join.apply(path, arguments) - if (!path.isAbsolute(filepath)) { - filepath = path.join(this.destinationRoot(), filepath) - } - return filepath - } - - template (template, source, dest, data, options) { - if (typeof dest !== 'string') { - options = data - data = dest - dest = source - } - this.fs.copyTpl( - this.templatePath(template, source), - this.destinationPath(dest), - Object.assign({}, this, data), - options - ) - return this - } - - copy (template, type, source, dest) { - dest = dest || source - this.template(template, type, source, dest) - return this - } - - writeGitKeepFile (dirname) { - dirname = path.resolve(dirname) - fs.writeFileSync(path.join(dirname, '.gitkeep'), 'Place hold file', 'utf8') - } - - write () {} -} - -module.exports = Creator diff --git a/packages/taro-cli/src/creator.ts b/packages/taro-cli/src/creator.ts new file mode 100644 index 000000000000..39571bd965ef --- /dev/null +++ b/packages/taro-cli/src/creator.ts @@ -0,0 +1,118 @@ +import * as path from 'path' +import * as fs from 'fs-extra' +import * as memFs from 'mem-fs' +import * as editor from 'mem-fs-editor' + +import { + getRootPath +} from './util' + +interface IFile { + contents: Buffer | NodeJS.ReadableStream | null, + cwd: string, + base: string | null | undefined, + history: string[], + relative: string, + dirname: string, + basename: string, + stem: string, + extname: string, + symlink: string, + stat: fs.Stats | null +} + +interface IReadOptions { + raw?: boolean +} + +interface IAppendOptions { + trimEnd?: boolean, + separator?: string +} + +interface IMemFsEditor { + store: { + [key: string]: IFile + }, + read(filePath: string, options?: IReadOptions): string | Buffer, + readJSON(filePath: string, defaults?: JSON): JSON, + write(filePath: string, contents: string | Buffer): string, + writeJSON(filepath: string, contents: JSON, replacer?: ((key: string, value: any) => any) | undefined, space?: string | number | undefined): string, + append(filePath: string, contents: string | Buffer, options?: IAppendOptions): string | Buffer, + copyTpl(from: string, to: string, context: object, templateOptions: object), + commit(cb: () => void) +} + +export default class Creator { + fs: IMemFsEditor + protected _rootPath: string + private _destinationRoot: string + + constructor () { + const store = memFs.create() + this.fs = editor.create(store) + this.sourceRoot(path.join(getRootPath())) + this.init() + } + + init () {} + + sourceRoot (rootPath?: string) { + if (typeof rootPath === 'string') { + this._rootPath = path.resolve(rootPath) + } + if (!fs.existsSync(this._rootPath)) { + fs.ensureDirSync(this._rootPath) + } + return this._rootPath + } + + templatePath (...args: string[]): string { + let filepath = path.join.apply(path, args) + if (!path.isAbsolute(filepath)) { + filepath = path.join(this._rootPath, 'templates', filepath) + } + return filepath + } + + destinationRoot (rootPath?: string): string { + if (typeof rootPath === 'string') { + this._destinationRoot = path.resolve(rootPath) + if (!fs.existsSync(rootPath)) { + fs.ensureDirSync(rootPath) + } + process.chdir(rootPath) + } + return this._destinationRoot || process.cwd() + } + + destinationPath (...args: string[]): string { + let filepath = path.join.apply(path, args) + if (!path.isAbsolute(filepath)) { + filepath = path.join(this.destinationRoot(), filepath) + } + return filepath + } + + template (template: string, source: string, dest: string, data?: object, options?) { + if (typeof dest !== 'string') { + options = data + data = dest + dest = source + } + this.fs.copyTpl( + this.templatePath(template, source), + this.destinationPath(dest), + Object.assign({}, this, data), + options + ) + return this + } + + writeGitKeepFile (dirname: string) { + dirname = path.resolve(dirname) + fs.writeFileSync(path.join(dirname, '.gitkeep'), 'Place hold file', 'utf8') + } + + write () {} +} diff --git a/packages/taro-cli/src/doctor/configSchema.js b/packages/taro-cli/src/doctor/configSchema.ts similarity index 98% rename from packages/taro-cli/src/doctor/configSchema.js rename to packages/taro-cli/src/doctor/configSchema.ts index 51441b227109..25f7798e7335 100644 --- a/packages/taro-cli/src/doctor/configSchema.js +++ b/packages/taro-cli/src/doctor/configSchema.ts @@ -1,4 +1,4 @@ -const Joi = require('joi'); +import Joi from 'joi' const schema = Joi.object().keys({ 'projectName': Joi.string().required(), @@ -100,4 +100,4 @@ const schema = Joi.object().keys({ }) }) -module.exports = schema +export default schema diff --git a/packages/taro-cli/src/doctor/configValidator.js b/packages/taro-cli/src/doctor/configValidator.ts similarity index 70% rename from packages/taro-cli/src/doctor/configValidator.js rename to packages/taro-cli/src/doctor/configValidator.ts index 41e6a402b5ea..53e257be11b2 100644 --- a/packages/taro-cli/src/doctor/configValidator.js +++ b/packages/taro-cli/src/doctor/configValidator.ts @@ -1,10 +1,11 @@ -const configSchema = require('./configSchema') -const Joi = require('joi') -const _ = require('lodash/fp') -const path = require('path') -const joi2desc = require('./joi2desc') +import Joi from 'joi' +import _ from 'lodash/fp' +import path from 'path' +import joi2desc from './joi2desc' +import configSchema from './configSchema' + +import { PROJECT_CONFIG } from '../util/constants' -const { PROJECT_CONFIG } = require('../util') const PROJECT_CONF_PATH = path.join(process.cwd(), PROJECT_CONFIG) const PROJECT_CONF = require(PROJECT_CONF_PATH)(_.merge) @@ -27,7 +28,7 @@ function buildReport (errors) { } } -module.exports = async function () { +export default async function () { const { error } = Joi.validate(PROJECT_CONF, configSchema, { abortEarly: false }) return buildReport(error) } diff --git a/packages/taro-cli/src/doctor/eslintValidator.js b/packages/taro-cli/src/doctor/eslintValidator.ts similarity index 78% rename from packages/taro-cli/src/doctor/eslintValidator.js rename to packages/taro-cli/src/doctor/eslintValidator.ts index c2b03be66cea..498a9d6c6464 100644 --- a/packages/taro-cli/src/doctor/eslintValidator.js +++ b/packages/taro-cli/src/doctor/eslintValidator.ts @@ -1,14 +1,15 @@ -const path = require('path') -const _ = require('lodash') -const { CLIEngine } = require('eslint') +import path from 'path' +import _ from 'lodash' +import { CLIEngine } from 'eslint' + +import { PROJECT_CONFIG } from '../util/constants' -const { PROJECT_CONFIG } = require('../util') const projectConfPath = path.join(process.cwd(), PROJECT_CONFIG) const projectConf = require(projectConfPath)(_.merge) const ESLINT_CONFIG_PATH = path.join(__dirname, 'validatorEslintrc.js') -module.exports = function () { +export default function () { const eslintCli = new CLIEngine({ cwd: process.cwd(), useEslintrc: false, diff --git a/packages/taro-cli/src/doctor/index.js b/packages/taro-cli/src/doctor/index.ts similarity index 89% rename from packages/taro-cli/src/doctor/index.js rename to packages/taro-cli/src/doctor/index.ts index bab3d7b8109c..3dec316e1010 100644 --- a/packages/taro-cli/src/doctor/index.js +++ b/packages/taro-cli/src/doctor/index.ts @@ -1,4 +1,4 @@ -module.exports = { +export default { validators: [ require('./configValidator'), require('./packageValidator'), diff --git a/packages/taro-cli/src/doctor/interface.ts b/packages/taro-cli/src/doctor/interface.ts new file mode 100644 index 000000000000..efe551e4a556 --- /dev/null +++ b/packages/taro-cli/src/doctor/interface.ts @@ -0,0 +1,5 @@ +export interface IErrorLine { + desc: string, + valid: boolean, + solution?: string +} diff --git a/packages/taro-cli/src/doctor/joi2desc.js b/packages/taro-cli/src/doctor/joi2desc.ts similarity index 98% rename from packages/taro-cli/src/doctor/joi2desc.js rename to packages/taro-cli/src/doctor/joi2desc.ts index 7f43c13af799..4fe795fdb705 100644 --- a/packages/taro-cli/src/doctor/joi2desc.js +++ b/packages/taro-cli/src/doctor/joi2desc.ts @@ -108,6 +108,6 @@ const joi2desc = { 'symbol.map': '' } -module.exports = function (error) { +export default function (error) { return joi2desc[error.type] || error.message } diff --git a/packages/taro-cli/src/doctor/packageValidator.js b/packages/taro-cli/src/doctor/packageValidator.ts similarity index 81% rename from packages/taro-cli/src/doctor/packageValidator.js rename to packages/taro-cli/src/doctor/packageValidator.ts index 5a9c7f4f5934..8f4d605a3e86 100644 --- a/packages/taro-cli/src/doctor/packageValidator.js +++ b/packages/taro-cli/src/doctor/packageValidator.ts @@ -1,14 +1,16 @@ -const _ = require('lodash/fp') -const npmCheck = require('npm-check') -const cliPkg = require('../../package.json') +import _ from 'lodash/fp' +import npmCheck from 'npm-check' +import { getPkgVersion } from '../util' + +const pkgVersion = getPkgVersion() const isTaroPkg = pkg => /^@tarojs\//.test(pkg.moduleName) -const isCliVersionNotMatch = _.compose(_.negate(_.equals(cliPkg.version)), _.get('installed')) +const isCliVersionNotMatch = _.compose(_.negate(_.equals(pkgVersion)), _.get('installed')) const isPkgInstalled = _.get('isInstalled') const isPkgNotInstalled = _.negate(isPkgInstalled) async function checkPkgs () { - let errorLines = [] + let errorLines: any[] = [] const pkgs = await npmCheck() .then(_.invoke('all')) .then(_.get('packages')) @@ -28,7 +30,7 @@ async function checkPkgs () { function taroCliVersionNotMatch (pkgs) { const pkgsNotMatch = _.filter(pkg => isPkgInstalled(pkg) && isCliVersionNotMatch(pkg), pkgs) const lines = _.map(pkg => Object({ - desc: `${pkg.moduleName} (${pkg.installed}) 与当前使用的 @tarojs/cli (${cliPkg.version}) 版本不一致, 请更新为统一的版本`, + desc: `${pkg.moduleName} (${pkg.installed}) 与当前使用的 @tarojs/cli (${pkgVersion}) 版本不一致, 请更新为统一的版本`, valid: false }), pkgsNotMatch) return lines @@ -41,7 +43,7 @@ function taroShouldUpdate (pkgs) { return [{ // 需要正确设置 next 版本以使 npm-check 在判定最新版本时将 rc 版本也算在内 - desc: `检测到最新稳定版本 Taro ${taroPkg.latest} , 当前 cli 版本 ${cliPkg.version}`, + desc: `检测到最新稳定版本 Taro ${taroPkg.latest} , 当前 cli 版本 ${pkgVersion}`, valid: true, // 并非错误,仅提示即可 solution: `前往 https://github.com/NervJS/taro/releases 了解详情` }] @@ -56,4 +58,4 @@ function pkgsNotInstalled (pkgs) { return lines } -module.exports = checkPkgs +export default checkPkgs diff --git a/packages/taro-cli/src/doctor/recommandValidator.js b/packages/taro-cli/src/doctor/recommandValidator.ts similarity index 92% rename from packages/taro-cli/src/doctor/recommandValidator.js rename to packages/taro-cli/src/doctor/recommandValidator.ts index d3e036ad4cd5..0c5001409816 100644 --- a/packages/taro-cli/src/doctor/recommandValidator.js +++ b/packages/taro-cli/src/doctor/recommandValidator.ts @@ -1,7 +1,9 @@ -const _ = require('lodash/fp') -const fs = require('fs-extra') -const path = require('path') -const chalk = require('chalk') +import _ from 'lodash/fp' +import fs from 'fs-extra' +import path from 'path' +import chalk from 'chalk' + +import { IErrorLine } from './interface' const PROJECT_PACKAGE_PATH = path.join(process.cwd(), 'package.json') const PROJECT_FOLDER_FILES = fs.readdirSync('./') @@ -27,8 +29,8 @@ const hasReadme = inProjectFolder(README) const hasGitignore = inProjectFolder(GITIGNORE) const hasEditorconfig = inProjectFolder(EDITORCONFIG) -module.exports = async function () { - const errorLines = [] +export default async function () { + const errorLines: IErrorLine[] = [] if (!hasRecommandTestFrameworks) { errorLines.push({ diff --git a/packages/taro-cli/src/doctor/validatorEslintrc.js b/packages/taro-cli/src/doctor/validatorEslintrc.ts similarity index 92% rename from packages/taro-cli/src/doctor/validatorEslintrc.js rename to packages/taro-cli/src/doctor/validatorEslintrc.ts index 521a005d3929..4e168dbb2596 100644 --- a/packages/taro-cli/src/doctor/validatorEslintrc.js +++ b/packages/taro-cli/src/doctor/validatorEslintrc.ts @@ -1,4 +1,4 @@ -module.exports = { +export default { 'extends': ['taro'], 'rules': { 'no-unused-vars': ['error', { 'varsIgnorePattern': 'Taro' }], diff --git a/packages/taro-cli/src/extra/util_wxs b/packages/taro-cli/src/extra/util_wxs deleted file mode 100644 index e6e011c2e14a..000000000000 --- a/packages/taro-cli/src/extra/util_wxs +++ /dev/null @@ -1,11 +0,0 @@ -var assign = function (s, d) { - if (typeof s !== 'object') { - return d - } - s = s || {} - d = d || {} - return JSON.parse((JSON.stringify(s) + JSON.stringify(d)).replace('}{', ',')) -} -module.exports = { - assign: assign -}; diff --git a/packages/taro-cli/src/h5.js b/packages/taro-cli/src/h5.ts similarity index 90% rename from packages/taro-cli/src/h5.js rename to packages/taro-cli/src/h5.ts index 150debe73376..4c1a4f51e638 100644 --- a/packages/taro-cli/src/h5.js +++ b/packages/taro-cli/src/h5.ts @@ -1,28 +1,42 @@ -const fs = require('fs-extra') -const path = require('path') -const chokidar = require('chokidar') -const wxTransformer = require('@tarojs/transformer-wx') -const klaw = require('klaw') -const traverse = require('babel-traverse').default -const t = require('babel-types') -const babel = require('babel-core') -const generate = require('better-babel-generator').default -const _ = require('lodash') -const rimraf = require('rimraf') -const { promisify } = require('util') -const minimatch = require('minimatch') - -const Util = require('./util') -const npmProcess = require('./util/npm') -const CONFIG = require('./config') -const { source: toAst, obj: objToAst, toVariable: toVar } = require('./util/ast_convert') +import * as fs from 'fs-extra' +import * as path from 'path' + +import * as chokidar from 'chokidar' +import * as wxTransformer from '@tarojs/transformer-wx' +import { PageConfig } from '@tarojs/taro' +import * as klaw from 'klaw' +import traverse from 'babel-traverse' +import * as t from 'babel-types' +import * as babel from 'babel-core' +import generate from 'better-babel-generator' +import * as _ from 'lodash' +import * as rimraf from 'rimraf' +import { promisify } from 'util' +import minimatch from 'minimatch' + +import * as Util from './util' +import * as npmProcess from './util/npm' +import CONFIG from './config' +import { + convertSourceStringToAstExpression as toAst, + convertObjectToAstExpression as objToAst, + convertAstExpressionToVariable as toVar +} from './util/astConvert' +import { + PROJECT_CONFIG, + REG_TYPESCRIPT, + REG_SCRIPTS, + processTypeEnum, + BUILD_TYPES +} from './util/constants' +import { ICopyOptions } from './mini/interface' const addLeadingSlash = path => path.charAt(0) === '/' ? path : '/' + path const removeLeadingSlash = path => path.replace(/^\.?\//, '') const stripTrailingSlash = path => path.charAt(path.length - 1) === '/' ? path.slice(0, -1) : path const appPath = process.cwd() -const projectConfig = require(path.join(appPath, Util.PROJECT_CONFIG))(_.merge) +const projectConfig = require(path.join(appPath, PROJECT_CONFIG))(_.merge) const h5Config = projectConfig.h5 || {} const routerConfig = h5Config.router || {} const routerMode = routerConfig.mode === 'browser' ? 'browser' : 'hash' @@ -36,7 +50,7 @@ const tempDir = CONFIG.TEMP_DIR const tempPath = path.join(appPath, tempDir) const entryFilePath = Util.resolveScriptPath(path.join(sourcePath, CONFIG.ENTRY)) const entryFileName = path.basename(entryFilePath) -let pxTransformConfig = { designWidth: projectConfig.designWidth || 750 } +const pxTransformConfig = { designWidth: projectConfig.designWidth || 750 } const pathAlias = projectConfig.alias || {} const PACKAGES = { @@ -87,8 +101,7 @@ if (projectConfig.hasOwnProperty(DEVICE_RATIO)) { pxTransformConfig[DEVICE_RATIO] = projectConfig.deviceRatio } -let pages = [] -// let appConfig = {} +let pages: string[] = [] const FILE_TYPE = { ENTRY: 'ENTRY', @@ -125,6 +138,7 @@ function classifyFiles (filename) { path.relative(appPath, page) ) if (path.relative(relPage, relSrcPath) === '') return true + return false }) if (isPage) { @@ -139,7 +153,7 @@ function processEntry (code, filePath) { code, sourcePath: filePath, isNormal: true, - isTyped: Util.REG_TYPESCRIPT.test(filePath), + isTyped: REG_TYPESCRIPT.test(filePath), adapter: 'h5' }).ast let taroImportDefaultName @@ -345,7 +359,7 @@ function processEntry (code, filePath) { if (!hasConstructor) { astPath.pushContainer('body', t.classMethod( 'method', t.identifier('constructor'), [t.identifier('props'), t.identifier('context')], - t.blockStatement([toAst('super(props, context)'), additionalConstructorNode]), false, false)) + t.blockStatement([toAst('super(props, context)'), additionalConstructorNode] as any), false, false)) } if (tabBar) { if (!hasComponentWillMount) { @@ -386,7 +400,7 @@ function processEntry (code, filePath) { }) root = rootNode ? rootNode.value.value : '' } - value.elements.forEach(v => { + (value.elements as t.StringLiteral[]).forEach(v => { const pagePath = `${root}/${v.value}`.replace(/\/{2,}/g, '/') pages.push(removeLeadingSlash(pagePath)) v.value = addLeadingSlash(v.value) @@ -394,7 +408,10 @@ function processEntry (code, filePath) { } else if (keyName === 'tabBar' && t.isObjectExpression(value)) { // tabBar相关处理 tabBar = value - value.properties.forEach(node => { + value.properties.forEach((node: any) => { + if (node.type === 'SpreadProperty') { + return + } switch (node.key.name) { case 'position': tabbarPos = node.value.value @@ -420,15 +437,15 @@ function processEntry (code, filePath) { }) } }) - value.properties.push(t.ObjectProperty( + value.properties.push(t.objectProperty( t.identifier('mode'), t.stringLiteral(routerMode) )) - value.properties.push(t.ObjectProperty( + value.properties.push(t.objectProperty( t.identifier('basename'), t.stringLiteral(routerBasename) )) - value.properties.push(t.ObjectProperty( + value.properties.push(t.objectProperty( t.identifier('customRoutes'), t.objectExpression(objToAst(customRoutes)) )) @@ -441,7 +458,7 @@ function processEntry (code, filePath) { ClassDeclaration: ClassDeclarationOrExpression, ClassProperty: { enter (astPath) { - const node = astPath.node + const node = astPath.node as t.ClassProperty const key = node.key const keyName = toVar(key) @@ -455,7 +472,7 @@ function processEntry (code, filePath) { }, ImportDeclaration: { enter (astPath) { - const node = astPath.node + const node = astPath.node as any const source = node.source const specifiers = node.specifiers let value = source.value @@ -467,7 +484,7 @@ function processEntry (code, filePath) { const pathArr = value.split('/') if (pathArr.indexOf('pages') >= 0) { astPath.remove() - } else if (Util.REG_SCRIPTS.test(value) || path.extname(value) === '') { + } else if (REG_SCRIPTS.test(value) || path.extname(value) === '') { const absolutePath = path.resolve(filePath, '..', value) const dirname = path.dirname(absolutePath) const extname = path.extname(absolutePath) @@ -508,7 +525,7 @@ function processEntry (code, filePath) { source.value = PACKAGES['@tarojs/mobx-h5'] } else if (value === PACKAGES['nervjs']) { hasNerv = true - let defaultSpecifier = specifiers.find(item => t.isImportDefaultSpecifier(item)) + const defaultSpecifier = specifiers.find(item => t.isImportDefaultSpecifier(item)) if (!defaultSpecifier) { specifiers.unshift( t.importDefaultSpecifier(t.identifier(nervJsImportDefaultName)) @@ -519,14 +536,16 @@ function processEntry (code, filePath) { }, CallExpression: { enter (astPath) { - const node = astPath.node - const callee = node.callee + const node = astPath.node as t.CallExpression + const callee = node.callee as t.Identifier const calleeName = callee.name const parentPath = astPath.parentPath if (t.isMemberExpression(callee)) { - if (callee.object.name === taroImportDefaultName && callee.property.name === 'render') { - callee.object.name = nervJsImportDefaultName + const object = callee.object as t.Identifier + const property = callee.property as t.Identifier + if (object.name === taroImportDefaultName && property.name === 'render') { + object.name = nervJsImportDefaultName renderCallCode = generate(astPath.node).code astPath.remove() } @@ -543,7 +562,7 @@ function processEntry (code, filePath) { }, ClassMethod: { exit (astPath) { - const node = astPath.node + const node = astPath.node as t.ClassMethod const key = node.key const keyName = toVar(key) if (keyName === 'constructor') { @@ -568,17 +587,18 @@ function processEntry (code, filePath) { }, JSXOpeningElement: { enter (astPath) { - if (astPath.node.name.name === 'Provider') { - for (let v of astPath.node.attributes) { + const node = astPath.node as t.JSXOpeningElement + if ((node.name as any).name === 'Provider') { + for (const v of node.attributes) { if (v.name.name !== 'store') continue - storeName = v.value.expression.name + storeName = (v.value as any).expression.name break } } } }, Program: { - exit (astPath) { + exit (astPath: any) { const importRouterNode = toAst(`import { Router, createHistory, mountApis } from '${PACKAGES['@tarojs/router']}'`) const importComponentNode = toAst(`import { View, ${tabBarComponentName}, ${tabBarContainerComponentName}, ${tabBarPanelComponentName}} from '${PACKAGES['@tarojs/components']}'`) const lastImportIndex = _.findLastIndex(astPath.node.body, t.isImportDeclaration) @@ -635,24 +655,24 @@ function processEntry (code, filePath) { function processOthers (code, filePath, fileType) { const componentnameMap = new Map() const taroapiMap = new Map() + const isPage = fileType === FILE_TYPE.PAGE let ast = wxTransformer({ code, sourcePath: filePath, isNormal: true, - isTyped: Util.REG_TYPESCRIPT.test(filePath), + isTyped: REG_TYPESCRIPT.test(filePath), adapter: 'h5' }).ast let taroImportDefaultName let hasJSX = false let hasNerv = false - let isPage = fileType === FILE_TYPE.PAGE let hasComponentDidMount = false let hasComponentDidShow = false let hasComponentDidHide = false let hasOnPageScroll = false let hasOnReachBottom = false let hasOnPullDownRefresh = false - let pageConfig = {} + let pageConfig: PageConfig = {} ast = babel.transformFromAst(ast, '', { plugins: [ @@ -853,7 +873,7 @@ function processOthers (code, filePath, fileType) { ClassExpression: ClassDeclarationOrExpression, ClassDeclaration: ClassDeclarationOrExpression, ClassProperty: isPage ? { - enter (astPath) { + enter (astPath: any) { const node = astPath.node const key = toVar(node.key) if (key === 'config') { @@ -863,7 +883,7 @@ function processOthers (code, filePath, fileType) { } : {}, ClassMethod: isPage ? { exit (astPath) { - const node = astPath.node + const node = astPath.node as t.ClassMethod const key = node.key const keyName = toVar(key) if (keyName === 'componentDidMount') { @@ -883,7 +903,7 @@ function processOthers (code, filePath, fileType) { } : {}, ImportDeclaration: { enter (astPath) { - const node = astPath.node + const node = astPath.node as t.ImportDeclaration const source = node.source let value = source.value const specifiers = node.specifiers @@ -891,7 +911,7 @@ function processOthers (code, filePath, fileType) { source.value = value = Util.replaceAliasPath(filePath, value, pathAlias) } if (!Util.isNpmPkg(value)) { - if (Util.REG_SCRIPTS.test(value) || path.extname(value) === '') { + if (REG_SCRIPTS.test(value) || path.extname(value) === '') { const absolutePath = path.resolve(filePath, '..', value) const dirname = path.dirname(absolutePath) const extname = path.extname(absolutePath) @@ -913,13 +933,13 @@ function processOthers (code, filePath, fileType) { } else if (value === PACKAGES['@tarojs/mobx']) { source.value = PACKAGES['@tarojs/mobx-h5'] } else if (value === PACKAGES['@tarojs/components']) { - node.specifiers.forEach(specifier => { + node.specifiers.forEach((specifier: any) => { if (t.isImportDefaultSpecifier(specifier)) return componentnameMap.set(toVar(specifier.local), toVar(specifier.imported)) }) } else if (value === PACKAGES['nervjs']) { hasNerv = true - let defaultSpecifier = specifiers.find(item => t.isImportDefaultSpecifier(item)) + const defaultSpecifier = specifiers.find(item => t.isImportDefaultSpecifier(item)) if (!defaultSpecifier) { specifiers.unshift( t.importDefaultSpecifier(t.identifier(nervJsImportDefaultName)) @@ -929,7 +949,7 @@ function processOthers (code, filePath, fileType) { } }, JSXOpeningElement: { - exit (astPath) { + exit (astPath: any) { hasJSX = true const node = astPath.node const componentName = componentnameMap.get(toVar(node.name)) @@ -937,7 +957,7 @@ function processOthers (code, filePath, fileType) { const componentRef = getComponentRef(node) if (!componentId) return - const refFunc = createRefFunc(componentId) + const refFunc = createRefFunc(componentId) as any if (componentRef) { const expression = componentRef.value.expression @@ -956,7 +976,7 @@ function processOthers (code, filePath, fileType) { } }, CallExpression: { - exit (astPath) { + exit (astPath: any) { const node = astPath.node const callee = node.callee let needToAppendThis = false @@ -978,14 +998,14 @@ function processOthers (code, filePath, fileType) { } if (needToAppendThis) { const thisOrder = APIS_NEED_TO_APPEND_THIS.get(funcName) - if (!node.arguments[thisOrder]) { + if (thisOrder && !node.arguments[thisOrder]) { node.arguments[thisOrder] = t.thisExpression() } } } }, Program: { - exit (astPath) { + exit (astPath: any) { if (isPage) { astPath.traverse(programExitVisitor) } @@ -1061,12 +1081,12 @@ function getDist (filename, isScriptFile) { }) } -function processFiles (filePath) { +export function processFiles (filePath) { const file = fs.readFileSync(filePath) const dirname = path.dirname(filePath) const extname = path.extname(filePath) const distDirname = dirname.replace(sourcePath, tempDir) - const isScriptFile = Util.REG_SCRIPTS.test(extname) + const isScriptFile = REG_SCRIPTS.test(extname) const distPath = getDist(filePath, isScriptFile) try { @@ -1103,32 +1123,32 @@ function watchFiles () { watcher .on('add', filePath => { const relativePath = path.relative(appPath, filePath) - Util.printLog(Util.pocessTypeEnum.CREATE, '添加文件', relativePath) + Util.printLog(processTypeEnum.CREATE, '添加文件', relativePath) processFiles(filePath) }) .on('change', filePath => { const relativePath = path.relative(appPath, filePath) - Util.printLog(Util.pocessTypeEnum.MODIFY, '文件变动', relativePath) + Util.printLog(processTypeEnum.MODIFY, '文件变动', relativePath) processFiles(filePath) }) .on('unlink', filePath => { const relativePath = path.relative(appPath, filePath) const extname = path.extname(relativePath) - const isScriptFile = Util.REG_SCRIPTS.test(extname) + const isScriptFile = REG_SCRIPTS.test(extname) const dist = getDist(filePath, isScriptFile) - Util.printLog(Util.pocessTypeEnum.UNLINK, '删除文件', relativePath) + Util.printLog(processTypeEnum.UNLINK, '删除文件', relativePath) fs.unlinkSync(dist) }) } -function buildTemp () { +export function buildTemp () { fs.ensureDirSync(tempPath) return new Promise((resolve, reject) => { klaw(sourcePath) .on('data', file => { const relativePath = path.relative(appPath, file.path) if (!file.stats.isDirectory()) { - Util.printLog(Util.pocessTypeEnum.CREATE, '发现文件', relativePath) + Util.printLog(processTypeEnum.CREATE, '发现文件', relativePath) processFiles(file.path) } }) @@ -1144,7 +1164,7 @@ async function buildDist (buildConfig) { const sourceRoot = projectConfig.sourceRoot || CONFIG.SOURCE_DIR h5Config.env = projectConfig.env Object.assign(h5Config.env, { - TARO_ENV: JSON.stringify(Util.BUILD_TYPES.H5) + TARO_ENV: JSON.stringify(BUILD_TYPES.H5) }) h5Config.defineConstants = projectConfig.defineConstants h5Config.plugins = projectConfig.plugins @@ -1164,7 +1184,7 @@ async function buildDist (buildConfig) { webpackRunner(h5Config) } -const pRimraf = promisify(rimraf) +const pRimraf = promisify(rimraf) as any async function clean () { try { @@ -1197,7 +1217,7 @@ function copyFiles () { const to = path.join(projectDir, pattern.to) let ignore = pattern.ignore || globalIgnore if (fs.existsSync(from)) { - const copyOptions = {} + const copyOptions: ICopyOptions = {} if (ignore) { ignore = Array.isArray(ignore) ? ignore : [ignore] copyOptions.filter = src => { @@ -1212,26 +1232,20 @@ function copyFiles () { } copyFileSync(from, to, copyOptions) } else { - Util.printLog(Util.pocessTypeEnum.ERROR, '拷贝失败', `${pattern.from} 文件不存在!`) + Util.printLog(processTypeEnum.ERROR, '拷贝失败', `${pattern.from} 文件不存在!`) } } }) } } -async function build (buildConfig) { - process.env.TARO_ENV = Util.BUILD_TYPES.H5 +export async function build (buildConfig) { + process.env.TARO_ENV = BUILD_TYPES.H5 await clean() copyFiles() - await buildTemp(buildConfig) + await buildTemp() await buildDist(buildConfig) if (buildConfig.watch) { watchFiles() } } - -module.exports = { - build, - buildTemp, - processFiles -} diff --git a/packages/taro-cli/src/jdreact/convert_to_jdreact.js b/packages/taro-cli/src/jdreact/convert_to_jdreact.ts similarity index 77% rename from packages/taro-cli/src/jdreact/convert_to_jdreact.js rename to packages/taro-cli/src/jdreact/convert_to_jdreact.ts index 3e5ce3d34214..339c612bf62f 100644 --- a/packages/taro-cli/src/jdreact/convert_to_jdreact.js +++ b/packages/taro-cli/src/jdreact/convert_to_jdreact.ts @@ -1,8 +1,11 @@ -const fs = require('fs-extra') -const klaw = require('klaw') -const path = require('path') -const Util = require('../util') -const _ = require('lodash') +import * as fs from 'fs-extra' +import * as path from 'path' +import * as klaw from 'klaw' +import * as _ from 'lodash' + +import * as Util from '../util' + +import { processTypeEnum } from '../util/constants' const JDREACT_DIR = '.jdreact' const NATIVE_BUNDLES_DIR = 'bundle' @@ -12,7 +15,7 @@ const jdreactPath = path.join(appPath, JDREACT_DIR) const pkgName = _.camelCase(require(path.join(process.cwd(), 'package.json')).name) const moduleName = 'JDReact' + _.upperFirst(pkgName) -async function processFile ({filePath, tempPath, entryBaseName}) { +async function processFile ({ filePath, tempPath, entryBaseName }) { const indexJsStr = ` import {AppRegistry} from 'react-native'; import App from '../${entryBaseName}'; @@ -35,7 +38,7 @@ async function processFile ({filePath, tempPath, entryBaseName}) { const indexDistFilePath = path.join(indexDistDirPath, `${moduleName}.js`) fs.ensureDirSync(indexDistDirPath) fs.writeFileSync(indexDistFilePath, indexJsStr) - Util.printLog(Util.pocessTypeEnum.GENERATE, `${moduleName}.js`, indexDistFilePath) + Util.printLog(processTypeEnum.GENERATE, `${moduleName}.js`, indexDistFilePath) return } @@ -43,21 +46,21 @@ async function processFile ({filePath, tempPath, entryBaseName}) { if (filePath === tempPkgPath) { const destPkgPath = path.join(jdreactPath, 'package.json') const templatePkgPath = path.join(jdreactTmpDirname, 'pkg') - let tempPkgObject = fs.readJsonSync(tempPkgPath) - let templatePkgObject = fs.readJsonSync(templatePkgPath) + const tempPkgObject = fs.readJsonSync(tempPkgPath) + const templatePkgObject = fs.readJsonSync(templatePkgPath) templatePkgObject.name = `jdreact-jsbundle-${moduleName}` templatePkgObject.dependencies = Object.assign({}, tempPkgObject.dependencies, templatePkgObject.dependencies) fs.writeJsonSync(destPkgPath, templatePkgObject, {spaces: 2}) - Util.printLog(Util.pocessTypeEnum.GENERATE, 'package.json', destPkgPath) + Util.printLog(processTypeEnum.GENERATE, 'package.json', destPkgPath) return } fs.ensureDirSync(destDirname) fs.copySync(filePath, destFilePath) - Util.printLog(Util.pocessTypeEnum.COPY, _.camelCase(path.extname(filePath)).toUpperCase(), filePath) + Util.printLog(processTypeEnum.COPY, _.camelCase(path.extname(filePath)).toUpperCase(), filePath) } -function convertToJDReact ({tempPath, entryBaseName}) { +export function convertToJDReact ({tempPath, entryBaseName}) { klaw(tempPath) .on('data', file => { const nativeBundlePath = path.join(tempPath, NATIVE_BUNDLES_DIR) @@ -77,8 +80,6 @@ function convertToJDReact ({tempPath, entryBaseName}) { // not overwrite fs.copySync(path.join(templateSrcDirname, 'JDReact.version'), path.join(indexDistDirPath, `${moduleName}.version`), {overwrite: false}) fs.copySync(path.join(templateSrcDirname, 'JDReact.web.js'), path.join(indexDistDirPath, `${moduleName}.web.js`), {overwrite: false}) - Util.printLog(Util.pocessTypeEnum.COPY, 'templates', templateSrcDirname) + Util.printLog(processTypeEnum.COPY, 'templates', templateSrcDirname) }) } - -module.exports = {convertToJDReact} diff --git a/packages/taro-cli/src/mini/astProcess.ts b/packages/taro-cli/src/mini/astProcess.ts new file mode 100644 index 000000000000..8c0ed1815224 --- /dev/null +++ b/packages/taro-cli/src/mini/astProcess.ts @@ -0,0 +1,882 @@ +import * as fs from 'fs-extra' +import * as path from 'path' + +import * as babel from 'babel-core' +import * as t from 'babel-types' +import generate from 'babel-generator' +import traverse from 'babel-traverse' +import _ from 'lodash' +import { Config as IConfig } from '@tarojs/taro' + +const template = require('babel-template') + +import { + CONFIG_MAP, + REG_SCRIPT, + REG_TYPESCRIPT, + REG_JSON, + REG_FONT, + REG_IMAGE, + REG_MEDIA, + REG_STYLE, + CSS_EXT, + processTypeEnum, + BUILD_TYPES +} from '../util/constants' +import { + resolveScriptPath, + printLog, + promoteRelativePath, + isNpmPkg, + isAliasPath, + replaceAliasPath +} from '../util' +import { convertObjectToAstExpression, convertArrayToAstExpression } from '../util/astConvert' +import babylonConfig from '../config/babylon' + +import { + NODE_MODULES_REG, + PARSE_AST_TYPE, + taroJsComponents, + taroJsRedux, + taroJsFramework, + DEVICE_RATIO_NAME +} from './constants' +import { IComponentObj } from './interface' +import { getExactedNpmFilePath, getNotExistNpmList } from './npmExact' +import { + getBuildData, + isFileToBePage +} from './helper' +import { processStyleUseCssModule } from './compileStyle' + +function traverseObjectNode (node) { + const { buildAdapter } = getBuildData() + if (node.type === 'ClassProperty' || node.type === 'ObjectProperty') { + const properties = node.value.properties + const obj = {} + properties.forEach(p => { + let key = t.isIdentifier(p.key) ? p.key.name : p.key.value + if (CONFIG_MAP[buildAdapter][key]) { + key = CONFIG_MAP[buildAdapter][key] + } + obj[key] = traverseObjectNode(p.value) + }) + return obj + } + if (node.type === 'ObjectExpression') { + const properties = node.properties + const obj= {} + properties.forEach(p => { + let key = t.isIdentifier(p.key) ? p.key.name : p.key.value + if (CONFIG_MAP[buildAdapter][key]) { + key = CONFIG_MAP[buildAdapter][key] + } + obj[key] = traverseObjectNode(p.value) + }) + return obj + } + if (node.type === 'ArrayExpression') { + return node.elements.map(item => traverseObjectNode(item)) + } + if (node.type === 'NullLiteral') { + return null + } + return node.value +} + +function createCssModuleMap (styleFilePath, tokens) { + const { + sourceDir, + outputDir + } = getBuildData() + const cssModuleMapFilename = path.basename(styleFilePath) + '.map.js' + const cssModuleMapFile = path.join(path.dirname(styleFilePath), cssModuleMapFilename).replace(sourceDir, outputDir) + printLog(processTypeEnum.GENERATE, 'CSS Modules map', cssModuleMapFile) + fs.ensureDirSync(path.dirname(cssModuleMapFile)) + fs.writeFileSync(cssModuleMapFile, `module.exports = ${JSON.stringify(tokens, null, 2)};\n`) + return cssModuleMapFile +} + +interface IAnalyzeImportUrlOptions { + astPath: any, + value: string, + sourceFilePath: string, + filePath: string, + styleFiles: string[], + scriptFiles: string[], + jsonFiles: string[], + mediaFiles: string[] +} + +function analyzeImportUrl ({ + astPath, + value, + sourceFilePath, + filePath, + styleFiles, + scriptFiles, + jsonFiles, + mediaFiles +}: IAnalyzeImportUrlOptions): void { + const valueExtname = path.extname(value) + const node = astPath.node + const { + nodeModulesPath, + npmOutputDir, + sourceDir, + outputDir, + npmConfig + } = getBuildData() + if (value.indexOf('.') === 0) { + let importPath = path.resolve(path.dirname(sourceFilePath), value) + importPath = resolveScriptPath(importPath) + if (isFileToBePage(importPath)) { + astPath.remove() + } else { + if (REG_SCRIPT.test(valueExtname) || REG_TYPESCRIPT.test(valueExtname)) { + const vpath = path.resolve(sourceFilePath, '..', value) + let fPath = value + if (fs.existsSync(vpath) && vpath !== sourceFilePath) { + fPath = vpath + } + if (scriptFiles.indexOf(fPath) < 0) { + scriptFiles.push(fPath) + } + } else if (REG_JSON.test(valueExtname)) { + const vpath = path.resolve(sourceFilePath, '..', value) + if (jsonFiles.indexOf(vpath) < 0) { + jsonFiles.push(vpath) + } + if (fs.existsSync(vpath)) { + const obj = JSON.parse(fs.readFileSync(vpath).toString()) + const specifiers = node.specifiers + let defaultSpecifier = null + specifiers.forEach(item => { + if (item.type === 'ImportDefaultSpecifier') { + defaultSpecifier = item.local.name + } + }) + if (defaultSpecifier) { + let objArr: t.NullLiteral | t.Expression = t.nullLiteral() + if (Array.isArray(obj)) { + objArr = t.arrayExpression(convertArrayToAstExpression(obj)) + } else { + objArr = t.objectExpression(convertObjectToAstExpression(obj)) + } + astPath.replaceWith(t.variableDeclaration('const', [t.variableDeclarator(t.identifier(defaultSpecifier), objArr)])) + } + } + } else if (REG_FONT.test(valueExtname) || REG_IMAGE.test(valueExtname) || REG_MEDIA.test(valueExtname)) { + const vpath = path.resolve(sourceFilePath, '..', value) + if (!fs.existsSync(vpath)) { + printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) + return + } + if (mediaFiles.indexOf(vpath) < 0) { + mediaFiles.push(vpath) + } + const specifiers = node.specifiers + let defaultSpecifier = null + specifiers.forEach(item => { + if (item.type === 'ImportDefaultSpecifier') { + defaultSpecifier = item.local.name + } + }) + let showPath + if (NODE_MODULES_REG.test(vpath)) { + showPath = vpath.replace(nodeModulesPath, `/${npmConfig.name}`) + } else { + showPath = vpath.replace(sourceDir, '') + } + + if (defaultSpecifier) { + astPath.replaceWith(t.variableDeclaration('const', [t.variableDeclarator(t.identifier(defaultSpecifier), t.stringLiteral(showPath.replace(/\\/g, '/')))])) + } else { + astPath.remove() + } + } else if (REG_STYLE.test(valueExtname)) { + const stylePath = path.resolve(path.dirname(sourceFilePath), value) + if (styleFiles.indexOf(stylePath) < 0) { + styleFiles.push(stylePath) + } + astPath.remove() + } else { + let vpath = resolveScriptPath(path.resolve(sourceFilePath, '..', value)) + let outputVpath + if (NODE_MODULES_REG.test(vpath)) { + outputVpath = vpath.replace(nodeModulesPath, npmOutputDir) + } else { + outputVpath = vpath.replace(sourceDir, outputDir) + } + let relativePath = path.relative(filePath, outputVpath) + if (vpath && vpath !== sourceFilePath) { + if (!fs.existsSync(vpath)) { + printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) + } else { + if (fs.lstatSync(vpath).isDirectory()) { + if (fs.existsSync(path.join(vpath, 'index.js'))) { + vpath = path.join(vpath, 'index.js') + relativePath = path.join(relativePath, 'index.js') + } else { + printLog(processTypeEnum.ERROR, '引用目录', `文件 ${sourceFilePath} 中引用了目录 ${value}!`) + return + } + } + if (scriptFiles.indexOf(vpath) < 0) { + scriptFiles.push(vpath) + } + relativePath = promoteRelativePath(relativePath) + relativePath = relativePath.replace(path.extname(relativePath), '.js') + node.source.value = relativePath + } + } + } + } + } +} + +export interface IParseAstReturn { + code: string, + styleFiles: string[], + scriptFiles: string[], + jsonFiles: string[], + mediaFiles: string[] + configObj: IConfig, + componentClassName: string +} + +export function parseAst ( + type: PARSE_AST_TYPE, + ast: t.File, + depComponents: IComponentObj[], + sourceFilePath: string, + filePath: string, + npmSkip: boolean = false +): IParseAstReturn { + const styleFiles: string[] = [] + const scriptFiles: string[] = [] + const jsonFiles: string[] = [] + const mediaFiles: string[] = [] + + const { + nodeModulesPath, + npmOutputDir, + sourceDir, + outputDir, + buildAdapter, + constantsReplaceList, + isProduction, + npmConfig, + alias: pathAlias, + compileInclude, + projectConfig + } = getBuildData() + const notExistNpmList = getNotExistNpmList() + const taroMiniAppFramework = `@tarojs/taro-${buildAdapter}` + let configObj: IConfig = {} + let componentClassName: string = '' + let taroJsReduxConnect: string = '' + let taroImportDefaultName + let needExportDefault = false + let exportTaroReduxConnected: string | null = null + ast = babel.transformFromAst(ast, '', { + plugins: [ + [require('babel-plugin-danger-remove-unused-import'), { ignore: ['@tarojs/taro', 'react', 'nervjs'] }], + [require('babel-plugin-transform-define').default, constantsReplaceList] + ] + }).ast as t.File + traverse(ast, { + ClassDeclaration (astPath) { + const node = astPath.node + let hasCreateData = false + if (node.superClass) { + astPath.traverse({ + ClassMethod (astPath) { + if (astPath.get('key').isIdentifier({ name: '_createData' })) { + hasCreateData = true + } + } + }) + if (hasCreateData) { + needExportDefault = true + astPath.traverse({ + ClassMethod (astPath) { + const node = astPath.node + if (node.kind === 'constructor') { + astPath.traverse({ + ExpressionStatement (astPath) { + const node = astPath.node + if (node.expression && + node.expression.type === 'AssignmentExpression' && + node.expression.operator === '=') { + const left = node.expression.left + if (left.type === 'MemberExpression' && + left.object.type === 'ThisExpression' && + left.property.type === 'Identifier' && + left.property.name === 'config') { + configObj = traverseObjectNode(node.expression.right) + } + } + } + }) + } + } + }) + if (node.id === null) { + componentClassName = '_TaroComponentClass' + astPath.replaceWith( + t.classDeclaration( + t.identifier(componentClassName), + node.superClass as t.Expression, + node.body as t.ClassBody, + node.decorators as t.Decorator[] || [] + ) + ) + } else if (node.id.name === 'App') { + componentClassName = '_App' + astPath.replaceWith( + t.classDeclaration( + t.identifier(componentClassName), + node.superClass as t.Expression, + node.body as t.ClassBody, + node.decorators as t.Decorator[] || [] + ) + ) + } else { + componentClassName = node.id.name + } + } + } + }, + + ClassExpression (astPath) { + const node = astPath.node + if (node.superClass) { + let hasCreateData = false + astPath.traverse({ + ClassMethod (astPath) { + if (astPath.get('key').isIdentifier({ name: '_createData' })) { + hasCreateData = true + } + } + }) + if (hasCreateData) { + needExportDefault = true + if (node.id === null) { + const parentNode = astPath.parentPath.node as any + if (t.isVariableDeclarator(astPath.parentPath)) { + componentClassName = parentNode.id.name + } else { + componentClassName = '_TaroComponentClass' + } + astPath.replaceWith( + t.classExpression( + t.identifier(componentClassName), + node.superClass as t.Expression, + node.body as t.ClassBody, + node.decorators as t.Decorator[] || [] + ) + ) + } else if (node.id.name === 'App') { + componentClassName = '_App' + astPath.replaceWith( + t.classExpression( + t.identifier(componentClassName), + node.superClass as t.Expression, + node.body as t.ClassBody, + node.decorators as t.Decorator[] || [] + ) + ) + } else { + componentClassName = node.id.name + } + } + } + }, + + ClassProperty (astPath) { + const node = astPath.node + if (node.key.name === 'config') { + configObj = traverseObjectNode(node) + } + }, + + ImportDeclaration (astPath) { + const node = astPath.node + const source = node.source + let value = source.value + const specifiers = node.specifiers + // alias 替换 + if (isAliasPath(value, pathAlias)) { + value = replaceAliasPath(sourceFilePath, value, pathAlias) + source.value = value + } + if (isNpmPkg(value) && !notExistNpmList.has(value)) { + if (value === taroJsComponents) { + astPath.remove() + } else { + let isDepComponent = false + if (depComponents && depComponents.length) { + depComponents.forEach(item => { + if (item.path === value) { + isDepComponent = true + } + }) + } + if (isDepComponent) { + astPath.remove() + } else { + const specifiers = node.specifiers + if (value === taroJsFramework) { + let defaultSpecifier: string | null = null + specifiers.forEach(item => { + if (item.type === 'ImportDefaultSpecifier') { + defaultSpecifier = item.local.name + } + }) + if (defaultSpecifier) { + taroImportDefaultName = defaultSpecifier + } + value = taroMiniAppFramework + } else if (value === taroJsRedux) { + specifiers.forEach(item => { + if (item.type === 'ImportSpecifier') { + const local = item.local + if (local.type === 'Identifier' && local.name === 'connect') { + taroJsReduxConnect = item.imported.name + } + } + }) + } + if (!npmSkip) { + source.value = getExactedNpmFilePath({ + npmName: value, + filePath, + isProduction, + npmConfig, + buildAdapter, + npmOutputDir, + compileInclude + }) + } else { + source.value = value + } + } + } + } else if (CSS_EXT.indexOf(path.extname(value)) !== -1 && specifiers.length > 0) { // 对 使用 import style from './style.css' 语法引入的做转化处理 + printLog(processTypeEnum.GENERATE, '替换代码', `为文件 ${sourceFilePath} 生成 css modules`) + const styleFilePath = path.join(path.dirname(sourceFilePath), value) + const styleCode = fs.readFileSync(styleFilePath).toString() + const result = processStyleUseCssModule({ + css: styleCode, + filePath: styleFilePath + }) + const tokens = result.root.exports || {} + const cssModuleMapFile = createCssModuleMap(styleFilePath, tokens) + astPath.node.source = t.stringLiteral(astPath.node.source.value.replace(path.basename(styleFilePath), path.basename(cssModuleMapFile))) + if (styleFiles.indexOf(styleFilePath) < 0) { // add this css file to queue + styleFiles.push(styleFilePath) + } + } else if (path.isAbsolute(value)) { + printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 是绝对路径!`) + } + }, + + CallExpression (astPath) { + const node = astPath.node + const callee = node.callee as (t.Identifier | t.MemberExpression) + if (t.isMemberExpression(callee)) { + if (taroImportDefaultName && (callee.object as t.Identifier).name === taroImportDefaultName && (callee.property as t.Identifier).name === 'render') { + astPath.remove() + } + } else if (callee.name === 'require') { + const args = node.arguments as t.StringLiteral[] + let value = args[0].value + if (isAliasPath(value, pathAlias)) { + value = replaceAliasPath(sourceFilePath, value, pathAlias) + args[0].value = value + } + if (isNpmPkg(value) && !notExistNpmList.has(value)) { + if (value === taroJsComponents) { + astPath.remove() + } else { + let isDepComponent = false + if (depComponents && depComponents.length) { + depComponents.forEach(item => { + if (item.path === value) { + isDepComponent = true + } + }) + } + if (isDepComponent) { + astPath.remove() + } else { + if (t.isVariableDeclaration(astPath.parentPath.parentPath)) { + const parentNode = astPath.parentPath.parentPath.node as t.VariableDeclaration + if (parentNode.declarations.length === 1 && parentNode.declarations[0].init) { + const id = parentNode.declarations[0].id + if (value === taroJsFramework && id.type === 'Identifier') { + taroImportDefaultName = id.name + value = taroMiniAppFramework + } else if (value === taroJsRedux) { + const declarations = parentNode.declarations + declarations.forEach(item => { + const id = item.id + if (id.type === 'ObjectPattern') { + const properties = id.properties as any + properties.forEach(p => { + if (p.type === 'ObjectProperty') { + if (p.value.type === 'Identifier' && p.value.name === 'connect') { + taroJsReduxConnect = p.key.name + } + } + }) + } + }) + } + } + } + if (!npmSkip) { + args[0].value = getExactedNpmFilePath({ + npmName: value, + filePath, + isProduction, + npmConfig, + buildAdapter, + npmOutputDir, + compileInclude + }) + } else { + args[0].value = value + } + } + } + } else if (CSS_EXT.indexOf(path.extname(value)) !== -1 && t.isVariableDeclarator(astPath.parentPath)) { // 对 使用 const style = require('./style.css') 语法引入的做转化处理 + printLog(processTypeEnum.GENERATE, '替换代码', `为文件 ${sourceFilePath} 生成 css modules`) + const styleFilePath = path.join(path.dirname(sourceFilePath), value) + const styleCode = fs.readFileSync(styleFilePath).toString() + const result = processStyleUseCssModule({ + css: styleCode, + filePath: styleFilePath + }) + const tokens = result.root.exports || {} + const objectPropperties: t.ObjectProperty[] = [] + for (const key in tokens) { + if (tokens.hasOwnProperty(key)) { + objectPropperties.push(t.objectProperty(t.identifier(key), t.stringLiteral(tokens[key]))) + } + } + astPath.replaceWith(t.objectExpression(objectPropperties)) + if (styleFiles.indexOf(styleFilePath) < 0) { // add this css file to queue + styleFiles.push(styleFilePath) + } + } else if (path.isAbsolute(value)) { + printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 是绝对路径!`) + } + } + }, + + ExportDefaultDeclaration (astPath) { + const node = astPath.node + const declaration = node.declaration + needExportDefault = false + if ( + declaration && + (declaration.type === 'ClassDeclaration' || declaration.type === 'ClassExpression') + ) { + const superClass = declaration.superClass + if (superClass) { + let hasCreateData = false + astPath.traverse({ + ClassMethod (astPath) { + if (astPath.get('key').isIdentifier({ name: '_createData' })) { + hasCreateData = true + } + } + }) + if (hasCreateData) { + needExportDefault = true + if (declaration.id === null) { + componentClassName = '_TaroComponentClass' + } else if (declaration.id.name === 'App') { + componentClassName = '_App' + } else { + componentClassName = declaration.id.name + } + const isClassDcl = declaration.type === 'ClassDeclaration' + const classDclProps = [t.identifier(componentClassName), superClass, declaration.body, declaration.decorators || []] + astPath.replaceWith(isClassDcl ? t.classDeclaration.apply(null, classDclProps) : t.classExpression.apply(null, classDclProps)) + } + } + } else if (declaration.type === 'CallExpression') { + const callee = declaration.callee + if (callee && callee.type === 'CallExpression') { + const subCallee = callee.callee + if (subCallee.type === 'Identifier' && subCallee.name === taroJsReduxConnect) { + const args = declaration.arguments as t.Identifier[] + if (args.length === 1 && args[0].name === componentClassName) { + needExportDefault = true + exportTaroReduxConnected = `${componentClassName}__Connected` + astPath.replaceWith(t.variableDeclaration('const', [t.variableDeclarator(t.identifier(`${componentClassName}__Connected`), t.callExpression(declaration.callee as t.Expression, declaration.arguments as Array))])) + } + } + } + } + }, + + ExportNamedDeclaration (astPath) { + const node = astPath.node + const source = node.source + if (source && source.type === 'StringLiteral') { + const value = source.value + analyzeImportUrl({ astPath, value, sourceFilePath, filePath, styleFiles, scriptFiles, jsonFiles, mediaFiles }) + } + }, + + ExportAllDeclaration (astPath) { + const node = astPath.node + const source = node.source + if (source && source.type === 'StringLiteral') { + const value = source.value + analyzeImportUrl({ astPath, value, sourceFilePath, filePath, styleFiles, scriptFiles, jsonFiles, mediaFiles }) + } + }, + + Program: { + exit (astPath) { + astPath.traverse({ + ImportDeclaration (astPath) { + const node = astPath.node + const source = node.source + const value = source.value + analyzeImportUrl({ astPath, value, sourceFilePath, filePath, styleFiles, scriptFiles, jsonFiles, mediaFiles }) + }, + CallExpression (astPath) { + const node = astPath.node + const callee = node.callee as t.Identifier + if (callee.name === 'require') { + const args = node.arguments as t.StringLiteral[] + const value = args[0].value + const valueExtname = path.extname(value) + if (value.indexOf('.') === 0) { + let importPath = path.resolve(path.dirname(sourceFilePath), value) + importPath = resolveScriptPath(importPath) + if (isFileToBePage(importPath)) { + if (astPath.parent.type === 'AssignmentExpression' || 'ExpressionStatement') { + astPath.parentPath.remove() + } else if (astPath.parent.type === 'VariableDeclarator') { + astPath.parentPath.parentPath.remove() + } else { + astPath.remove() + } + } else { + if (REG_STYLE.test(valueExtname)) { + const stylePath = path.resolve(path.dirname(sourceFilePath), value) + if (styleFiles.indexOf(stylePath) < 0) { + styleFiles.push(stylePath) + } + if (astPath.parent.type === 'AssignmentExpression' || 'ExpressionStatement') { + astPath.parentPath.remove() + } else if (astPath.parent.type === 'VariableDeclarator') { + astPath.parentPath.parentPath.remove() + } else { + astPath.remove() + } + } else if (REG_JSON.test(valueExtname)) { + const vpath = path.resolve(sourceFilePath, '..', value) + if (jsonFiles.indexOf(vpath) < 0) { + jsonFiles.push(vpath) + } + if (fs.existsSync(vpath)) { + const obj = JSON.parse(fs.readFileSync(vpath).toString()) + let objArr: t.NullLiteral | t.Expression | t.ObjectProperty[] = t.nullLiteral() + if (Array.isArray(obj)) { + objArr = t.arrayExpression(convertArrayToAstExpression(obj)) + } else { + objArr = convertObjectToAstExpression(obj) + } + astPath.replaceWith(t.objectExpression(objArr as any)) + } + } else if (REG_SCRIPT.test(valueExtname) || REG_TYPESCRIPT.test(valueExtname)) { + const vpath = path.resolve(sourceFilePath, '..', value) + let fPath = value + if (fs.existsSync(vpath) && vpath !== sourceFilePath) { + fPath = vpath + } + if (scriptFiles.indexOf(fPath) < 0) { + scriptFiles.push(fPath) + } + } else if (REG_FONT.test(valueExtname) || REG_IMAGE.test(valueExtname) || REG_MEDIA.test(valueExtname)) { + const vpath = path.resolve(sourceFilePath, '..', value) + if (mediaFiles.indexOf(vpath) < 0) { + mediaFiles.push(vpath) + } + let showPath + if (NODE_MODULES_REG.test(vpath)) { + showPath = vpath.replace(nodeModulesPath, `/${npmConfig.name}`) + } else { + showPath = vpath.replace(sourceDir, '') + } + astPath.replaceWith(t.stringLiteral(showPath.replace(/\\/g, '/'))) + } else { + let vpath = resolveScriptPath(path.resolve(sourceFilePath, '..', value)) + let outputVpath + if (NODE_MODULES_REG.test(vpath)) { + outputVpath = vpath.replace(nodeModulesPath, npmOutputDir) + } else { + outputVpath = vpath.replace(sourceDir, outputDir) + } + let relativePath = path.relative(filePath, outputVpath) + if (vpath) { + if (!fs.existsSync(vpath)) { + printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) + } else { + if (fs.lstatSync(vpath).isDirectory()) { + if (fs.existsSync(path.join(vpath, 'index.js'))) { + vpath = path.join(vpath, 'index.js') + relativePath = path.join(relativePath, 'index.js') + } else { + printLog(processTypeEnum.ERROR, '引用目录', `文件 ${sourceFilePath} 中引用了目录 ${value}!`) + return + } + } + if (scriptFiles.indexOf(vpath) < 0) { + scriptFiles.push(vpath) + } + relativePath = promoteRelativePath(relativePath) + relativePath = relativePath.replace(path.extname(relativePath), '.js') + args[0].value = relativePath + } + } + } + } + } + } + } + }) + const node = astPath.node as t.Program + const exportVariableName = exportTaroReduxConnected || componentClassName + if (needExportDefault) { + const exportDefault = template(`export default ${exportVariableName}`, babylonConfig as any)() + node.body.push(exportDefault as any) + } + const taroMiniAppFrameworkPath = !npmSkip ? getExactedNpmFilePath({ + npmName: taroMiniAppFramework, + filePath, + isProduction, + npmConfig, + buildAdapter, + npmOutputDir, + compileInclude + }) : taroMiniAppFramework + switch (type) { + case PARSE_AST_TYPE.ENTRY: + const pxTransformConfig = { + designWidth: projectConfig.designWidth || 750 + } + if (projectConfig.hasOwnProperty(DEVICE_RATIO_NAME)) { + pxTransformConfig[DEVICE_RATIO_NAME] = projectConfig.deviceRatio + } + node.body.push(template(`App(require('${taroMiniAppFrameworkPath}').default.createApp(${exportVariableName}))`, babylonConfig as any)() as any) + node.body.push(template(`Taro.initPxTransform(${JSON.stringify(pxTransformConfig)})`, babylonConfig as any)() as any) + break + case PARSE_AST_TYPE.PAGE: + if (buildAdapter === BUILD_TYPES.WEAPP) { + node.body.push(template(`Component(require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}, true))`, babylonConfig as any)() as any) + } else { + node.body.push(template(`Page(require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}, true))`, babylonConfig as any)() as any) + } + break + case PARSE_AST_TYPE.COMPONENT: + node.body.push(template(`Component(require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}))`, babylonConfig as any)() as any) + break + default: + break + } + } + } + }) + return { + code: generate(ast).code, + styleFiles, + scriptFiles, + jsonFiles, + configObj, + mediaFiles, + componentClassName + } +} + +export function parseComponentExportAst (ast: t.File, componentName: string, componentPath: string, componentType: string): string | null { + const { + constantsReplaceList + } = getBuildData() + let componentRealPath: string | null = null + let importExportName + ast = babel.transformFromAst(ast, '', { + plugins: [ + [require('babel-plugin-transform-define').default, constantsReplaceList] + ] + }).ast as t.File + traverse(ast, { + ExportNamedDeclaration (astPath) { + const node = astPath.node + const specifiers = node.specifiers + const source = node.source + if (source && source.type === 'StringLiteral') { + specifiers.forEach(specifier => { + const exported = specifier.exported + if (_.kebabCase(exported.name) === componentName) { + componentRealPath = resolveScriptPath(path.resolve(path.dirname(componentPath), source.value)) + } + }) + } else { + specifiers.forEach(specifier => { + const exported = specifier.exported + if (_.kebabCase(exported.name) === componentName) { + importExportName = exported.name + } + }) + } + }, + + ExportDefaultDeclaration (astPath) { + const node = astPath.node + const declaration = node.declaration as t.Identifier + if (componentType === 'default') { + importExportName = declaration.name + } + }, + + CallExpression (astPath) { + if (astPath.get('callee').isIdentifier({ name: 'require' })) { + const arg = astPath.get('arguments')[0] + if (t.isStringLiteral(arg.node)) { + componentRealPath = resolveScriptPath(path.resolve(path.dirname(componentPath), arg.node.value)) + } + } + }, + + Program: { + exit (astPath) { + astPath.traverse({ + ImportDeclaration (astPath) { + const node = astPath.node + const specifiers = node.specifiers + const source = node.source + if (importExportName) { + specifiers.forEach(specifier => { + const local = specifier.local + if (local.name === importExportName) { + componentRealPath = resolveScriptPath(path.resolve(path.dirname(componentPath), source.value)) + } + }) + } + } + }) + } + } + }) + return componentRealPath +} diff --git a/packages/taro-cli/src/mini/compileScript.ts b/packages/taro-cli/src/mini/compileScript.ts new file mode 100644 index 000000000000..88885c486b23 --- /dev/null +++ b/packages/taro-cli/src/mini/compileScript.ts @@ -0,0 +1,157 @@ +import * as fs from 'fs-extra' +import * as path from 'path' + +import * as wxTransformer from '@tarojs/transformer-wx' + +import { + printLog, + isDifferentArray +} from '../util' +import { + BUILD_TYPES, + processTypeEnum, + REG_TYPESCRIPT +} from '../util/constants' +import { callPlugin } from '../util/npm' +import { IWxTransformResult } from '../util/types' + +import { + babelConfig, + shouldTransformAgain, + getBuildData, + copyFilesFromSrcToOutput, + getDependencyTree, + uglifyJS +} from './helper' +import { parseAst } from './astProcess' +import { PARSE_AST_TYPE, NODE_MODULES_REG } from './constants' +import { copyFileSync } from './copy' +import { IDependency } from './interface' + +const isBuildingScripts: Map = new Map() + +export function initCompileScripts () { + isBuildingScripts.clear() +} + +export function compileDepScripts (scriptFiles: string[], buildDepSync?: boolean) { + const { + nodeModulesPath, + npmOutputDir, + projectConfig, + sourceDir, + outputDir, + appPath, + buildAdapter, + constantsReplaceList, + isProduction, + jsxAttributeNameReplace + } = getBuildData() + const dependencyTree = getDependencyTree() + return scriptFiles.map(async item => { + if (path.isAbsolute(item)) { + let outputItem + if (NODE_MODULES_REG.test(item)) { + outputItem = item.replace(nodeModulesPath, npmOutputDir).replace(path.extname(item), '.js') + } else { + outputItem = item.replace(path.join(sourceDir), path.join(outputDir)).replace(path.extname(item), '.js') + } + const weappConf = Object.assign({}, projectConfig.weapp) + const useCompileConf = Object.assign({}, weappConf.compile) + const compileExclude = useCompileConf.exclude || [] + let isInCompileExclude = false + compileExclude.forEach(excludeItem => { + if (item.indexOf(path.join(appPath, excludeItem)) >= 0) { + isInCompileExclude = true + } + }) + if (isInCompileExclude) { + copyFileSync(item, outputItem) + return + } + if (!isBuildingScripts.get(outputItem)) { + isBuildingScripts.set(outputItem, true) + try { + const code = fs.readFileSync(item).toString() + const transformResult = wxTransformer({ + code, + sourcePath: item, + outputPath: outputItem, + isNormal: true, + isTyped: REG_TYPESCRIPT.test(item), + adapter: buildAdapter, + env: constantsReplaceList, + jsxAttributeNameReplace + }) + const ast = transformResult.ast + const res = parseAst(PARSE_AST_TYPE.NORMAL, ast, [], item, outputItem) + const fileDep = dependencyTree.get(item) || {} as IDependency + let resCode = res.code + resCode = await compileScriptFile(res.code, item, outputItem, buildAdapter) + fs.ensureDirSync(path.dirname(outputItem)) + if (isProduction) { + uglifyJS(resCode, item) + } + fs.writeFileSync(outputItem, resCode) + let modifyOutput = outputItem.replace(appPath + path.sep, '') + modifyOutput = modifyOutput.split(path.sep).join('/') + printLog(processTypeEnum.GENERATE, '依赖文件', modifyOutput) + // 编译依赖的脚本文件 + if (isDifferentArray(fileDep['script'], res.scriptFiles)) { + if (buildDepSync) { + await Promise.all(compileDepScripts(res.scriptFiles, buildDepSync)) + } else { + compileDepScripts(res.scriptFiles, buildDepSync) + } + } + // 拷贝依赖文件 + if (isDifferentArray(fileDep['json'], res.jsonFiles)) { + copyFilesFromSrcToOutput(res.jsonFiles) + } + if (isDifferentArray(fileDep['media'], res.mediaFiles)) { + copyFilesFromSrcToOutput(res.mediaFiles) + } + fileDep['script'] = res.scriptFiles + fileDep['json'] = res.jsonFiles + fileDep['media'] = res.mediaFiles + dependencyTree.set(item, fileDep) + } catch (err) { + printLog(processTypeEnum.ERROR, '编译失败', item.replace(appPath + path.sep, '')) + console.log(err) + } + } + } + }) +} + +export async function compileScriptFile ( + content: string, + sourceFilePath: string, + outputFilePath: string, + adapter: BUILD_TYPES +): Promise { + const { + constantsReplaceList, + jsxAttributeNameReplace + } = getBuildData() + if (NODE_MODULES_REG.test(sourceFilePath) && fs.existsSync(outputFilePath)) { + return fs.readFileSync(outputFilePath).toString() + } + const compileScriptRes = await callPlugin('babel', content, sourceFilePath, babelConfig) + const code = compileScriptRes.code + if (!shouldTransformAgain) { + return code + } + const transformResult: IWxTransformResult = wxTransformer({ + code, + sourcePath: sourceFilePath, + outputPath: outputFilePath, + isNormal: true, + isTyped: false, + adapter, + env: constantsReplaceList, + jsxAttributeNameReplace + }) + const res = parseAst(PARSE_AST_TYPE.NORMAL, transformResult.ast, [], sourceFilePath, outputFilePath) + return res.code +} diff --git a/packages/taro-cli/src/mini/compileStyle.ts b/packages/taro-cli/src/mini/compileStyle.ts new file mode 100644 index 000000000000..85c079420772 --- /dev/null +++ b/packages/taro-cli/src/mini/compileStyle.ts @@ -0,0 +1,255 @@ +import * as fs from 'fs-extra' +import * as path from 'path' + +import * as autoprefixer from 'autoprefixer' +import * as postcss from 'postcss' +import * as pxtransform from 'postcss-pxtransform' + +import browserList from '../config/browser_list' +import { + resolveNpmPkgMainPath, + resolveNpmFilesPath +} from '../util/resolve_npm_files' +import { + callPlugin, callPluginSync +} from '../util/npm' +import { + isNpmPkg, + processStyleImports, + promoteRelativePath +} from '../util' +import { CSS_EXT, FILE_PROCESSOR_MAP } from '../util/constants' +import { IMiniAppConfig } from '../util/types' + +import { + getBuildData +} from './helper' +import { DEVICE_RATIO_NAME } from './constants' + +const cssUrlParse = require('postcss-url') +const genericNames = require('generic-names') +const Scope = require('postcss-modules-scope') +const Values = require('postcss-modules-values') +const LocalByDefault = require('postcss-modules-local-by-default') +const ExtractImports = require('postcss-modules-extract-imports') +const ResolveImports = require('postcss-modules-resolve-imports') +interface IStyleObj { + css: string, + filePath: string +} + +const appPath = process.cwd() +const isBuildingStyles: Map = new Map() + +export function initCompileStyles () { + isBuildingStyles.clear() +} + +export interface ICSSModulesConf { + enable: boolean, + config: { + generateScopedName: string | ((localName: string, absoluteFilePath: string) => string), + namingPattern: 'global' | 'module' + } +} + +/** + * css module processor + * @param styleObj { css: string, filePath: '' } + * @returns postcss.process() + */ +export function processStyleUseCssModule (styleObj: IStyleObj): any { + const { projectConfig } = getBuildData() + const weappConf = Object.assign({}, projectConfig.weapp) + const useModuleConf = weappConf.module || {} + const customPostcssConf = useModuleConf.postcss || {} + const customCssModulesConf: ICSSModulesConf = Object.assign({ + enable: false, + config: { + generateScopedName: '[name]__[local]___[hash:base64:5]', + namingPattern: 'global' + } + }, customPostcssConf.cssModules || {}) + if (!customCssModulesConf.enable) { + return styleObj + } + const namingPattern = customCssModulesConf.config.namingPattern + if (namingPattern === 'module') { + // 只对 xxx.module.[css|scss|less|styl] 等样式文件做处理 + const DO_USE_CSS_MODULE_REGEX = /^(.*\.module).*\.(css|scss|less|styl)$/ + if (!DO_USE_CSS_MODULE_REGEX.test(styleObj.filePath)) return styleObj + } else { + // 对 xxx.global.[css|scss|less|styl] 等样式文件不做处理 + const DO_NOT_USE_CSS_MODULE_REGEX = /^(.*\.global).*\.(css|scss|less|styl)$/ + if (DO_NOT_USE_CSS_MODULE_REGEX.test(styleObj.filePath)) return styleObj + } + const generateScopedName = customCssModulesConf.config.generateScopedName + const context = process.cwd() + let scopedName + if (generateScopedName) { + scopedName = typeof generateScopedName === 'function' + ? (local, filename) => generateScopedName(local, filename) + : genericNames(generateScopedName, { context }) + } else { + scopedName = (local, filename) => Scope.generateScopedName(local, path.relative(context, filename)) + } + const postcssPlugins = [ + Values, + LocalByDefault, + ExtractImports, + new Scope({ generateScopedName: scopedName }), + new ResolveImports({ resolve: Object.assign({}, { extensions: CSS_EXT }) }) + ] + const runner = postcss(postcssPlugins) + const result = runner.process(styleObj.css, Object.assign({}, { from: styleObj.filePath })) + return result +} + +async function processStyleWithPostCSS (styleObj: IStyleObj): Promise { + const { projectConfig, npmConfig, isProduction, buildAdapter } = getBuildData() + const weappConf = Object.assign({}, projectConfig.weapp) + const useModuleConf = weappConf.module || {} + const customPostcssConf = useModuleConf.postcss || {} + const customCssModulesConf = Object.assign({ + enable: false, + config: { + generateScopedName: '[name]__[local]___[hash:base64:5]' + } + }, customPostcssConf.cssModules || {}) + const customPxtransformConf = Object.assign({ + enable: true, + config: {} + }, customPostcssConf.pxtransform || {}) + const customUrlConf = Object.assign({ + enable: true, + config: { + limit: 10240 + } + }, customPostcssConf.url || {}) + const customAutoprefixerConf = Object.assign({ + enable: true, + config: { + browsers: browserList + } + }, customPostcssConf.autoprefixer || {}) + const postcssPxtransformOption = { + designWidth: projectConfig.designWidth || 750, + platform: 'weapp' + } + + if (projectConfig.hasOwnProperty(DEVICE_RATIO_NAME)) { + postcssPxtransformOption[DEVICE_RATIO_NAME] = projectConfig.deviceRatio + } + const cssUrlConf = Object.assign({ limit: 10240 }, customUrlConf) + const maxSize = Math.round((customUrlConf.config.limit || cssUrlConf.limit) / 1024) + const postcssPxtransformConf = Object.assign({}, postcssPxtransformOption, customPxtransformConf, customPxtransformConf.config) + const processors: any[] = [] + if (customAutoprefixerConf.enable) { + processors.push(autoprefixer(customAutoprefixerConf.config)) + } + if (customPxtransformConf.enable) { + processors.push(pxtransform(postcssPxtransformConf)) + } + if (cssUrlConf.enable) { + processors.push(cssUrlParse({ + url: 'inline', + maxSize, + encodeType: 'base64' + })) + } + + const defaultPostCSSPluginNames = ['autoprefixer', 'pxtransform', 'url', 'cssModules'] + Object.keys(customPostcssConf).forEach(pluginName => { + if (defaultPostCSSPluginNames.indexOf(pluginName) < 0) { + const pluginConf = customPostcssConf[pluginName] + if (pluginConf && pluginConf.enable) { + if (!isNpmPkg(pluginName)) { // local plugin + pluginName = path.join(appPath, pluginName) + } + processors.push(require(resolveNpmPkgMainPath(pluginName, isProduction, npmConfig, buildAdapter))(pluginConf.config || {})) + } + } + }) + let css = styleObj.css + if (customCssModulesConf.enable) { + css = processStyleUseCssModule(styleObj).css + } + const postcssResult = await postcss(processors).process(css, { + from: styleObj.filePath + }) + return postcssResult.css +} + +function compileImportStyles (filePath: string, importStyles: string[]) { + const { sourceDir, outputDir } = getBuildData() + if (importStyles.length) { + importStyles.forEach(async importItem => { + const importFilePath = path.resolve(filePath, '..', importItem) + if (fs.existsSync(importFilePath)) { + await compileDepStyles(importFilePath.replace(sourceDir, outputDir), [importFilePath]) + } + }) + } +} + +export function compileDepStyles (outputFilePath: string, styleFiles: string[]) { + if (isBuildingStyles.get(outputFilePath)) { + return Promise.resolve({}) + } + const { projectConfig, npmConfig, isProduction, buildAdapter } = getBuildData() + const pluginsConfig = projectConfig.plugins || {} + const weappConf = projectConfig.weapp || {} as IMiniAppConfig + const useCompileConf = Object.assign({}, weappConf.compile) + const compileInclude = useCompileConf.include || [] + isBuildingStyles.set(outputFilePath, true) + return Promise.all(styleFiles.map(async p => { + const filePath = path.join(p) + const fileExt = path.extname(filePath) + const pluginName = FILE_PROCESSOR_MAP[fileExt] + const fileContent = fs.readFileSync(filePath).toString() + const cssImportsRes = processStyleImports(fileContent, buildAdapter, (str, stylePath) => { + if (stylePath.indexOf('~') === 0) { + let newStylePath = stylePath + newStylePath = stylePath.replace('~', '') + const npmInfo = resolveNpmFilesPath(newStylePath, isProduction, npmConfig, buildAdapter, appPath, compileInclude) + const importRelativePath = promoteRelativePath(path.relative(filePath, npmInfo.main)) + return str.replace(stylePath, importRelativePath) + } + return str + }) + compileImportStyles(filePath, cssImportsRes.imports) + if (pluginName) { + return callPlugin(pluginName, cssImportsRes.content, filePath, pluginsConfig[pluginName] || {}) + .then(res => ({ + css: cssImportsRes.style.join('\n') + '\n' + res.css, + filePath + })).catch(err => { + if (err) { + console.log(err) + process.exit(0) + } + }) + } + return new Promise(resolve => { + resolve({ + css: cssImportsRes.style.join('\n') + '\n' + cssImportsRes.content, + filePath + }) + }) + })).then(async resList => { + await Promise.all(resList.map(res => processStyleWithPostCSS(res))) + .then(cssList => { + let resContent = cssList.map(res => res).join('\n') + if (isProduction) { + const cssoPuginConfig = pluginsConfig.csso || { enable: true } + if (cssoPuginConfig.enable) { + const cssoConfig = cssoPuginConfig.config || {} + const cssoResult = callPluginSync('csso', resContent, outputFilePath, cssoConfig) + resContent = cssoResult.css + } + } + fs.ensureDirSync(path.dirname(outputFilePath)) + fs.writeFileSync(outputFilePath, resContent) + }) + }) +} diff --git a/packages/taro-cli/src/mini/component.ts b/packages/taro-cli/src/mini/component.ts new file mode 100644 index 000000000000..4e8bf7466802 --- /dev/null +++ b/packages/taro-cli/src/mini/component.ts @@ -0,0 +1,331 @@ +import * as fs from 'fs-extra' +import * as path from 'path' + +import { Config as IConfig } from '@tarojs/taro' +import * as wxTransformer from '@tarojs/transformer-wx' +import * as _ from 'lodash' +import traverse from 'babel-traverse' + +import { IWxTransformResult } from '../util/types' +import { + REG_TYPESCRIPT, + processTypeEnum +} from '../util/constants' +import { + printLog, + isEmptyObject, + promoteRelativePath, + isDifferentArray +} from '../util' + +import { parseComponentExportAst, parseAst } from './astProcess' +import { IComponentObj, IBuildResult } from './interface' +import { + setHasBeenBuiltComponents, + isComponentHasBeenBuilt, + getBuildData, + setComponentExportsMap, + getComponentExportsMap, + getRealComponentsPathList, + uglifyJS, + copyFilesFromSrcToOutput, + getComponentsBuildResult, + getDependencyTree, + buildUsingComponents, + getDepComponents +} from './helper' +import { compileScriptFile, compileDepScripts } from './compileScript' +import { compileDepStyles } from './compileStyle' +import { transfromNativeComponents, processNativeWxml } from './native' +import { PARSE_AST_TYPE, NODE_MODULES_REG, NODE_MODULES } from './constants' + +const notTaroComponents = new Set() +const componentsNamedMap = new Map() + +export function getComponentsNamedMap () { + return componentsNamedMap +} + +export function isFileToBeTaroComponent ( + code: string, + sourcePath: string, + outputPath: string +) { + const { + buildAdapter, + constantsReplaceList, + jsxAttributeNameReplace + } = getBuildData() + const transformResult: IWxTransformResult = wxTransformer({ + code, + sourcePath: sourcePath, + outputPath: outputPath, + isNormal: true, + isTyped: REG_TYPESCRIPT.test(sourcePath), + adapter: buildAdapter, + env: constantsReplaceList, + jsxAttributeNameReplace + }) + const { ast }: IWxTransformResult = transformResult + let isTaroComponent = false + + traverse(ast, { + ClassDeclaration (astPath) { + astPath.traverse({ + ClassMethod (astPath) { + if (astPath.get('key').isIdentifier({ name: 'render' })) { + astPath.traverse({ + JSXElement () { + isTaroComponent = true + } + }) + } + } + }) + }, + + ClassExpression (astPath) { + astPath.traverse({ + ClassMethod (astPath) { + if (astPath.get('key').isIdentifier({ name: 'render' })) { + astPath.traverse({ + JSXElement () { + isTaroComponent = true + } + }) + } + } + }) + } + }) + + return { + isTaroComponent, + transformResult + } +} + +export interface IComponentBuildConfig { + outputDir?: string, + outputDirName?: string, + npmSkip?: boolean +} + +export function buildDepComponents ( + componentPathList: IComponentObj[], + buildConfig?: IComponentBuildConfig +): Promise { + return Promise.all(componentPathList.map(componentObj => buildSingleComponent(componentObj, buildConfig))) +} + +export async function buildSingleComponent ( + componentObj: IComponentObj, + buildConfig: IComponentBuildConfig = {} +): Promise { + const componentsBuildResult = getComponentsBuildResult() + if (isComponentHasBeenBuilt(componentObj.path as string) && componentsBuildResult[componentObj.path as string]) { + return componentsBuildResult[componentObj.path as string] + } + const { + appPath, + buildAdapter, + constantsReplaceList, + sourceDir, + outputDir, + sourceDirName, + outputDirName, + npmOutputDir, + nodeModulesPath, + outputFilesTypes, + isProduction, + jsxAttributeNameReplace + } = getBuildData() + + if (componentObj.path) { + componentsNamedMap.set(componentObj.path, { + name: componentObj.name, + type: componentObj.type + }) + } + const component = componentObj.path + if (!component) { + printLog(processTypeEnum.ERROR, '组件错误', `组件${_.upperFirst(_.camelCase(componentObj.name))}路径错误,请检查!(可能原因是导出的组件名不正确)`) + return { + js: '', + wxss: '', + wxml: '' + } + } + let componentShowPath = component.replace(appPath + path.sep, '') + componentShowPath = componentShowPath.split(path.sep).join('/') + let isComponentFromNodeModules = false + let sourceDirPath = sourceDir + let buildOutputDir = outputDir + // 来自 node_modules 的组件 + if (NODE_MODULES_REG.test(componentShowPath)) { + isComponentFromNodeModules = true + sourceDirPath = nodeModulesPath + buildOutputDir = npmOutputDir + } + let outputComponentShowPath = componentShowPath.replace(isComponentFromNodeModules ? NODE_MODULES : sourceDirName, buildConfig.outputDirName || outputDirName) + outputComponentShowPath = outputComponentShowPath.replace(path.extname(outputComponentShowPath), '') + printLog(processTypeEnum.COMPILE, '组件文件', componentShowPath) + const componentContent = fs.readFileSync(component).toString() + const outputComponentJSPath = component.replace(sourceDirPath, buildConfig.outputDir || buildOutputDir).replace(path.extname(component), outputFilesTypes.SCRIPT) + const outputComponentWXMLPath = outputComponentJSPath.replace(path.extname(outputComponentJSPath), outputFilesTypes.TEMPL) + const outputComponentWXSSPath = outputComponentJSPath.replace(path.extname(outputComponentJSPath), outputFilesTypes.STYLE) + const outputComponentJSONPath = outputComponentJSPath.replace(path.extname(outputComponentJSPath), outputFilesTypes.CONFIG) + if (!isComponentHasBeenBuilt(component)) { + setHasBeenBuiltComponents(component) + } + try { + const isTaroComponentRes = isFileToBeTaroComponent(componentContent, component, outputComponentJSPath) + const componentExportsMap = getComponentExportsMap() + if (!isTaroComponentRes.isTaroComponent) { + const transformResult = isTaroComponentRes.transformResult + const componentRealPath = parseComponentExportAst(transformResult.ast, componentObj.name as string, component, componentObj.type as string) + const realComponentObj: IComponentObj = { + path: componentRealPath, + name: componentObj.name, + type: componentObj.type + } + let isInMap = false + notTaroComponents.add(component) + if (!isEmptyObject(componentExportsMap)) { + Object.keys(componentExportsMap).forEach(key => { + componentExportsMap[key].forEach(item => { + if (item.path === component) { + isInMap = true + item.path = componentRealPath + } + }) + }) + } + if (!isInMap) { + const componentExportsMapItem = componentExportsMap.get(component) || [] + componentExportsMapItem.push(realComponentObj) + setComponentExportsMap(component, componentExportsMapItem) + } + return await buildSingleComponent(realComponentObj, buildConfig) + } + const transformResult: IWxTransformResult = wxTransformer({ + code: componentContent, + sourcePath: component, + outputPath: outputComponentJSPath, + isRoot: false, + isTyped: REG_TYPESCRIPT.test(component), + isNormal: false, + adapter: buildAdapter, + env: constantsReplaceList, + jsxAttributeNameReplace + }) + const componentWXMLContent = isProduction ? transformResult.compressedTemplate : transformResult.template + const componentDepComponents = transformResult.components + const res = parseAst(PARSE_AST_TYPE.COMPONENT, transformResult.ast, componentDepComponents, component, outputComponentJSPath, buildConfig.npmSkip) + let resCode = res.code + resCode = await compileScriptFile(resCode, component, outputComponentJSPath, buildAdapter) + fs.ensureDirSync(path.dirname(outputComponentJSPath)) + if (isProduction) { + uglifyJS(resCode, component) + } + const { usingComponents = {} }: IConfig = res.configObj + if (usingComponents && !isEmptyObject(usingComponents)) { + const keys = Object.keys(usingComponents) + keys.forEach(item => { + componentDepComponents.forEach(component => { + if (_.camelCase(item) === _.camelCase(component.name)) { + delete usingComponents[item] + } + }) + }) + transfromNativeComponents(outputComponentJSONPath.replace(buildConfig.outputDir || buildOutputDir, sourceDirPath), res.configObj) + } + const dependencyTree = getDependencyTree() + const fileDep = dependencyTree.get(component) || {} + // 编译依赖的组件文件 + let realComponentsPathList: IComponentObj[] = [] + if (componentDepComponents.length) { + realComponentsPathList = getRealComponentsPathList(component, componentDepComponents) + res.scriptFiles = res.scriptFiles.map(item => { + for (let i = 0; i < realComponentsPathList.length; i++) { + const componentObj = realComponentsPathList[i] + const componentPath = componentObj.path + if (item === componentPath) { + return '' + } + } + return item + }).filter(item => item) + realComponentsPathList = realComponentsPathList.filter(item => isComponentHasBeenBuilt(item.path as string) || notTaroComponents.has(item.path as string)) + await buildDepComponents(realComponentsPathList) + } + if (!isEmptyObject(componentExportsMap) && realComponentsPathList.length) { + const mapKeys = Object.keys(componentExportsMap) + realComponentsPathList.forEach(componentObj => { + if (mapKeys.indexOf(componentObj.path as string) >= 0) { + const componentMap = componentExportsMap[componentObj.path as string] + componentMap.forEach(componentObj => { + componentDepComponents.forEach(depComponent => { + if (depComponent.name === componentObj.name) { + let componentPath = componentObj.path + let realPath + if (NODE_MODULES_REG.test(componentPath)) { + componentPath = componentPath.replace(nodeModulesPath, npmOutputDir) + realPath = promoteRelativePath(path.relative(outputComponentJSPath, componentPath)) + } else { + realPath = promoteRelativePath(path.relative(component, componentPath)) + } + depComponent.path = realPath.replace(path.extname(realPath), '') + } + }) + }) + } + }) + } + fs.writeFileSync(outputComponentJSONPath, JSON.stringify(_.merge({}, buildUsingComponents(component, componentDepComponents, true), res.configObj), null, 2)) + printLog(processTypeEnum.GENERATE, '组件配置', `${outputDirName}/${outputComponentShowPath}${outputFilesTypes.CONFIG}`) + fs.writeFileSync(outputComponentJSPath, resCode) + printLog(processTypeEnum.GENERATE, '组件逻辑', `${outputDirName}/${outputComponentShowPath}${outputFilesTypes.SCRIPT}`) + fs.writeFileSync(outputComponentWXMLPath, componentWXMLContent) + processNativeWxml(outputComponentWXMLPath.replace(outputDir, sourceDir), componentWXMLContent, outputComponentWXMLPath) + printLog(processTypeEnum.GENERATE, '组件模板', `${outputDirName}/${outputComponentShowPath}${outputFilesTypes.TEMPL}`) + // 编译依赖的脚本文件 + if (isDifferentArray(fileDep['script'], res.scriptFiles)) { + compileDepScripts(res.scriptFiles) + } + const depComponents = getDepComponents() + // 编译样式文件 + if (isDifferentArray(fileDep['style'], res.styleFiles) || isDifferentArray(depComponents.get(component) || [], componentDepComponents)) { + printLog(processTypeEnum.GENERATE, '组件样式', `${outputDirName}/${outputComponentShowPath}${outputFilesTypes.STYLE}`) + await compileDepStyles(outputComponentWXSSPath, res.styleFiles) + } + // 拷贝依赖文件 + if (isDifferentArray(fileDep['json'], res.jsonFiles)) { + copyFilesFromSrcToOutput(res.jsonFiles) + } + if (isDifferentArray(fileDep['media'], res.mediaFiles)) { + copyFilesFromSrcToOutput(res.mediaFiles) + } + fileDep['style'] = res.styleFiles + fileDep['script'] = res.scriptFiles + fileDep['json'] = res.jsonFiles + fileDep['media'] = res.mediaFiles + dependencyTree[component] = fileDep + depComponents.set(component, componentDepComponents) + const buildResult = { + js: outputComponentJSPath, + wxss: outputComponentWXSSPath, + wxml: outputComponentWXMLPath + } + componentsBuildResult.set(component, buildResult) + return buildResult + } catch (err) { + printLog(processTypeEnum.ERROR, '组件编译', `组件${componentShowPath}编译失败!`) + console.log(err) + return { + js: '', + wxss: '', + wxml: '' + } + } +} diff --git a/packages/taro-cli/src/mini/constants.ts b/packages/taro-cli/src/mini/constants.ts new file mode 100644 index 000000000000..13c44e0d256d --- /dev/null +++ b/packages/taro-cli/src/mini/constants.ts @@ -0,0 +1,18 @@ +import * as os from 'os' + +export const taroJsFramework = '@tarojs/taro' +export const taroJsComponents = '@tarojs/components' +export const taroJsRedux = '@tarojs/redux' + +export const NODE_MODULES = 'node_modules' +export const NODE_MODULES_REG = /(.*)node_modules/ + +export enum PARSE_AST_TYPE { + ENTRY = 'ENTRY', + PAGE = 'PAGE', + COMPONENT = 'COMPONENT', + NORMAL = 'NORMAL' +} + +export const DEVICE_RATIO_NAME = 'deviceRatio' +export const isWindows = os.platform() === 'win32' diff --git a/packages/taro-cli/src/mini/copy.ts b/packages/taro-cli/src/mini/copy.ts new file mode 100644 index 000000000000..4458c810f76e --- /dev/null +++ b/packages/taro-cli/src/mini/copy.ts @@ -0,0 +1,20 @@ +import * as fs from 'fs-extra' +import * as path from 'path' + +import { ICopyOptions } from './interface' + +export function copyFileSync (from: string, to: string, options?: ICopyOptions) { + const filename = path.basename(from) + if (fs.statSync(from).isFile() && !path.extname(to)) { + fs.ensureDir(to) + if (from === path.join(to, filename)) { + return + } + return fs.copySync(from, path.join(to, filename), options) + } + if (from === to) { + return + } + fs.ensureDir(path.dirname(to)) + return fs.copySync(from, to, options) +} diff --git a/packages/taro-cli/src/mini/entry.ts b/packages/taro-cli/src/mini/entry.ts new file mode 100644 index 000000000000..fb45bddb8d34 --- /dev/null +++ b/packages/taro-cli/src/mini/entry.ts @@ -0,0 +1,181 @@ +import * as fs from 'fs-extra' +import * as path from 'path' + +import { AppConfig } from '@tarojs/taro' +import * as wxTransformer from '@tarojs/transformer-wx' + +import { + REG_SCRIPTS, + REG_TYPESCRIPT, + CONFIG_MAP, + processTypeEnum +} from '../util/constants' +import { + isDifferentArray, + printLog, + isEmptyObject, + resolveScriptPath +} from '../util' +import { IWxTransformResult } from '../util/types' + +import { getBuildData, uglifyJS, copyFilesFromSrcToOutput, getDependencyTree } from './helper' +import { PARSE_AST_TYPE } from './constants' +import { compileDepScripts, compileScriptFile } from './compileScript' +import { compileDepStyles } from './compileStyle' +import { parseAst } from './astProcess' +import { buildSingleComponent } from './component' + +async function buildCustomTabbar () { + const { + sourceDir + } = getBuildData() + const customTabbarPath = path.join(sourceDir, 'custom-tab-bar') + const customTabbarJSPath = resolveScriptPath(customTabbarPath) + await buildSingleComponent({ + path: customTabbarJSPath, + name: 'custom-tab-bar' + }) +} + +function buildWorkers (worker: string) { + const { + sourceDir + } = getBuildData() + printLog(processTypeEnum.COMPILE, 'Workers', '编译 worker 相关文件') + const workerDir = path.join(sourceDir, worker) + function fileRecursiveSearch (fileDir) { + fs.readdir(fileDir, (err, files) => { + if (err) { + console.warn(err) + } else { + files.forEach(filename => { + const filePath = path.join(fileDir, filename) + fs.stat(filePath, (err, stats) => { + if (err) { + console.warn(err) + } else { + const isFile = stats.isFile() + const isDir = stats.isDirectory() + if (isFile) { + if (REG_SCRIPTS.test(filePath)) { + compileDepScripts([filePath]) + } else { + copyFilesFromSrcToOutput([filePath]) + } + } else if (isDir) { + fileRecursiveSearch(filePath) + } + } + }) + }) + } + }) + } + fileRecursiveSearch(workerDir) +} + +export async function buildEntry (): Promise { + const { + buildAdapter, + constantsReplaceList, + entryFilePath, + sourceDir, + outputDir, + entryFileName, + sourceDirName, + outputDirName, + projectConfig, + outputFilesTypes, + isProduction, + jsxAttributeNameReplace + } = getBuildData() + const weappConf = projectConfig.weapp || { appOutput: true} + const appOutput = typeof weappConf.appOutput === 'boolean' ? weappConf.appOutput : true + const entryFileCode = fs.readFileSync(entryFilePath).toString() + const outputEntryFilePath = path.join(outputDir, entryFileName) + + printLog(processTypeEnum.COMPILE, '入口文件', `${sourceDirName}/${entryFileName}`) + try { + const transformResult: IWxTransformResult = wxTransformer({ + code: entryFileCode, + sourcePath: entryFilePath, + outputPath: outputEntryFilePath, + isApp: true, + isTyped: REG_TYPESCRIPT.test(entryFilePath), + adapter: buildAdapter, + env: constantsReplaceList, + jsxAttributeNameReplace + }) + // app.js的template忽略 + const res = parseAst(PARSE_AST_TYPE.ENTRY, transformResult.ast, [], entryFilePath, outputEntryFilePath) + let resCode = res.code + resCode = await compileScriptFile(resCode, entryFilePath, outputEntryFilePath, buildAdapter) + if (isProduction) { + resCode = uglifyJS(resCode, entryFilePath) + } + if (appOutput) { + fs.writeFileSync(path.join(outputDir, 'app.json'), JSON.stringify(res.configObj, null, 2)) + printLog(processTypeEnum.GENERATE, '入口配置', `${outputDirName}/app.json`) + fs.writeFileSync(path.join(outputDir, 'app.js'), resCode) + printLog(processTypeEnum.GENERATE, '入口文件', `${outputDirName}/app.js`) + } + if (res.configObj.workers) { + buildWorkers(res.configObj.workers) + } + if (res.configObj.tabBar && res.configObj.tabBar.custom) { + await buildCustomTabbar() + } + const dependencyTree = getDependencyTree() + const fileDep = dependencyTree.get(entryFilePath) || { + style: [], + script: [], + json: [], + media: [] + } + // 编译依赖的脚本文件 + if (isDifferentArray(fileDep['script'], res.scriptFiles)) { + compileDepScripts(res.scriptFiles) + } + // 编译样式文件 + if (isDifferentArray(fileDep['style'], res.styleFiles) && appOutput) { + await compileDepStyles(path.join(outputDir, `app${outputFilesTypes.STYLE}`), res.styleFiles) + printLog(processTypeEnum.GENERATE, '入口样式', `${outputDirName}/app${outputFilesTypes.STYLE}`) + } + // 拷贝依赖文件 + if (isDifferentArray(fileDep['json'], res.jsonFiles)) { + copyFilesFromSrcToOutput(res.jsonFiles) + } + + // 处理res.configObj 中的tabBar配置 + const tabBar = res.configObj.tabBar + if (tabBar && typeof tabBar === 'object' && !isEmptyObject(tabBar)) { + const { + list: listConfig, + iconPath: pathConfig, + selectedIconPath: selectedPathConfig + } = CONFIG_MAP[buildAdapter] + const list = tabBar[listConfig] || [] + let tabBarIcons: string[] = [] + list.forEach(item => { + item[pathConfig] && tabBarIcons.push(item[pathConfig]) + item[selectedPathConfig] && tabBarIcons.push(item[selectedPathConfig]) + }) + tabBarIcons = tabBarIcons.map(item => path.resolve(sourceDir, item)) + if (tabBarIcons && tabBarIcons.length) { + res.mediaFiles = res.mediaFiles.concat(tabBarIcons) + } + } + if (isDifferentArray(fileDep['media'], res.mediaFiles)) { + copyFilesFromSrcToOutput(res.mediaFiles) + } + fileDep['style'] = res.styleFiles + fileDep['script'] = res.scriptFiles + fileDep['json'] = res.jsonFiles + fileDep['media'] = res.mediaFiles + dependencyTree.set(entryFilePath, fileDep) + return res.configObj + } catch (err) { + console.log(err) + return {} + } +} diff --git a/packages/taro-cli/src/mini/helper.ts b/packages/taro-cli/src/mini/helper.ts new file mode 100644 index 000000000000..e3bd3b98ad74 --- /dev/null +++ b/packages/taro-cli/src/mini/helper.ts @@ -0,0 +1,334 @@ +import * as fs from 'fs-extra' +import * as path from 'path' + +import * as _ from 'lodash' +import { AppConfig } from '@tarojs/taro' + +import { + BUILD_TYPES, + MINI_APP_FILES, + IMINI_APP_FILE_TYPE, + PROJECT_CONFIG, + processTypeEnum, + REG_SCRIPTS +} from '../util/constants' +import { + resolveScriptPath, + isAliasPath, + replaceAliasPath, + promoteRelativePath, + isNpmPkg, + printLog, + generateEnvList, + generateConstantsList, + isEmptyObject +} from '../util' +import { callPluginSync } from '../util/npm' +import { resolveNpmPkgMainPath } from '../util/resolve_npm_files' +import { + IProjectConfig, + IOption, + INpmConfig +} from '../util/types' +import defaultBabelConfig from '../config/babel' +import defaultUglifyConfig from '../config/uglify' +import CONFIG from '../config' + +import { + IComponentObj, + IBuildResult, + IDependency +} from './interface' +import { NODE_MODULES_REG } from './constants' +import { getNodeModulesPath, getNpmOutputDir } from './npmExact' + +const appPath = process.cwd() +const configDir = path.join(appPath, PROJECT_CONFIG) +const projectConfig = require(configDir)(_.merge) +const sourceDirName = projectConfig.sourceRoot || CONFIG.SOURCE_DIR +const outputDirName = projectConfig.outputRoot || CONFIG.OUTPUT_DIR +const sourceDir = path.join(appPath, sourceDirName) +const outputDir = path.join(appPath, outputDirName) +const entryFilePath = resolveScriptPath(path.join(sourceDir, CONFIG.ENTRY)) +const entryFileName = path.basename(entryFilePath) + +const plugins = projectConfig.plugins || {} +const pathAlias = projectConfig.alias || {} +const weappConf = projectConfig.weapp || {} +const npmConfig = Object.assign({ + name: CONFIG.NPM_DIR, + dir: null +}, weappConf.npm) +const useCompileConf = Object.assign({}, weappConf.compile) +const compileInclude = useCompileConf.include || [] + +const isCopyingFiles: Map = new Map() +const dependencyTree: Map = new Map() +const hasBeenBuiltComponents: Set = new Set() +const componentExportsMap = new Map() +const componentsBuildResult = new Map() +const depComponents = new Map() + +export interface IBuildData { + appPath: string, + configDir: string, + sourceDirName: string, + outputDirName: string, + sourceDir: string, + outputDir: string, + entryFilePath: string, + entryFileName: string, + projectConfig: IProjectConfig, + npmConfig: INpmConfig, + appConfig: AppConfig, + alias: IOption, + compileInclude: string[], + isProduction: boolean, + buildAdapter: BUILD_TYPES, + outputFilesTypes: IMINI_APP_FILE_TYPE, + constantsReplaceList: IOption, + nodeModulesPath: string, + npmOutputDir: string, + jsxAttributeNameReplace?: { + [key: string]: any + } +} + +const BuildData: IBuildData = { + appPath, + configDir, + sourceDirName, + outputDirName, + sourceDir, + outputDir, + entryFilePath, + entryFileName, + projectConfig, + npmConfig, + alias: pathAlias, + isProduction: false, + appConfig: {}, + compileInclude, + buildAdapter: BUILD_TYPES.WEAPP, + outputFilesTypes: MINI_APP_FILES[BUILD_TYPES.WEAPP], + constantsReplaceList: {}, + nodeModulesPath: getNodeModulesPath(), + npmOutputDir: getNpmOutputDir(outputDir, configDir, npmConfig), + jsxAttributeNameReplace: weappConf.jsxAttributeNameReplace || {} +} + +export const babelConfig = _.mergeWith({}, defaultBabelConfig, plugins.babel, (objValue, srcValue) => { + if (Array.isArray(objValue)) { + return Array.from(new Set(srcValue.concat(objValue))) + } +}) + +export const shouldTransformAgain = (function () { + const pluginsStr = JSON.stringify(babelConfig.plugins) + if (/transform-runtime/.test(pluginsStr)) { + return true + } + return false +})() + +export function setAppConfig (appConfig: AppConfig) { + BuildData.appConfig = appConfig +} + +export function setIsProduction (isProduction: boolean) { + BuildData.isProduction = isProduction +} + +export function setBuildAdapter (adapter: BUILD_TYPES) { + BuildData.buildAdapter = adapter + BuildData.outputFilesTypes = MINI_APP_FILES[adapter] + // 可以自定义输出文件类型 + if (weappConf.customFilesTypes && !isEmptyObject(weappConf.customFilesTypes)) { + BuildData.outputFilesTypes = Object.assign({}, BuildData.outputFilesTypes, weappConf.customFilesTypes[adapter] || {}) + } + BuildData.constantsReplaceList = Object.assign({}, generateEnvList(projectConfig.env || {}), generateConstantsList(projectConfig.defineConstants || {}), { + 'process.env.TARO_ENV': adapter + }) +} + +export function getBuildData (): IBuildData { + return BuildData +} + +export function uglifyJS (resCode: string, filePath: string): string { + const uglifyPluginConfig = plugins.uglify || { enable: true } + if (uglifyPluginConfig.enable) { + const uglifyConfig = Object.assign(defaultUglifyConfig, uglifyPluginConfig.config || {}) + const uglifyResult = callPluginSync('uglifyjs', resCode, filePath, uglifyConfig) + if (uglifyResult.error) { + printLog(processTypeEnum.ERROR, '压缩错误', `文件${filePath}`) + console.log(uglifyResult.error) + return resCode + } + return uglifyResult.code + } + return resCode +} + +export function getDependencyTree (): Map { + return dependencyTree +} + +export function setHasBeenBuiltComponents (componentPath: string) { + hasBeenBuiltComponents.add(componentPath) +} + +export function getHasBeenBuiltComponents () { + return hasBeenBuiltComponents +} + +export function isComponentHasBeenBuilt (componentPath: string): boolean { + return hasBeenBuiltComponents.has(componentPath) +} + +export function deleteHasBeenBuiltComponent (filePath) { + if (hasBeenBuiltComponents.has(filePath)) { + hasBeenBuiltComponents.delete(filePath) + } +} + +export function setComponentExportsMap (key: string, value: IComponentObj[]) { + componentExportsMap.set(key, value) +} + +export function getComponentExportsMapItem (key: string): IComponentObj[] | void { + return componentExportsMap.get(key) +} + +export function getComponentExportsMap (): Map { + return componentExportsMap +} + +export function getComponentsBuildResult (): Map { + return componentsBuildResult +} + +export function getDepComponents (): Map { + return depComponents +} + +export function buildUsingComponents ( + filePath: string, + components: IComponentObj[], + isComponent?: boolean +): IOption { + const usingComponents = Object.create(null) + for (const component of components) { + let componentPath = component.path + if (isAliasPath(componentPath as string, pathAlias)) { + componentPath = replaceAliasPath(filePath, componentPath as string, pathAlias) + } + componentPath = resolveScriptPath(path.resolve(filePath, '..', componentPath as string)) + if (fs.existsSync(componentPath)) { + componentPath = promoteRelativePath(path.relative(filePath, componentPath)) + } else { + componentPath = component.path + } + if (component.name) { + usingComponents[component.name] = (componentPath as string).replace(path.extname(componentPath as string), '') + } + } + return Object.assign({}, isComponent ? { component: true } : { usingComponents: {} }, components.length ? { + usingComponents + } : {}) +} + +export function getRealComponentsPathList ( + filePath: string, + components: IComponentObj[] +): IComponentObj[] { + const { isProduction, buildAdapter } = BuildData + return components.map(component => { + let componentPath = component.path + if (isAliasPath(componentPath as string, pathAlias)) { + componentPath = replaceAliasPath(filePath, componentPath as string, pathAlias) + } + if (isNpmPkg(componentPath as string)) { + try { + componentPath = resolveNpmPkgMainPath(componentPath as string, isProduction, npmConfig, buildAdapter) + } catch (err) { + console.log(err) + } + } else { + componentPath = path.resolve(path.dirname(filePath), componentPath as string) + componentPath = resolveScriptPath(componentPath) + } + if (componentPath && isFileToBePage(componentPath)) { + printLog(processTypeEnum.ERROR, '组件引用', `文件${component.path}已经在 app.js 中被指定为页面,不能再作为组件来引用!`) + } + return { + path: componentPath, + name: component.name, + type: component.type + } + }) +} + +export function isFileToBePage (filePath: string): boolean { + let isPage = false + const { appConfig, sourceDir } = BuildData + const extname = path.extname(filePath) + const pages = appConfig.pages || [] + const filePathWithoutExt = filePath.replace(extname, '') + pages.forEach(page => { + if (filePathWithoutExt === path.join(sourceDir, page)) { + isPage = true + } + }) + return isPage && REG_SCRIPTS.test(extname) +} + +export function getDepStyleList ( + outputFilePath: string, + buildDepComponentsResult: IBuildResult[] +): string[] { + let depWXSSList: string[] = [] + if (buildDepComponentsResult.length) { + depWXSSList = buildDepComponentsResult.map(item => { + let wxss = item.wxss + wxss = wxss.replace(sourceDir, outputDir) + wxss = promoteRelativePath(path.relative(outputFilePath, wxss)) + return wxss + }) + } + return depWXSSList +} + +export function initCopyFiles () { + isCopyingFiles.clear() +} + +export function copyFilesFromSrcToOutput (files: string[]) { + const { nodeModulesPath, npmOutputDir } = BuildData + files.forEach(file => { + let outputFilePath + if (NODE_MODULES_REG.test(file)) { + outputFilePath = file.replace(nodeModulesPath, npmOutputDir) + } else { + outputFilePath = file.replace(sourceDir, outputDir) + } + if (isCopyingFiles.get(outputFilePath)) { + return + } + isCopyingFiles.set(outputFilePath, true) + let modifySrc = file.replace(appPath + path.sep, '') + modifySrc = modifySrc.split(path.sep).join('/') + let modifyOutput = outputFilePath.replace(appPath + path.sep, '') + modifyOutput = modifyOutput.split(path.sep).join('/') + printLog(processTypeEnum.COPY, '文件', modifyOutput) + if (!fs.existsSync(file)) { + printLog(processTypeEnum.ERROR, '文件', `${modifySrc} 不存在`) + } else { + fs.ensureDir(path.dirname(outputFilePath)) + if (file === outputFilePath) { + return + } + fs.copySync(file, outputFilePath) + } + }) +} diff --git a/packages/taro-cli/src/mini/index.ts b/packages/taro-cli/src/mini/index.ts new file mode 100644 index 000000000000..b15ed1a6ccd9 --- /dev/null +++ b/packages/taro-cli/src/mini/index.ts @@ -0,0 +1,153 @@ +import * as fs from 'fs-extra' +import * as path from 'path' + +import chalk from 'chalk' +import * as minimatch from 'minimatch' +import * as _ from 'lodash' + +import { + printLog, + getInstalledNpmPkgVersion, + getPkgVersion +} from '../util' +import { processTypeEnum, BUILD_TYPES } from '../util/constants' +import { IMiniAppBuildConfig } from '../util/types' + +import { + getBuildData, + setIsProduction, + setBuildAdapter, + setAppConfig +} from './helper' +import { ICopyOptions } from './interface' +import { copyFileSync } from './copy' +import { buildEntry } from './entry' +import { buildPages } from './page' +import { watchFiles } from './watch' + +const appPath = process.cwd() + +async function checkCliAndFrameworkVersion () { + const { buildAdapter, nodeModulesPath } = getBuildData() + const frameworkName = `@tarojs/taro-${buildAdapter}` + const frameworkVersion = getInstalledNpmPkgVersion(frameworkName, nodeModulesPath) + if (frameworkVersion) { + if (frameworkVersion !== getPkgVersion()) { + printLog(processTypeEnum.ERROR, '版本问题', `Taro CLI 与本地安装的小程序框架 ${frameworkName} 版本不一致,请确保一致`) + console.log(`Taro CLI: ${getPkgVersion()}`) + console.log(`${frameworkName}: ${frameworkVersion}`) + process.exit(1) + } + } else { + printLog(processTypeEnum.WARNING, '依赖安装', chalk.red(`项目依赖 ${frameworkName} 未安装,或安装有误!`)) + } +} + +function buildProjectConfig () { + const { buildAdapter, sourceDir, outputDir, outputDirName } = getBuildData() + let projectConfigFileName = `project.${buildAdapter}.json` + if (buildAdapter === BUILD_TYPES.WEAPP) { + projectConfigFileName = 'project.config.json' + } + let projectConfigPath = path.join(appPath, projectConfigFileName) + + if (!fs.existsSync(projectConfigPath)) { + projectConfigPath = path.join(sourceDir, projectConfigFileName) + if (!fs.existsSync(projectConfigPath)) return + } + + const origProjectConfig = fs.readJSONSync(projectConfigPath) + if (buildAdapter === BUILD_TYPES.TT) { + projectConfigFileName = 'project.config.json' + } + fs.ensureDirSync(outputDir) + fs.writeFileSync( + path.join(outputDir, projectConfigFileName), + JSON.stringify(Object.assign({}, origProjectConfig, { miniprogramRoot: './' }), null, 2) + ) + printLog(processTypeEnum.GENERATE, '工具配置', `${outputDirName}/${projectConfigFileName}`) +} + +async function buildFrameworkInfo () { + // 百度小程序编译出 .frameworkinfo 文件 + const { + buildAdapter, + outputDir, + outputDirName, + nodeModulesPath, + projectConfig + } = getBuildData() + if (buildAdapter === BUILD_TYPES.SWAN) { + const frameworkInfoFileName = '.frameworkinfo' + const frameworkName = `@tarojs/taro-${buildAdapter}` + const frameworkVersion = getInstalledNpmPkgVersion(frameworkName, nodeModulesPath) + if (frameworkVersion) { + const frameworkinfo = { + toolName: 'Taro', + toolCliVersion: getPkgVersion(), + toolFrameworkVersion: frameworkVersion, + createTime: projectConfig.date ? new Date(projectConfig.date).getTime() : Date.now() + } + fs.writeFileSync( + path.join(outputDir, frameworkInfoFileName), + JSON.stringify(frameworkinfo, null, 2) + ) + printLog(processTypeEnum.GENERATE, '框架信息', `${outputDirName}/${frameworkInfoFileName}`) + } else { + printLog(processTypeEnum.WARNING, '依赖安装', chalk.red(`项目依赖 ${frameworkName} 未安装,或安装有误!`)) + } + } +} + +function copyFiles () { + const { projectConfig } = getBuildData() + const copyConfig = projectConfig.copy || { patterns: [], options: {} } + if (copyConfig.patterns && copyConfig.patterns.length) { + copyConfig.options = copyConfig.options || {} + const globalIgnore = copyConfig.options.ignore + const projectDir = appPath + copyConfig.patterns.forEach(pattern => { + if (typeof pattern === 'object' && pattern.from && pattern.to) { + const from = path.join(projectDir, pattern.from) + const to = path.join(projectDir, pattern.to) + let ignore = pattern.ignore || globalIgnore + if (fs.existsSync(from)) { + const copyOptions: ICopyOptions = {} + if (ignore) { + ignore = Array.isArray(ignore) ? ignore : [ignore] + copyOptions.filter = src => { + let isMatch = false + ignore && ignore.forEach(iPa => { + if (minimatch(path.basename(src), iPa)) { + isMatch = true + } + }) + return !isMatch + } + } + copyFileSync(from, to, copyOptions) + } else { + printLog(processTypeEnum.ERROR, '拷贝失败', `${pattern.from} 文件不存在!`) + } + } + }) + } +} + +export async function build ({ watch, adapter = BUILD_TYPES.WEAPP, envHasBeenSet = false }: IMiniAppBuildConfig) { + process.env.TARO_ENV = adapter + if (!envHasBeenSet) { + setIsProduction(process.env.NODE_ENV === 'production' || !watch) + } + setBuildAdapter(adapter) + await checkCliAndFrameworkVersion() + buildProjectConfig() + await buildFrameworkInfo() + copyFiles() + const appConfig = await buildEntry() + setAppConfig(appConfig) + await buildPages() + if (watch) { + watchFiles() + } +} diff --git a/packages/taro-cli/src/mini/interface.ts b/packages/taro-cli/src/mini/interface.ts new file mode 100644 index 000000000000..92fac4df8d16 --- /dev/null +++ b/packages/taro-cli/src/mini/interface.ts @@ -0,0 +1,29 @@ +import { IWxTransformResult } from '../util/types' + +export interface IComponentObj { + name?: string, + path: string | null, + type?: string +} + +export interface IIsFileToBeTaroComponentReturn { + isTaroComponent: boolean, + transformResult: IWxTransformResult +} + +export interface IBuildResult { + js: string, + wxss: string, + wxml: string +} + +export interface IDependency { + style: string[], + script: string[], + json: string[], + media: string[] +} + +export interface ICopyOptions { + filter?: (src: string) => boolean +} diff --git a/packages/taro-cli/src/mini/native.ts b/packages/taro-cli/src/mini/native.ts new file mode 100644 index 000000000000..1cdf243d5a14 --- /dev/null +++ b/packages/taro-cli/src/mini/native.ts @@ -0,0 +1,106 @@ +import * as fs from 'fs-extra' +import * as path from 'path' + +import { Config as IConfig } from '@tarojs/taro' +import chalk from 'chalk' + +import { REG_WXML_IMPORT, processTypeEnum } from '../util/constants' +import { isEmptyObject, printLog, resolveScriptPath } from '../util' + +import { copyFileSync } from './copy' +import { buildDepComponents } from './component' +import { taroJsFramework } from './constants' +import { compileDepScripts } from './compileScript' +import { compileDepStyles } from './compileStyle' +import { getBuildData } from './helper' + +export function processNativeWxml ( + componentWXMLPath: string, + componentWXMLContent: string | null, + outputComponentWXMLPath: string +) { + let wxmlContent + let needCopy = true + const { sourceDir, outputDir } = getBuildData() + if (componentWXMLPath && fs.existsSync(componentWXMLPath)) { + wxmlContent = fs.readFileSync(componentWXMLPath).toString() + } else { + needCopy = false + wxmlContent = componentWXMLContent + } + const importWxmlPathList: string[] = [] + let regResult + while ((regResult = REG_WXML_IMPORT.exec(wxmlContent)) != null) { + importWxmlPathList.push(regResult[2] || regResult[3]) + } + if (importWxmlPathList.length) { + importWxmlPathList.forEach(item => { + const itemPath = path.resolve(componentWXMLPath, '..', item) + if (fs.existsSync(itemPath)) { + const outputItemPath = itemPath.replace(sourceDir, outputDir) + processNativeWxml(itemPath, null, outputItemPath) + } + }) + } + if (componentWXMLPath === outputComponentWXMLPath || !needCopy) { + return + } + copyFileSync(componentWXMLPath, outputComponentWXMLPath) +} + +export function transfromNativeComponents (configFile: string, componentConfig: IConfig) { + const { sourceDir, outputDir, outputFilesTypes } = getBuildData() + const usingComponents = componentConfig.usingComponents + if (usingComponents && !isEmptyObject(usingComponents)) { + Object.keys(usingComponents).map(async item => { + const componentPath = usingComponents[item] + if (/^plugin:\/\//.test(componentPath)) { + // 小程序 plugin + printLog(processTypeEnum.REFERENCE, '插件引用', `使用了插件 ${chalk.bold(componentPath)}`) + return + } + let componentJSPath = resolveScriptPath(path.resolve(path.dirname(configFile), componentPath)) + if (!fs.existsSync(componentJSPath)) { + componentJSPath = resolveScriptPath(path.join(sourceDir, componentPath)) + } + const componentJSONPath = componentJSPath.replace(path.extname(componentJSPath), outputFilesTypes.CONFIG) + const componentWXMLPath = componentJSPath.replace(path.extname(componentJSPath), outputFilesTypes.TEMPL) + const componentWXSSPath = componentJSPath.replace(path.extname(componentJSPath), outputFilesTypes.STYLE) + const outputComponentJSPath = componentJSPath.replace(sourceDir, outputDir).replace(path.extname(componentJSPath), outputFilesTypes.SCRIPT) + if (fs.existsSync(componentJSPath)) { + const componentJSContent = fs.readFileSync(componentJSPath).toString() + if (componentJSContent.indexOf(taroJsFramework) >= 0 && !fs.existsSync(componentWXMLPath)) { + const buildDepComponentsRes = await buildDepComponents([{ path: componentJSPath, name: item, type: 'default'}]) + return buildDepComponentsRes + } + compileDepScripts([componentJSPath]) + } else { + return printLog(processTypeEnum.ERROR, '编译错误', `原生组件文件 ${componentJSPath} 不存在!`) + } + if (fs.existsSync(componentWXMLPath)) { + const outputComponentWXMLPath = outputComponentJSPath.replace(path.extname(outputComponentJSPath), outputFilesTypes.TEMPL) + processNativeWxml(componentWXMLPath, null, outputComponentWXMLPath) + } + if (fs.existsSync(componentWXSSPath)) { + const outputComponentWXSSPath = outputComponentJSPath.replace(path.extname(outputComponentJSPath), outputFilesTypes.STYLE) + await compileDepStyles(outputComponentWXSSPath, [componentWXSSPath]) + } + if (fs.existsSync(componentJSONPath)) { + const componentJSON = require(componentJSONPath) + const outputComponentJSONPath = outputComponentJSPath.replace(path.extname(outputComponentJSPath), outputFilesTypes.CONFIG) + copyFileSync(componentJSONPath, outputComponentJSONPath) + + // 解决组件循环依赖不断编译爆栈的问题 + if (componentJSON && componentJSON.usingComponents) { + Object.keys(componentJSON.usingComponents).forEach(key => { + if (key === item) { + delete componentJSON.usingComponents[key] + } + }) + } + + transfromNativeComponents(componentJSONPath, componentJSON) + } + }) + } +} diff --git a/packages/taro-cli/src/mini/npmExact.ts b/packages/taro-cli/src/mini/npmExact.ts new file mode 100644 index 000000000000..3309c7d7cd5c --- /dev/null +++ b/packages/taro-cli/src/mini/npmExact.ts @@ -0,0 +1,69 @@ +import * as path from 'path' + +import { resolveNpmFilesPath } from '../util/resolve_npm_files' +import { INpmConfig } from '../util/types' +import { BUILD_TYPES, REG_STYLE } from '../util/constants' +import { promoteRelativePath, recursiveFindNodeModules } from '../util' + +import { NODE_MODULES } from './constants' + +interface IArgs { + npmName: string, + filePath: string, + isProduction: boolean, + npmConfig: INpmConfig, + buildAdapter: BUILD_TYPES, + npmOutputDir: string, + compileInclude: string[] +} +const appPath = process.cwd() +const notExistNpmList: Set = new Set() +const nodeModulesPath = recursiveFindNodeModules(path.join(appPath, NODE_MODULES)) + +export function getNpmOutputDir (outputDir: string, configDir: string, npmConfig: INpmConfig): string { + let npmOutputDir + if (!npmConfig.dir) { + npmOutputDir = path.join(outputDir, npmConfig.name) + } else { + npmOutputDir = path.join(path.resolve(configDir, '..', npmConfig.dir), npmConfig.name) + } + return npmOutputDir +} + +export function getExactedNpmFilePath ({ + npmName, + filePath, + isProduction, + npmConfig, + buildAdapter, + npmOutputDir, + compileInclude +}: IArgs) { + try { + const npmInfo = resolveNpmFilesPath(npmName, isProduction, npmConfig, buildAdapter, appPath, compileInclude) + const npmInfoMainPath = npmInfo.main + let outputNpmPath + if (REG_STYLE.test(npmInfoMainPath)) { + outputNpmPath = npmInfoMainPath + } else { + outputNpmPath = npmInfoMainPath.replace(nodeModulesPath, npmOutputDir) + } + if (buildAdapter === BUILD_TYPES.ALIPAY) { + outputNpmPath = outputNpmPath.replace(/@/g, '_') + } + const relativePath = path.relative(filePath, outputNpmPath) + return promoteRelativePath(relativePath) + } catch (err) { + console.log(err) + notExistNpmList.add(npmName) + return npmName + } +} + +export function getNotExistNpmList () { + return notExistNpmList +} + +export function getNodeModulesPath (): string { + return nodeModulesPath +} diff --git a/packages/taro-cli/src/mini/page.ts b/packages/taro-cli/src/mini/page.ts new file mode 100644 index 000000000000..dd0329254302 --- /dev/null +++ b/packages/taro-cli/src/mini/page.ts @@ -0,0 +1,220 @@ +import * as fs from 'fs-extra' +import * as path from 'path' + +import { Config as IConfig } from '@tarojs/taro' +import * as wxTransformer from '@tarojs/transformer-wx' +import * as _ from 'lodash' + +import { + REG_TYPESCRIPT, + processTypeEnum +} from '../util/constants' +import { + resolveScriptPath, + printLog, + isEmptyObject, + promoteRelativePath, + isDifferentArray +} from '../util' +import { IWxTransformResult } from '../util/types' + +import { IComponentObj } from './interface' +import { PARSE_AST_TYPE, NODE_MODULES_REG, taroJsFramework } from './constants' +import { copyFileSync } from './copy' +import { + getBuildData, + getRealComponentsPathList, + buildUsingComponents, + uglifyJS, + copyFilesFromSrcToOutput, + getDependencyTree, + getComponentExportsMap, + getDepComponents +} from './helper' +import { compileDepScripts, compileScriptFile } from './compileScript' +import { compileDepStyles } from './compileStyle' +import { transfromNativeComponents, processNativeWxml } from './native' +import { buildDepComponents } from './component' +import { parseAst } from './astProcess' + +// 小程序页面编译 +export async function buildSinglePage (page: string) { + const { + buildAdapter, + constantsReplaceList, + outputDir, + sourceDirName, + outputDirName, + sourceDir, + isProduction, + outputFilesTypes, + nodeModulesPath, + npmOutputDir, + jsxAttributeNameReplace + } = getBuildData() + const pagePath = path.join(sourceDir, `${page}`) + const pageJs = resolveScriptPath(pagePath) + const dependencyTree = getDependencyTree() + const depComponents = getDepComponents() + + printLog(processTypeEnum.COMPILE, '页面文件', `${sourceDirName}/${page}`) + if (!fs.existsSync(pageJs)) { + printLog(processTypeEnum.ERROR, '页面文件', `${sourceDirName}/${page} 不存在!`) + return + } + const pageJsContent = fs.readFileSync(pageJs).toString() + const outputPageJSPath = pageJs.replace(sourceDir, outputDir).replace(path.extname(pageJs), outputFilesTypes.SCRIPT) + const outputPagePath = path.dirname(outputPageJSPath) + const outputPageJSONPath = outputPageJSPath.replace(path.extname(outputPageJSPath), outputFilesTypes.CONFIG) + const outputPageWXMLPath = outputPageJSPath.replace(path.extname(outputPageJSPath), outputFilesTypes.TEMPL) + const outputPageWXSSPath = outputPageJSPath.replace(path.extname(outputPageJSPath), outputFilesTypes.STYLE) + // 判断是不是小程序原生代码页面 + const pageWXMLPath = pageJs.replace(path.extname(pageJs), outputFilesTypes.TEMPL) + if (fs.existsSync(pageWXMLPath) && pageJsContent.indexOf(taroJsFramework) < 0) { + const pageJSONPath = pageJs.replace(path.extname(pageJs), outputFilesTypes.CONFIG) + const pageWXSSPath = pageJs.replace(path.extname(pageJs), outputFilesTypes.STYLE) + if (fs.existsSync(pageJSONPath)) { + const pageJSON = require(pageJSONPath) + copyFileSync(pageJSONPath, outputPageJSONPath) + transfromNativeComponents(pageJSONPath, pageJSON) + } + compileDepScripts([pageJs]) + copyFileSync(pageWXMLPath, outputPageWXMLPath) + if (fs.existsSync(pageWXSSPath)) { + await compileDepStyles(outputPageWXSSPath, [pageWXSSPath]) + } + return + } + try { + const transformResult: IWxTransformResult = wxTransformer({ + code: pageJsContent, + sourcePath: pageJs, + outputPath: outputPageJSPath, + isRoot: true, + isTyped: REG_TYPESCRIPT.test(pageJs), + adapter: buildAdapter, + env: constantsReplaceList, + jsxAttributeNameReplace + }) + const pageDepComponents = transformResult.components + const pageWXMLContent = isProduction ? transformResult.compressedTemplate : transformResult.template + const res = parseAst(PARSE_AST_TYPE.PAGE, transformResult.ast, pageDepComponents, pageJs, outputPageJSPath) + let resCode = res.code + resCode = await compileScriptFile(resCode, pageJs, outputPageJSPath, buildAdapter) + if (isProduction) { + uglifyJS(resCode, pageJs) + } + fs.ensureDirSync(outputPagePath) + const { usingComponents = {} }: IConfig = res.configObj + if (usingComponents && !isEmptyObject(usingComponents)) { + const keys = Object.keys(usingComponents) + keys.forEach(item => { + pageDepComponents.forEach(component => { + if (_.camelCase(item) === _.camelCase(component.name)) { + delete usingComponents[item] + } + }) + }) + transfromNativeComponents(outputPageJSONPath.replace(outputDir, sourceDir), res.configObj) + } + const fileDep = dependencyTree.get(pageJs) || {} + // 编译依赖的组件文件 + let realComponentsPathList: IComponentObj[] = [] + if (pageDepComponents.length) { + realComponentsPathList = getRealComponentsPathList(pageJs, pageDepComponents) + res.scriptFiles = res.scriptFiles.map(item => { + for (let i = 0; i < realComponentsPathList.length; i++) { + const componentObj = realComponentsPathList[i] + const componentPath = componentObj.path + if (item === componentPath) { + return '' + } + } + return item + }).filter(item => item) + await buildDepComponents(realComponentsPathList) + } + const componentExportsMap = getComponentExportsMap() + if (!isEmptyObject(componentExportsMap) && realComponentsPathList.length) { + const mapKeys = Object.keys(componentExportsMap) + realComponentsPathList.forEach(component => { + if (mapKeys.indexOf(component.path as string) >= 0) { + const componentMap = componentExportsMap.get(component.path as string) + componentMap && componentMap.forEach(component => { + pageDepComponents.forEach(depComponent => { + if (depComponent.name === component.name) { + let componentPath = component.path + let realPath + if (NODE_MODULES_REG.test(componentPath as string)) { + componentPath = (componentPath as string).replace(nodeModulesPath, npmOutputDir) + realPath = promoteRelativePath(path.relative(outputPageJSPath, componentPath)) + } else { + realPath = promoteRelativePath(path.relative(pageJs, componentPath as string)) + } + depComponent.path = realPath.replace(path.extname(realPath), '') + } + }) + }) + } + }) + } + fs.writeFileSync(outputPageJSONPath, JSON.stringify(_.merge({}, buildUsingComponents(pageJs, pageDepComponents), res.configObj), null, 2)) + printLog(processTypeEnum.GENERATE, '页面配置', `${outputDirName}/${page}${outputFilesTypes.CONFIG}`) + fs.writeFileSync(outputPageJSPath, resCode) + printLog(processTypeEnum.GENERATE, '页面逻辑', `${outputDirName}/${page}${outputFilesTypes.SCRIPT}`) + fs.writeFileSync(outputPageWXMLPath, pageWXMLContent) + processNativeWxml(outputPageWXMLPath.replace(outputDir, sourceDir), pageWXMLContent, outputPageWXMLPath) + printLog(processTypeEnum.GENERATE, '页面模板', `${outputDirName}/${page}${outputFilesTypes.TEMPL}`) + // 编译依赖的脚本文件 + if (isDifferentArray(fileDep['script'], res.scriptFiles)) { + compileDepScripts(res.scriptFiles) + } + // 编译样式文件 + if (isDifferentArray(fileDep['style'], res.styleFiles) || isDifferentArray(depComponents.get(pageJs) || [], pageDepComponents)) { + printLog(processTypeEnum.GENERATE, '页面样式', `${outputDirName}/${page}${outputFilesTypes.STYLE}`) + await compileDepStyles(outputPageWXSSPath, res.styleFiles) + } + // 拷贝依赖文件 + if (isDifferentArray(fileDep['json'], res.jsonFiles)) { + copyFilesFromSrcToOutput(res.jsonFiles) + } + if (isDifferentArray(fileDep['media'], res.mediaFiles)) { + copyFilesFromSrcToOutput(res.mediaFiles) + } + depComponents.set(pageJs, pageDepComponents) + fileDep['style'] = res.styleFiles + fileDep['script'] = res.scriptFiles + fileDep['json'] = res.jsonFiles + fileDep['media'] = res.mediaFiles + dependencyTree[pageJs] = fileDep + } catch (err) { + printLog(processTypeEnum.ERROR, '页面编译', `页面${pagePath}编译失败!`) + console.log(err) + } +} + +export async function buildPages () { + printLog(processTypeEnum.COMPILE, '所有页面') + const { appConfig } = getBuildData() + // 支持分包,解析子包页面 + const pages = appConfig.pages || [] + const subPackages = appConfig.subPackages || appConfig.subpackages + if (subPackages && subPackages.length) { + subPackages.forEach(item => { + if (item.pages && item.pages.length) { + const root = item.root + item.pages.forEach(page => { + let pagePath = `${root}/${page}` + pagePath = pagePath.replace(/\/{2,}/g, '/') + if (pages.indexOf(pagePath) < 0) { + pages.push(pagePath) + } + }) + } + }) + } + const pagesPromises = pages.map(async page => { + return buildSinglePage(page) + }) + await Promise.all(pagesPromises) +} diff --git a/packages/taro-cli/src/mini/watch.ts b/packages/taro-cli/src/mini/watch.ts new file mode 100644 index 000000000000..e32ae8274901 --- /dev/null +++ b/packages/taro-cli/src/mini/watch.ts @@ -0,0 +1,203 @@ +import * as path from 'path' + +import * as chokidar from 'chokidar' +import chalk from 'chalk' + +import { + REG_TYPESCRIPT, + REG_SCRIPT, + REG_STYLE, + processTypeEnum +} from '../util/constants' +import { + printLog, + checksum +} from '../util' + +import { initCompileStyles, compileDepStyles } from './compileStyle' +import { initCompileScripts, compileDepScripts } from './compileScript' +import { + initCopyFiles, + getBuildData, + setAppConfig, + isComponentHasBeenBuilt, + deleteHasBeenBuiltComponent, + copyFilesFromSrcToOutput, + getDependencyTree, + isFileToBePage +} from './helper' +import { buildEntry } from './entry' +import { buildPages, buildSinglePage } from './page' +import { buildSingleComponent, getComponentsNamedMap } from './component' +import { isWindows, NODE_MODULES_REG } from './constants' + +export function watchFiles () { + const appPath = process.cwd() + console.log() + console.log(chalk.gray('监听文件修改中...')) + console.log() + initCompileStyles() + initCompileScripts() + initCopyFiles() + const { + sourceDir, + outputDir, + sourceDirName, + projectConfig, + outputFilesTypes, + appConfig, + nodeModulesPath, + npmOutputDir, + entryFileName, + entryFilePath + } = getBuildData() + const dependencyTree = getDependencyTree() + const watcherPaths = [path.join(sourceDir)].concat(projectConfig.watcher || []) + const watcher = chokidar.watch(watcherPaths, { + ignored: /(^|[/\\])\../, + persistent: true, + ignoreInitial: true + }) + watcher + .on('addDir', dirPath => { + console.log(dirPath) + }) + .on('add', filePath => { + console.log(filePath) + }) + .on('change', async filePath => { + const extname = path.extname(filePath) + const componentsNamedMap = getComponentsNamedMap() + // 编译JS文件 + if (REG_SCRIPT.test(extname) || REG_TYPESCRIPT.test(extname)) { + if (entryFilePath === filePath) { + printLog(processTypeEnum.MODIFY, '入口文件', `${sourceDirName}/${entryFileName}.js`) + const config = await buildEntry() + // TODO 此处待优化 + if ((checksum(JSON.stringify(config.pages)) !== checksum(JSON.stringify(appConfig.pages))) || + (checksum(JSON.stringify(config.subPackages || config.subpackages || {})) !== checksum(JSON.stringify(appConfig.subPackages || appConfig.subpackages || {})))) { + setAppConfig(config) + await buildPages() + } + } else { + const filePathWithoutExt = filePath.replace(extname, '') + if (isFileToBePage(filePath)) { // 编译页面 + filePath = filePathWithoutExt + filePath = filePath.replace(path.join(sourceDir) + path.sep, '') + filePath = filePath.split(path.sep).join('/') + printLog(processTypeEnum.MODIFY, '页面文件', `${sourceDirName}/${filePath}`) + await buildSinglePage(filePath) + } else if (isComponentHasBeenBuilt(filePath)) { // 编译组件 + let outoutShowFilePath = filePath.replace(appPath + path.sep, '') + outoutShowFilePath = outoutShowFilePath.split(path.sep).join('/') + printLog(processTypeEnum.MODIFY, '组件文件', outoutShowFilePath) + deleteHasBeenBuiltComponent(filePath) + + if (isWindows) { + await new Promise((resolve, reject) => { + setTimeout(async () => { + await buildSingleComponent(Object.assign({ + path: filePath + }, componentsNamedMap.get(filePath))) + resolve() + }, 300) + }) + } else { + await buildSingleComponent(Object.assign({ + path: filePath + }, componentsNamedMap.get(filePath))) + } + } else { + let isImported = false + for (const key in dependencyTree) { + const dependencyTreeItem = dependencyTree.get(key) + if (dependencyTreeItem) { + const scripts = dependencyTreeItem.script + if (scripts.indexOf(filePath) >= 0) { + isImported = true + } + } + } + let modifySource = filePath.replace(appPath + path.sep, '') + modifySource = modifySource.split(path.sep).join('/') + if (isImported) { + printLog(processTypeEnum.MODIFY, 'JS文件', modifySource) + compileDepScripts([filePath]) + } else { + printLog(processTypeEnum.WARNING, 'JS文件', `${modifySource} 没有被引用到,不会被编译`) + } + } + } + } else if (REG_STYLE.test(extname)) { + const includeStyleJSPath: any[] = [] + for (const key in dependencyTree) { + const styles = dependencyTree[key]['style'] || [] + styles.forEach(item => { + if (item === filePath) { + includeStyleJSPath.push({ + filePath: key, + styles + }) + } + }) + } + if (includeStyleJSPath.length) { + includeStyleJSPath.forEach(async item => { + let outputWXSSPath = item.filePath.replace(path.extname(item.filePath), outputFilesTypes.STYLE) + let modifySource = outputWXSSPath.replace(appPath + path.sep, '') + modifySource = modifySource.split(path.sep).join('/') + printLog(processTypeEnum.MODIFY, '样式文件', modifySource) + if (NODE_MODULES_REG.test(outputWXSSPath)) { + outputWXSSPath = outputWXSSPath.replace(nodeModulesPath, npmOutputDir) + } else { + outputWXSSPath = outputWXSSPath.replace(sourceDir, outputDir) + } + let modifyOutput = outputWXSSPath.replace(appPath + path.sep, '') + modifyOutput = modifyOutput.split(path.sep).join('/') + if (isWindows) { + await new Promise((resolve, reject) => { + setTimeout(async () => { + await compileDepStyles(outputWXSSPath, item.styles) + resolve() + }, 300) + }) + } else { + await compileDepStyles(outputWXSSPath, item.styles) + } + printLog(processTypeEnum.GENERATE, '样式文件', modifyOutput) + }) + } else { + let outputWXSSPath = filePath.replace(path.extname(filePath), outputFilesTypes.STYLE) + let modifySource = outputWXSSPath.replace(appPath + path.sep, '') + modifySource = modifySource.split(path.sep).join('/') + printLog(processTypeEnum.MODIFY, '样式文件', modifySource) + if (NODE_MODULES_REG.test(outputWXSSPath)) { + outputWXSSPath = outputWXSSPath.replace(nodeModulesPath, npmOutputDir) + } else { + outputWXSSPath = outputWXSSPath.replace(sourceDir, outputDir) + } + let modifyOutput = outputWXSSPath.replace(appPath + path.sep, '') + modifyOutput = modifyOutput.split(path.sep).join('/') + if (isWindows) { + await new Promise((resolve, reject) => { + setTimeout(async () => { + await compileDepStyles(outputWXSSPath, [filePath]) + resolve() + }, 300) + }) + } else { + await compileDepStyles(outputWXSSPath, [filePath]) + } + printLog(processTypeEnum.GENERATE, '样式文件', modifyOutput) + } + } else { + let modifySource = filePath.replace(appPath + path.sep, '') + modifySource = modifySource.split(path.sep).join('/') + printLog(processTypeEnum.MODIFY, '文件', modifySource) + copyFilesFromSrcToOutput([filePath]) + } + initCompileStyles() + initCompileScripts() + initCopyFiles() + }) +} diff --git a/packages/taro-cli/src/plugin.js b/packages/taro-cli/src/plugin.ts similarity index 65% rename from packages/taro-cli/src/plugin.js rename to packages/taro-cli/src/plugin.ts index b1d2491348c8..72cb873ce524 100644 --- a/packages/taro-cli/src/plugin.js +++ b/packages/taro-cli/src/plugin.ts @@ -1,64 +1,56 @@ -const fs = require('fs-extra') -const os = require('os') -const path = require('path') -const glob = require('glob') -const chalk = require('chalk') -const chokidar = require('chokidar') -const _ = require('lodash') -const Util = require('./util') -const CONFIG = require('./config') -const { - buildEntry, - buildPages, - build: buildWeapp, - buildSinglePage, +import * as fs from 'fs-extra' +import * as path from 'path' +import * as glob from 'glob' +import chalk from 'chalk' +import * as chokidar from 'chokidar' +import * as _ from 'lodash' + +import * as Util from './util' +import { + BUILD_TYPES, + REG_SCRIPT, + REG_STYLE, + REG_FONT, + REG_IMAGE, + REG_MEDIA, + REG_TYPESCRIPT, + processTypeEnum +} from './util/constants' + +import { buildEntry } from './mini/entry' +import { buildPages, buildSinglePage } from './mini/page' +import { build as buildWeapp } from './mini' +import { isWindows } from './mini/constants' +import { getRealComponentsPathList, - buildDepComponents, - buildSingleComponent, - compileDepScripts, - compileDepStyles, isFileToBePage, - getHasBeenBuiltComponents, - spliceHasBeenBuiltComponents, + isComponentHasBeenBuilt, + deleteHasBeenBuiltComponent, getDependencyTree, - getAppConfig, + getBuildData, setAppConfig, - getComponentsNamedMap, - setEnv, - resetIsBuildingScripts, - resetIsBuildingStyles -} = require('./weapp') + setIsProduction +} from './mini/helper' +import { buildDepComponents, buildSingleComponent, getComponentsNamedMap } from './mini/component' +import { compileDepScripts, initCompileScripts } from './mini/compileScript' +import { compileDepStyles, initCompileStyles } from './mini/compileStyle' -const appPath = process.cwd() const PLUGIN_ROOT = 'plugin/' const DOC_ROOT = 'doc/' const NPM_DIR = 'npm/' const PLUGIN_JSON = 'plugin.json' const PLUGIN_MOCK_JSON = 'plugin-mock.json' -const configDir = require(path.join(appPath, Util.PROJECT_CONFIG))(_.merge) -const sourceDirName = configDir.sourceRoot || CONFIG.SOURCE_DIR -const outputDirName = configDir.outputRoot || CONFIG.OUTPUT_DIR -const srcPath = path.join(appPath, sourceDirName) -const outputPath = path.join(appPath, outputDirName) -const pluginDir = path.join(srcPath, PLUGIN_ROOT) -const pluginPath = path.join(appPath, PLUGIN_ROOT) -const docDir = path.join(pluginDir, DOC_ROOT) -const docPath = path.join(appPath, DOC_ROOT) -const isWindows = os.platform() === 'win32' + let isCopyingFiles = {} -let buildAdapter = Util.BUILD_TYPES.WEAPP -let outputFilesTypes = Util.MINI_APP_FILES[buildAdapter] -const entryFilePath = Util.resolveScriptPath(path.join(srcPath, CONFIG.ENTRY)) -const entryFileName = path.basename(entryFilePath) -async function build ({ watch, platform }) { - setEnv(watch) +export async function build ({ watch, platform }) { + setIsProduction(process.env.NODE_ENV === 'production' || !watch) switch (platform) { - case Util.BUILD_TYPES.WEAPP: + case BUILD_TYPES.WEAPP: buildWxPlugin({ watch }) break - case Util.BUILD_TYPES.ALIPAY: - await buildWeapp({ watch, adapter: Util.BUILD_TYPES.ALIPAY }) + case BUILD_TYPES.ALIPAY: + await buildWeapp({ watch, adapter: BUILD_TYPES.ALIPAY }) buildAlipayPlugin() break default: @@ -78,11 +70,26 @@ function wxPluginWatchFiles () { console.log() console.log(chalk.gray('监听文件修改中...')) console.log() - resetIsBuildingScripts() - resetIsBuildingStyles() + initCompileScripts() + initCompileStyles() isCopyingFiles = {} - const watcher = chokidar.watch(srcPath, { + const { + appPath, + sourceDirName, + sourceDir, + outputDir, + outputFilesTypes, + entryFilePath, + entryFileName, + appConfig + } = getBuildData() + const pluginDir = path.join(sourceDir, PLUGIN_ROOT) + const pluginPath = path.join(appPath, PLUGIN_ROOT) + const docDir = path.join(pluginDir, DOC_ROOT) + const docPath = path.join(appPath, DOC_ROOT) + + const watcher = chokidar.watch(sourceDir, { ignored: /(^|[/\\])\../, persistent: true, ignoreInitial: true @@ -101,11 +108,11 @@ function wxPluginWatchFiles () { } else if (filePath.includes(pluginDir)) { outputFilePath = filePath.replace(pluginDir, pluginPath) } else { - outputFilePath = filePath.replace(srcPath, outputPath) + outputFilePath = filePath.replace(sourceDir, outputDir) } const extname = path.extname(filePath) - if (Util.REG_SCRIPT.test(extname) || Util.REG_TYPESCRIPT.test(extname)) { + if (REG_SCRIPT.test(extname) || REG_TYPESCRIPT.test(extname)) { const pluginJsonPath = path.join(pluginDir, PLUGIN_JSON) if (!fs.existsSync(pluginDir) || !fs.existsSync(pluginJsonPath)) { return console.log(chalk.red('缺少 plugin.json!')) @@ -115,9 +122,8 @@ function wxPluginWatchFiles () { const main = pluginJson.main || '' if (entryFilePath === filePath) { - Util.printLog(Util.pocessTypeEnum.MODIFY, '入口文件', `${sourceDirName}/${entryFileName}.js`) + Util.printLog(processTypeEnum.MODIFY, '入口文件', `${sourceDirName}/${entryFileName}.js`) const config = await buildEntry() - const appConfig = getAppConfig() // TODO 此处待优化 if ((Util.checksum(JSON.stringify(config.pages)) !== Util.checksum(JSON.stringify(appConfig.pages))) || (Util.checksum(JSON.stringify(config.subPackages || config.subpackages || {})) !== Util.checksum(JSON.stringify(appConfig.subPackages || appConfig.subpackages || {})))) { @@ -126,18 +132,15 @@ function wxPluginWatchFiles () { } } else if (isWxPluginPage(Object.values(pages), filePath) || isFileToBePage(filePath)) { filePath = filePath.replace(extname, '') - filePath = filePath.replace(path.join(srcPath) + path.sep, '') + filePath = filePath.replace(path.join(sourceDir) + path.sep, '') filePath = filePath.split(path.sep).join('/') - Util.printLog(Util.pocessTypeEnum.MODIFY, '页面文件', `${sourceDirName}/${filePath}`) + Util.printLog(processTypeEnum.MODIFY, '页面文件', `${sourceDirName}/${filePath}`) await buildSinglePage(filePath) - } else if (isWxPluginComp(getHasBeenBuiltComponents(), filePath)) { - let outoutShowFilePath = filePath.replace(appPath + path.sep, '') - outoutShowFilePath = outoutShowFilePath.split(path.sep).join('/') - Util.printLog(Util.pocessTypeEnum.MODIFY, '组件文件', outoutShowFilePath) - - const hasbeenBuiltIndex = getHasBeenBuiltComponents().indexOf(filePath) - spliceHasBeenBuiltComponents(hasbeenBuiltIndex) - + } else if (isComponentHasBeenBuilt(filePath)) { + let outputShowFilePath = filePath.replace(appPath + path.sep, '') + outputShowFilePath = outputShowFilePath.split(path.sep).join('/') + Util.printLog(processTypeEnum.MODIFY, '组件文件', outputShowFilePath) + deleteHasBeenBuiltComponent(filePath) const componentsNamedMap = getComponentsNamedMap() if (isWindows) { await new Promise((resolve, reject) => { @@ -167,15 +170,15 @@ function wxPluginWatchFiles () { modifySource = modifySource.split(path.sep).join('/') if (isImported || filePath.includes(path.join(pluginDir, main))) { - Util.printLog(Util.pocessTypeEnum.MODIFY, 'JS文件', modifySource) + Util.printLog(processTypeEnum.MODIFY, 'JS文件', modifySource) await Promise.all(compileDepScripts([filePath], true)) } else { - Util.printLog(Util.pocessTypeEnum.WARNING, 'JS文件', `${modifySource} 没有被引用到,不会被编译`) + Util.printLog(processTypeEnum.WARNING, 'JS文件', `${modifySource} 没有被引用到,不会被编译`) } } - } else if (Util.REG_STYLE.test(extname)) { + } else if (REG_STYLE.test(extname)) { const dependencyTree = getDependencyTree() - const includeStyleJSPath = [] + const includeStyleJSPath: { filePath: string, styles: any[] }[] = [] for (const key in dependencyTree) { const styles = dependencyTree[key]['style'] || [] styles.forEach(item => { @@ -190,13 +193,12 @@ function wxPluginWatchFiles () { if (includeStyleJSPath.length) { await Promise.all(includeStyleJSPath.map(async item => { - let outputWXSSPath = null - outputWXSSPath = item.filePath.replace(path.extname(item.filePath), outputFilesTypes.STYLE) + let outputWXSSPath = item.filePath.replace(path.extname(item.filePath), outputFilesTypes.STYLE) let modifySource = outputWXSSPath.replace(appPath + path.sep, '') modifySource = modifySource.split(path.sep).join('/') - Util.printLog(Util.pocessTypeEnum.MODIFY, '样式文件', modifySource) + Util.printLog(processTypeEnum.MODIFY, '样式文件', modifySource) - outputWXSSPath = outputWXSSPath.replace(srcPath, outputPath) + outputWXSSPath = outputWXSSPath.replace(sourceDir, outputDir) if (isWindows) { await new Promise((resolve, reject) => { setTimeout(async () => { @@ -210,27 +212,27 @@ function wxPluginWatchFiles () { let modifyOutput = outputWXSSPath.replace(appPath + path.sep, '') modifyOutput = modifyOutput.split(path.sep).join('/') - Util.printLog(Util.pocessTypeEnum.GENERATE, '样式文件', modifyOutput) + Util.printLog(processTypeEnum.GENERATE, '样式文件', modifyOutput) })) } else { let outputWXSSPath = filePath.replace(path.extname(filePath), outputFilesTypes.STYLE) let modifySource = outputWXSSPath.replace(appPath + path.sep, '') modifySource = modifySource.split(path.sep).join('/') - Util.printLog(Util.pocessTypeEnum.MODIFY, '样式文件', modifySource) - outputWXSSPath = outputWXSSPath.replace(srcPath, outputPath) + Util.printLog(processTypeEnum.MODIFY, '样式文件', modifySource) + outputWXSSPath = outputWXSSPath.replace(sourceDir, outputDir) if (isWindows) { await new Promise((resolve, reject) => { setTimeout(async () => { - await compileDepStyles(outputWXSSPath, [filePath], false) + await compileDepStyles(outputWXSSPath, [filePath]) resolve() }, 300) }) } else { - await compileDepStyles(outputWXSSPath, [filePath], false) + await compileDepStyles(outputWXSSPath, [filePath]) } let modifyOutput = outputWXSSPath.replace(appPath + path.sep, '') modifyOutput = modifyOutput.split(path.sep).join('/') - Util.printLog(Util.pocessTypeEnum.GENERATE, '样式文件', modifyOutput) + Util.printLog(processTypeEnum.GENERATE, '样式文件', modifyOutput) } } else { if (isCopyingFiles[outputFilePath]) return @@ -238,12 +240,12 @@ function wxPluginWatchFiles () { let modifyOutput = outputFilePath.replace(appPath + path.sep, '') modifyOutput = modifyOutput.split(path.sep).join('/') - Util.printLog(Util.pocessTypeEnum.COPY, '文件', modifyOutput) + Util.printLog(processTypeEnum.COPY, '文件', modifyOutput) if (!fs.existsSync(filePath)) { let modifySrc = filePath.replace(appPath + path.sep, '') modifySrc = modifySrc.split(path.sep).join('/') - Util.printLog(Util.pocessTypeEnum.ERROR, '文件', `${modifySrc} 不存在`) + Util.printLog(processTypeEnum.ERROR, '文件', `${modifySrc} 不存在`) } else { fs.ensureDir(path.dirname(outputFilePath)) if (filePath === outputFilePath) { @@ -256,12 +258,11 @@ function wxPluginWatchFiles () { // 如果 output/plugin 里有新编译出的文件, // 先把 js 里对 npm 的引用修改,然后把所有文件迁移到插件目录 // 最后删除 output/plugin - const names = glob.sync(`${outputPath}/${PLUGIN_ROOT}/**/*`) + const names = glob.sync(`${outputDir}/${PLUGIN_ROOT}/**/*`) if (names.length) { - const jsNames = glob.sync(`${outputPath}/${PLUGIN_ROOT}/{,!(npm)/**/}*.js`) + const jsNames = glob.sync(`${outputDir}/${PLUGIN_ROOT}/{,!(npm)/**/}*.js`) const ioPromises = jsNames.map(async name => { - let content = await fs.readFile(name) - content = content.toString() + const content = fs.readFileSync(name).toString() let isShouldBeWritten let replacement = content.replace(/['|"]((\.\.\/)+)npm\/.+?['|"]/g, (str, $1) => { @@ -271,7 +272,7 @@ function wxPluginWatchFiles () { const REG_PLUGIN_DEPS = RegExp(`['|"](/${PLUGIN_ROOT}.+)['|"]`, 'g') replacement = replacement.replace(REG_PLUGIN_DEPS, (str, $1) => { - if (Util.REG_FONT.test($1) || Util.REG_IMAGE.test($1) || Util.REG_MEDIA.test($1)) { + if (REG_FONT.test($1) || REG_IMAGE.test($1) || REG_MEDIA.test($1)) { return str.replace(RegExp(`^['|"]/${PLUGIN_ROOT}`, 'g'), str => str.replace(`${PLUGIN_ROOT}`, '')) } return str @@ -283,22 +284,22 @@ function wxPluginWatchFiles () { await Promise.all(names.map(async from => { if (fs.existsSync(from) && fs.statSync(from).isFile()) { - const to = from.replace(outputPath, appPath) + const to = from.replace(outputDir, appPath) fs.ensureDirSync(path.dirname(to)) await fs.copyFile(from, to) } })) - const tempPluginPath = path.join(outputPath, PLUGIN_ROOT) + const tempPluginPath = path.join(outputDir, PLUGIN_ROOT) Util.emptyDirectory(tempPluginPath) fs.rmdirSync(tempPluginPath) } // 迁移 npm 到 plugin 目录 Util.emptyDirectory(path.join(pluginPath, NPM_DIR)) // fs.rmdirSync(tempPluginPath) - fs.copySync(path.join(outputPath, NPM_DIR), path.join(pluginPath, NPM_DIR)) + fs.copySync(path.join(outputDir, NPM_DIR), path.join(pluginPath, NPM_DIR)) - resetIsBuildingScripts() - resetIsBuildingStyles() + initCompileScripts() + initCompileStyles() isCopyingFiles = {} }) } @@ -307,15 +308,21 @@ function isWxPluginPage (pages, filePath) { return pages.findIndex(page => filePath.includes(page)) >= 0 } -function isWxPluginComp (components, filePath) { - return components.indexOf(filePath) >= 0 -} - async function buildWxPlugin ({ watch }) { + const { + appPath, + sourceDir, + outputDir + } = getBuildData() + const pluginDir = path.join(sourceDir, PLUGIN_ROOT) + const pluginPath = path.join(appPath, PLUGIN_ROOT) + const docDir = path.join(pluginDir, DOC_ROOT) + const docPath = path.join(appPath, DOC_ROOT) + fs.existsSync(pluginPath) && Util.emptyDirectory(pluginPath) fs.existsSync(docPath) && Util.emptyDirectory(docPath) // 编译调试项目 - await buildWeapp({ adapter: Util.BUILD_TYPES.WEAPP, envHasBeenSet: true }) + await buildWeapp({ adapter: BUILD_TYPES.WEAPP, envHasBeenSet: true }) const pluginJsonPath = path.join(pluginDir, PLUGIN_JSON) if (!fs.existsSync(pluginDir) || !fs.existsSync(pluginJsonPath)) { @@ -323,21 +330,21 @@ async function buildWxPlugin ({ watch }) { } const pluginJson = fs.readJSONSync(pluginJsonPath) const components = pluginJson.publicComponents - const pages = pluginJson.pages + const pages: { [key: string]: any } = pluginJson.pages const main = pluginJson.main // 编译插件页面 if (pages && Object.keys(pages).length) { - Util.printLog(Util.pocessTypeEnum.COMPILE, '插件页面') + Util.printLog(processTypeEnum.COMPILE, '插件页面') const pagesPromises = Object.values(pages).map(page => buildSinglePage(path.join(PLUGIN_ROOT, page))) await Promise.all(pagesPromises) } // 编译插件组件 if (components && Object.keys(components).length) { - Util.printLog(Util.pocessTypeEnum.COMPILE, '插件组件') - const componentList = [] - for (let component in components) { + Util.printLog(processTypeEnum.COMPILE, '插件组件') + const componentList: any[] = [] + for (const component in components) { const componentPath = components[component] componentList.push({ path: /^(\.|\/)/.test(componentPath) ? componentPath : '.' + path.sep + componentPath, @@ -351,14 +358,14 @@ async function buildWxPlugin ({ watch }) { // 编译插件 main.js if (main) { - Util.printLog(Util.pocessTypeEnum.COMPILE, '插件 JS') + Util.printLog(processTypeEnum.COMPILE, '插件 JS') await Promise.all(compileDepScripts([path.join(pluginDir, main)], true)) } // 把 plugin 目录挪到根目录 - fs.moveSync(path.join(outputPath, PLUGIN_ROOT), pluginPath) + fs.moveSync(path.join(outputDir, PLUGIN_ROOT), pluginPath) // 把 npm 拷贝一份到 plugin 目录 - fs.copySync(path.join(outputPath, NPM_DIR), path.join(pluginPath, NPM_DIR)) + fs.copySync(path.join(outputDir, NPM_DIR), path.join(pluginPath, NPM_DIR)) // 把 doc 目录拷贝到根目录 fs.existsSync(docDir) && fs.copySync(docDir, docPath) // 拷贝 plugin.json @@ -366,9 +373,8 @@ async function buildWxPlugin ({ watch }) { // plugin 文件夹内对 npm 的引用路径修改 const names = glob.sync('plugin/{,!(npm)/**/}*.js') - const ioPromises = names.map(async name => { - let content = await fs.readFile(name) - content = content.toString() + const ioPromises = names.map(name => { + const content = fs.readFileSync(name).toString() let isShouldBeWritten let replacement = content.replace(/['|"]((\.\.\/)+)npm\/.+?['|"]/g, (str, $1) => { @@ -378,13 +384,13 @@ async function buildWxPlugin ({ watch }) { const REG_PLUGIN_DEPS = RegExp(`['|"](/${PLUGIN_ROOT}.+)['|"]`, 'g') replacement = replacement.replace(REG_PLUGIN_DEPS, (str, $1) => { - if (Util.REG_FONT.test($1) || Util.REG_IMAGE.test($1) || Util.REG_MEDIA.test($1)) { + if (REG_FONT.test($1) || REG_IMAGE.test($1) || REG_MEDIA.test($1)) { return str.replace(RegExp(`^['|"]/${PLUGIN_ROOT}`, 'g'), str => str.replace(`${PLUGIN_ROOT}`, '')) } return str }) - if (isShouldBeWritten) await fs.writeFile(path.join(appPath, name), replacement) + if (isShouldBeWritten) fs.writeFileSync(path.join(appPath, name), replacement) }) await Promise.all(ioPromises) @@ -392,16 +398,17 @@ async function buildWxPlugin ({ watch }) { } function buildAlipayPlugin () { - const pluginJson = path.join(srcPath, PLUGIN_JSON) - const pluginMockJson = path.join(srcPath, PLUGIN_MOCK_JSON) + const { + sourceDir, + outputDir + } = getBuildData() + const pluginJson = path.join(sourceDir, PLUGIN_JSON) + const pluginMockJson = path.join(sourceDir, PLUGIN_MOCK_JSON) + if (fs.existsSync(pluginJson)) { - fs.copyFileSync(pluginJson, path.join(outputPath, PLUGIN_JSON)) + fs.copyFileSync(pluginJson, path.join(outputDir, PLUGIN_JSON)) } if (fs.existsSync(pluginMockJson)) { - fs.copyFileSync(pluginMockJson, path.join(outputPath, PLUGIN_MOCK_JSON)) + fs.copyFileSync(pluginMockJson, path.join(outputDir, PLUGIN_MOCK_JSON)) } } - -module.exports = { - build -} diff --git a/packages/taro-cli/src/project.js b/packages/taro-cli/src/project.ts similarity index 84% rename from packages/taro-cli/src/project.js rename to packages/taro-cli/src/project.ts index 3a1cbd039ddc..68590b5377af 100644 --- a/packages/taro-cli/src/project.js +++ b/packages/taro-cli/src/project.ts @@ -1,20 +1,33 @@ -const path = require('path') -const fs = require('fs-extra') -const chalk = require('chalk') -const inquirer = require('inquirer') -const semver = require('semver') +import * as path from 'path' +import * as fs from 'fs-extra' +import chalk from 'chalk' +import * as inquirer from 'inquirer' +import * as semver from 'semver' -const Creator = require('./creator') +import Creator from './creator' -const { +import { shouldUseYarn, shouldUseCnpm, getPkgVersion -} = require('./util') -const { SOURCE_DIR } = require('./config') +} from './util' +import CONFIG from './config' + +interface IProjectConf { + projectName: string, + template: 'default' | 'mobx' | 'redux', + description?: string, + typescript?: boolean, + css: 'none' | 'sass' | 'stylus' | 'less', + date?: string, + src?: string +} + +export default class Project extends Creator { + public rootPath: string + public conf: IProjectConf -class Project extends Creator { - constructor (options) { + constructor (options: IProjectConf) { super() const unSupportedVer = semver.lt(process.version, 'v7.6.0') if (unSupportedVer) { @@ -23,8 +36,8 @@ class Project extends Creator { this.rootPath = this._rootPath this.conf = Object.assign({ - projectName: null, - template: null, + projectName: '', + template: '', description: '' }, options) } @@ -46,7 +59,7 @@ class Project extends Creator { } ask () { - const prompts = [] + const prompts: object[] = [] const conf = this.conf if (typeof conf.projectName !== 'string') { prompts.push({ @@ -164,9 +177,9 @@ class Project extends Creator { return inquirer.prompt(prompts) } - write (cb) { + write (cb?: () => void) { const { template } = this.conf - this.conf.src = SOURCE_DIR + this.conf.src = CONFIG.SOURCE_DIR const templateCreate = require(path.join(this.templatePath(), template, 'index.js')) templateCreate(this, this.conf, { shouldUseYarn, @@ -175,5 +188,3 @@ class Project extends Creator { }, cb) } } - -module.exports = Project diff --git a/packages/taro-cli/src/rn.js b/packages/taro-cli/src/rn.ts similarity index 76% rename from packages/taro-cli/src/rn.js rename to packages/taro-cli/src/rn.ts index 3210ba7bbd28..7729c954f34e 100644 --- a/packages/taro-cli/src/rn.js +++ b/packages/taro-cli/src/rn.ts @@ -1,24 +1,23 @@ -const fs = require('fs-extra') -const path = require('path') -const {performance} = require('perf_hooks') -const chokidar = require('chokidar') -const chalk = require('chalk') -const ejs = require('ejs') -const _ = require('lodash') -const shelljs = require('shelljs') -const klaw = require('klaw') +import * as fs from 'fs-extra' +import * as path from 'path' +import child_process, { execSync, SpawnSyncOptions } from 'child_process' +import { performance } from 'perf_hooks' +import * as chokidar from 'chokidar' +import chalk from 'chalk' +import * as ejs from 'ejs' +import * as _ from 'lodash' +import * as shelljs from 'shelljs' +import * as klaw from 'klaw' -const Util = require('./util') -const child_process = require('child_process') // eslint-disable-line -const execSync = require('child_process').execSync -const CONFIG = require('./config') -const {getPkgVersion} = require('./util') -const StyleProcess = require('./rn/styleProcess') -const {transformJSCode} = require('./rn/transformJS') -const {convertToJDReact} = require('./jdreact/convert_to_jdreact') +import * as Util from './util' +import CONFIG from './config' +import * as StyleProcess from './rn/styleProcess' +import { parseJSCode as transformJSCode } from './rn/transformJS' +import { PROJECT_CONFIG, processTypeEnum, REG_STYLE, REG_SCRIPTS, REG_TYPESCRIPT, BUILD_TYPES } from './util/constants' +import { convertToJDReact } from './jdreact/convert_to_jdreact' const appPath = process.cwd() -const projectConfig = require(path.join(appPath, Util.PROJECT_CONFIG))(_.merge) +const projectConfig = require(path.join(appPath, PROJECT_CONFIG))(_.merge) const sourceDirName = projectConfig.sourceRoot || CONFIG.SOURCE_DIR const sourceDir = path.join(appPath, sourceDirName) const tempDir = '.rn_temp' @@ -32,7 +31,9 @@ const rnConfig = projectConfig.rn || {} const pkgPath = path.join(__dirname, './rn/pkg') -let depTree = {} +const depTree: { + [key: string]: string[] +} = {} let isBuildingStyles = {} const styleDenpendencyTree = {} @@ -49,16 +50,16 @@ function compileDepStyles (filePath, styleFiles) { return Promise.all(styleFiles.map(async p => { // to css string const filePath = path.join(p) const fileExt = path.extname(filePath) - Util.printLog(Util.pocessTypeEnum.COMPILE, _.camelCase(fileExt).toUpperCase(), filePath) + Util.printLog(processTypeEnum.COMPILE, _.camelCase(fileExt).toUpperCase(), filePath) return StyleProcess.loadStyle({filePath, pluginsConfig}) })).then(resList => { // postcss return Promise.all(resList.map(item => { - return StyleProcess.postCSS({...item, projectConfig}) + return StyleProcess.postCSS({ ...item as { css: string, filePath: string }, projectConfig }) })) }).then(resList => { - let styleObjectEntire = {} + const styleObjectEntire = {} resList.forEach(item => { - let styleObject = StyleProcess.getStyleObject({css: item.css, filePath: item.filePath}) + const styleObject = StyleProcess.getStyleObject({css: item.css, filePath: item.filePath}) // validate styleObject StyleProcess.validateStyle({styleObject, filePath: item.filePath}) @@ -93,7 +94,7 @@ function initProjectFile () { ejs.render( fs.readFileSync(pkgPath, 'utf-8'), { projectName: _.camelCase(projectConfig.projectName), - version: getPkgVersion() + version: Util.getPkgVersion() } ).replace(/(\r\n|\n|\r|\s+)/gm, '') ) @@ -108,11 +109,11 @@ function initProjectFile () { AppRegistry.registerComponent(appName, () => App);` fs.writeFileSync(path.join(tempDir, 'index.js'), indexJsStr) - Util.printLog(Util.pocessTypeEnum.GENERATE, 'index.js', path.join(tempPath, 'index.js')) + Util.printLog(processTypeEnum.GENERATE, 'index.js', path.join(tempPath, 'index.js')) fs.writeFileSync(path.join(tempDir, 'app.json'), JSON.stringify(appJsonObject, null, 2)) - Util.printLog(Util.pocessTypeEnum.GENERATE, 'app.json', path.join(tempPath, 'app.json')) + Util.printLog(processTypeEnum.GENERATE, 'app.json', path.join(tempPath, 'app.json')) fs.writeFileSync(path.join(tempDir, 'package.json'), JSON.stringify(pkgTempObj, null, 2)) - Util.printLog(Util.pocessTypeEnum.GENERATE, 'package.json', path.join(tempPath, 'package.json')) + Util.printLog(processTypeEnum.GENERATE, 'package.json', path.join(tempPath, 'package.json')) } async function processFile (filePath) { @@ -123,15 +124,15 @@ async function processFile (filePath) { const distDirname = dirname.replace(sourceDir, tempDir) let distPath = path.format({dir: distDirname, base: path.basename(filePath)}) const code = fs.readFileSync(filePath, 'utf-8') - if (Util.REG_STYLE.test(filePath)) { + if (REG_STYLE.test(filePath)) { // do something - } else if (Util.REG_SCRIPTS.test(filePath)) { - if (Util.REG_TYPESCRIPT.test(filePath)) { + } else if (REG_SCRIPTS.test(filePath)) { + if (REG_TYPESCRIPT.test(filePath)) { distPath = distPath.replace(/\.(tsx|ts)(\?.*)?$/, '.js') } - Util.printLog(Util.pocessTypeEnum.COMPILE, _.camelCase(path.extname(filePath)).toUpperCase(), filePath) + Util.printLog(processTypeEnum.COMPILE, _.camelCase(path.extname(filePath)).toUpperCase(), filePath) // transformJSCode - let transformResult = transformJSCode({code, filePath, isEntryFile: isEntryFile(filePath), projectConfig}) + const transformResult = transformJSCode({code, filePath, isEntryFile: isEntryFile(filePath), projectConfig}) const jsCode = transformResult.code fs.ensureDirSync(distDirname) fs.writeFileSync(distPath, Buffer.from(jsCode)) @@ -142,7 +143,7 @@ async function processFile (filePath) { } else { fs.ensureDirSync(distDirname) fs.copySync(filePath, distPath) - Util.printLog(Util.pocessTypeEnum.COPY, _.camelCase(path.extname(filePath)).toUpperCase(), filePath) + Util.printLog(processTypeEnum.COPY, _.camelCase(path.extname(filePath)).toUpperCase(), filePath) } } @@ -198,13 +199,13 @@ function buildBundle () { {stdio: 'inherit'}) } -async function perfWrap (callback, args) { +async function perfWrap (callback, args?) { isBuildingStyles = {} // 清空 // 后期可以优化,不编译全部 - let t0 = performance.now() + const t0 = performance.now() await callback(args) - let t1 = performance.now() - Util.printLog(Util.pocessTypeEnum.COMPILE, `编译完成,花费${Math.round(t1 - t0)} ms`) + const t1 = performance.now() + Util.printLog(processTypeEnum.COMPILE, `编译完成,花费${Math.round(t1 - t0)} ms`) } function watchFiles () { @@ -222,16 +223,16 @@ function watchFiles () { }) .on('add', filePath => { const relativePath = path.relative(appPath, filePath) - Util.printLog(Util.pocessTypeEnum.CREATE, '添加文件', relativePath) + Util.printLog(processTypeEnum.CREATE, '添加文件', relativePath) perfWrap(buildTemp) }) .on('change', filePath => { const relativePath = path.relative(appPath, filePath) - Util.printLog(Util.pocessTypeEnum.MODIFY, '文件变动', relativePath) - if (Util.REG_SCRIPTS.test(filePath)) { + Util.printLog(processTypeEnum.MODIFY, '文件变动', relativePath) + if (REG_SCRIPTS.test(filePath)) { perfWrap(processFile, filePath) } - if (Util.REG_STYLE.test(filePath)) { + if (REG_STYLE.test(filePath)) { _.forIn(depTree, (styleFiles, jsFilePath) => { if (styleFiles.indexOf(filePath) > -1) { perfWrap(processFile, jsFilePath) @@ -241,19 +242,19 @@ function watchFiles () { }) .on('unlink', filePath => { const relativePath = path.relative(appPath, filePath) - Util.printLog(Util.pocessTypeEnum.UNLINK, '删除文件', relativePath) + Util.printLog(processTypeEnum.UNLINK, '删除文件', relativePath) perfWrap(buildTemp) }) .on('error', error => console.log(`Watcher error: ${error}`)) } -async function build ({watch}) { - process.env.TARO_ENV = Util.BUILD_TYPES.RN +export async function build ({watch}) { + process.env.TARO_ENV = BUILD_TYPES.RN fs.ensureDirSync(tempPath) - let t0 = performance.now() + const t0 = performance.now() await buildTemp() - let t1 = performance.now() - Util.printLog(Util.pocessTypeEnum.COMPILE, `编译完成,花费${Math.round(t1 - t0)} ms`) + const t1 = performance.now() + Util.printLog(processTypeEnum.COMPILE, `编译完成,花费${Math.round(t1 - t0)} ms`) if (watch) { watchFiles() @@ -281,7 +282,7 @@ function startServerInNewWindow (port = 8081) { // set up the launchpackager.(command|bat) file const scriptsDir = path.resolve(tempPath, './node_modules', 'react-native', 'scripts') const launchPackagerScript = path.resolve(scriptsDir, scriptFile) - const procConfig = {cwd: scriptsDir} + const procConfig: SpawnSyncOptions = { cwd: scriptsDir } const terminal = process.env.REACT_TERMINAL // set up the .packager.(env|bat) file to ensure the packager starts on the right port @@ -309,7 +310,6 @@ function startServerInNewWindow (port = 8081) { } return child_process.spawnSync('open', [launchPackagerScript], procConfig) } else if (process.platform === 'linux') { - procConfig.detached = true if (terminal) { return child_process.spawn( terminal, @@ -319,7 +319,6 @@ function startServerInNewWindow (port = 8081) { } return child_process.spawn('sh', [launchPackagerScript], procConfig) } else if (/^win/.test(process.platform)) { - procConfig.detached = true procConfig.stdio = 'ignore' return child_process.spawn( 'cmd.exe', @@ -334,5 +333,3 @@ function startServerInNewWindow (port = 8081) { ) } } - -module.exports = {build} diff --git a/packages/taro-cli/src/rn/StyleSheet/ColorPropType.js b/packages/taro-cli/src/rn/StyleSheet/ColorPropType.ts similarity index 95% rename from packages/taro-cli/src/rn/StyleSheet/ColorPropType.js rename to packages/taro-cli/src/rn/StyleSheet/ColorPropType.ts index 3fecbc400131..c708dbe8c7b7 100644 --- a/packages/taro-cli/src/rn/StyleSheet/ColorPropType.js +++ b/packages/taro-cli/src/rn/StyleSheet/ColorPropType.ts @@ -9,7 +9,7 @@ 'use strict' -const normalizeColor = require('./normalizeColor') +import normalizeColor from './normalizeColor' const colorPropType = function ( isRequired, @@ -73,4 +73,4 @@ const colorPropType = function ( const ColorPropType = colorPropType.bind(null, false /* isRequired */) ColorPropType.isRequired = colorPropType.bind(null, true /* isRequired */) -module.exports = ColorPropType +export default ColorPropType diff --git a/packages/taro-cli/src/rn/StyleSheet/ImageResizeMode.js b/packages/taro-cli/src/rn/StyleSheet/ImageResizeMode.ts similarity index 93% rename from packages/taro-cli/src/rn/StyleSheet/ImageResizeMode.js rename to packages/taro-cli/src/rn/StyleSheet/ImageResizeMode.ts index 50111bcd0fe7..8281f9a598fa 100644 --- a/packages/taro-cli/src/rn/StyleSheet/ImageResizeMode.js +++ b/packages/taro-cli/src/rn/StyleSheet/ImageResizeMode.ts @@ -7,12 +7,10 @@ * * @format */ -'use strict' - /* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error * found when Flow v0.54 was deployed. To see the error delete this comment and * run Flow. */ -const keyMirror = require('fbjs/lib/keyMirror') +import keyMirror from 'fbjs/lib/keyMirror' /** * ImageResizeMode - Enum for different image resizing modes, set via @@ -49,4 +47,4 @@ const ImageResizeMode = keyMirror({ repeat: null }) -module.exports = ImageResizeMode +export default ImageResizeMode diff --git a/packages/taro-cli/src/rn/StyleSheet/ImageStylePropTypes.js b/packages/taro-cli/src/rn/StyleSheet/ImageStylePropTypes.ts similarity index 82% rename from packages/taro-cli/src/rn/StyleSheet/ImageStylePropTypes.js rename to packages/taro-cli/src/rn/StyleSheet/ImageStylePropTypes.ts index 4f687539c583..037b289a5c03 100644 --- a/packages/taro-cli/src/rn/StyleSheet/ImageStylePropTypes.js +++ b/packages/taro-cli/src/rn/StyleSheet/ImageStylePropTypes.ts @@ -9,12 +9,12 @@ */ 'use strict' -const ColorPropType = require('./ColorPropType') -const ImageResizeMode = require('./ImageResizeMode') -const LayoutPropTypes = require('./LayoutPropTypes') -const ReactPropTypes = require('prop-types') -const ShadowPropTypesIOS = require('./ShadowPropTypesIOS') -const TransformPropTypes = require('./TransformPropTypes') +import ColorPropType from './ColorPropType' +import ImageResizeMode from './ImageResizeMode' +import LayoutPropTypes from './LayoutPropTypes' +import ReactPropTypes from 'prop-types' +import ShadowPropTypesIOS from './ShadowPropTypesIOS' +import TransformPropTypes from './TransformPropTypes' const ImageStylePropTypes = { ...LayoutPropTypes, @@ -59,4 +59,4 @@ const ImageStylePropTypes = { borderBottomRightRadius: ReactPropTypes.number } -module.exports = ImageStylePropTypes +export default ImageStylePropTypes diff --git a/packages/taro-cli/src/rn/StyleSheet/LayoutPropTypes.js b/packages/taro-cli/src/rn/StyleSheet/LayoutPropTypes.ts similarity index 99% rename from packages/taro-cli/src/rn/StyleSheet/LayoutPropTypes.js rename to packages/taro-cli/src/rn/StyleSheet/LayoutPropTypes.ts index c6192548f6fc..f8c11129e436 100644 --- a/packages/taro-cli/src/rn/StyleSheet/LayoutPropTypes.js +++ b/packages/taro-cli/src/rn/StyleSheet/LayoutPropTypes.ts @@ -8,9 +8,7 @@ * strict */ -'use strict' - -const ReactPropTypes = require('prop-types') +import ReactPropTypes from 'prop-types' /** * React Native's layout system is based on Flexbox and is powered both @@ -558,4 +556,4 @@ const LayoutPropTypes = { direction: ReactPropTypes.oneOf(['inherit', 'ltr', 'rtl']) } -module.exports = LayoutPropTypes +export default LayoutPropTypes diff --git a/packages/taro-cli/src/rn/StyleSheet/ShadowPropTypesIOS.js b/packages/taro-cli/src/rn/StyleSheet/ShadowPropTypesIOS.ts similarity index 89% rename from packages/taro-cli/src/rn/StyleSheet/ShadowPropTypesIOS.js rename to packages/taro-cli/src/rn/StyleSheet/ShadowPropTypesIOS.ts index 538e2c5f6bee..32484e80eb0e 100644 --- a/packages/taro-cli/src/rn/StyleSheet/ShadowPropTypesIOS.js +++ b/packages/taro-cli/src/rn/StyleSheet/ShadowPropTypesIOS.ts @@ -7,10 +7,8 @@ * * @format */ -'use strict' - -const ColorPropType = require('./ColorPropType') -const ReactPropTypes = require('prop-types') +import ColorPropType from './ColorPropType' +import ReactPropTypes from 'prop-types' /** * These props can be used to dynamically generate shadows on views, images, text, etc. @@ -47,4 +45,4 @@ const ShadowPropTypesIOS = { shadowRadius: ReactPropTypes.number } -module.exports = ShadowPropTypesIOS +export default ShadowPropTypesIOS diff --git a/packages/taro-cli/src/rn/StyleSheet/StyleSheetValidation.js b/packages/taro-cli/src/rn/StyleSheet/StyleSheetValidation.ts similarity index 85% rename from packages/taro-cli/src/rn/StyleSheet/StyleSheetValidation.js rename to packages/taro-cli/src/rn/StyleSheet/StyleSheetValidation.ts index 9f3ae833d1fc..7db4c219cc7f 100644 --- a/packages/taro-cli/src/rn/StyleSheet/StyleSheetValidation.js +++ b/packages/taro-cli/src/rn/StyleSheet/StyleSheetValidation.ts @@ -8,13 +8,11 @@ * */ -'use strict' +import ImageStylePropTypes from './ImageStylePropTypes' +import TextStylePropTypes from './TextStylePropTypes' +import ViewStylePropTypes from './ViewStylePropTypes' -const ImageStylePropTypes = require('./ImageStylePropTypes') -const TextStylePropTypes = require('./TextStylePropTypes') -const ViewStylePropTypes = require('./ViewStylePropTypes') - -const invariant = require('fbjs/lib/invariant') +import invariant from 'fbjs/lib/invariant' // Hardcoded because this is a legit case but we don't want to load it from // a private API. We might likely want to unify style sheet creation with how it @@ -62,7 +60,7 @@ class StyleSheetValidation { } } -const styleError = function (message1, style, caller, message2) { +const styleError = function (message1, style, caller, message2?) { invariant( false, message1 + @@ -80,4 +78,4 @@ StyleSheetValidation.addValidStylePropTypes(ImageStylePropTypes) StyleSheetValidation.addValidStylePropTypes(TextStylePropTypes) StyleSheetValidation.addValidStylePropTypes(ViewStylePropTypes) -module.exports = StyleSheetValidation +export default StyleSheetValidation diff --git a/packages/taro-cli/src/rn/StyleSheet/TextStylePropTypes.js b/packages/taro-cli/src/rn/StyleSheet/TextStylePropTypes.ts similarity index 93% rename from packages/taro-cli/src/rn/StyleSheet/TextStylePropTypes.js rename to packages/taro-cli/src/rn/StyleSheet/TextStylePropTypes.ts index 1935170cf67f..816a6130e575 100644 --- a/packages/taro-cli/src/rn/StyleSheet/TextStylePropTypes.js +++ b/packages/taro-cli/src/rn/StyleSheet/TextStylePropTypes.ts @@ -10,9 +10,9 @@ 'use strict' -const ColorPropType = require('./ColorPropType') -const ReactPropTypes = require('prop-types') -const ViewStylePropTypes = require('./ViewStylePropTypes') +import ColorPropType from './ColorPropType' +import ReactPropTypes from 'prop-types' +import ViewStylePropTypes from './ViewStylePropTypes' const TextStylePropTypes = { ...ViewStylePropTypes, @@ -120,4 +120,4 @@ const TextStylePropTypes = { writingDirection: ReactPropTypes.oneOf(['auto' /* default */, 'ltr', 'rtl']) } -module.exports = TextStylePropTypes +export default TextStylePropTypes diff --git a/packages/taro-cli/src/rn/StyleSheet/TransformPropTypes.js b/packages/taro-cli/src/rn/StyleSheet/TransformPropTypes.ts similarity index 95% rename from packages/taro-cli/src/rn/StyleSheet/TransformPropTypes.js rename to packages/taro-cli/src/rn/StyleSheet/TransformPropTypes.ts index 21f612aefbbe..7d2f5ac56522 100644 --- a/packages/taro-cli/src/rn/StyleSheet/TransformPropTypes.js +++ b/packages/taro-cli/src/rn/StyleSheet/TransformPropTypes.ts @@ -10,9 +10,9 @@ 'use strict' -const ReactPropTypes = require('prop-types') +import ReactPropTypes from 'prop-types' -const deprecatedPropType = require('./deprecatedPropType') +import deprecatedPropType from './deprecatedPropType' const TransformMatrixPropType = function ( props, @@ -106,4 +106,4 @@ const TransformPropTypes = { ) } -module.exports = TransformPropTypes +export default TransformPropTypes diff --git a/packages/taro-cli/src/rn/StyleSheet/ViewStylePropTypes.js b/packages/taro-cli/src/rn/StyleSheet/ViewStylePropTypes.ts similarity index 86% rename from packages/taro-cli/src/rn/StyleSheet/ViewStylePropTypes.js rename to packages/taro-cli/src/rn/StyleSheet/ViewStylePropTypes.ts index 889c5074023b..ae8e237c5a62 100644 --- a/packages/taro-cli/src/rn/StyleSheet/ViewStylePropTypes.js +++ b/packages/taro-cli/src/rn/StyleSheet/ViewStylePropTypes.ts @@ -10,11 +10,11 @@ 'use strict' -const ColorPropType = require('./ColorPropType') -const LayoutPropTypes = require('./LayoutPropTypes') -const ReactPropTypes = require('prop-types') -const ShadowPropTypesIOS = require('./ShadowPropTypesIOS') -const TransformPropTypes = require('./TransformPropTypes') +import ColorPropType from './ColorPropType' +import LayoutPropTypes from './LayoutPropTypes' +import ReactPropTypes from 'prop-types' +import ShadowPropTypesIOS from './ShadowPropTypesIOS' +import TransformPropTypes from './TransformPropTypes' /** * Warning: Some of these properties may not be supported in all releases. @@ -58,4 +58,4 @@ const ViewStylePropTypes = { elevation: ReactPropTypes.number } -module.exports = ViewStylePropTypes +export default ViewStylePropTypes diff --git a/packages/taro-cli/src/rn/StyleSheet/deprecatedPropType.js b/packages/taro-cli/src/rn/StyleSheet/deprecatedPropType.ts similarity index 90% rename from packages/taro-cli/src/rn/StyleSheet/deprecatedPropType.js rename to packages/taro-cli/src/rn/StyleSheet/deprecatedPropType.ts index 3a62f2d5c22f..88b3e3cef5b0 100644 --- a/packages/taro-cli/src/rn/StyleSheet/deprecatedPropType.js +++ b/packages/taro-cli/src/rn/StyleSheet/deprecatedPropType.ts @@ -8,14 +8,12 @@ * strict-local */ -'use strict' - // const UIManager = require('UIManager') /** * Adds a deprecation warning when the prop is used. */ -function deprecatedPropType ( +export default function deprecatedPropType ( propType, explanation ) { @@ -31,5 +29,3 @@ function deprecatedPropType ( return propType(props, propName, componentName, ...rest) } } - -module.exports = deprecatedPropType diff --git a/packages/taro-cli/src/rn/StyleSheet/index.js b/packages/taro-cli/src/rn/StyleSheet/index.js deleted file mode 100644 index 325863b24d0f..000000000000 --- a/packages/taro-cli/src/rn/StyleSheet/index.js +++ /dev/null @@ -1,3 +0,0 @@ -const StyleSheetValidation = require('./StyleSheetValidation') - -module.exports = {StyleSheetValidation} diff --git a/packages/taro-cli/src/rn/StyleSheet/index.ts b/packages/taro-cli/src/rn/StyleSheet/index.ts new file mode 100644 index 000000000000..26534cc3b7ff --- /dev/null +++ b/packages/taro-cli/src/rn/StyleSheet/index.ts @@ -0,0 +1,5 @@ +import StyleSheetValidation from './StyleSheetValidation' + +export { + StyleSheetValidation +} diff --git a/packages/taro-cli/src/rn/StyleSheet/normalizeColor.js b/packages/taro-cli/src/rn/StyleSheet/normalizeColor.ts similarity index 99% rename from packages/taro-cli/src/rn/StyleSheet/normalizeColor.js rename to packages/taro-cli/src/rn/StyleSheet/normalizeColor.ts index b4a117a04be9..b49b5dfc25c3 100755 --- a/packages/taro-cli/src/rn/StyleSheet/normalizeColor.js +++ b/packages/taro-cli/src/rn/StyleSheet/normalizeColor.ts @@ -9,9 +9,8 @@ */ /* eslint no-bitwise: 0 */ -'use strict' -function normalizeColor (color) { +export default function normalizeColor (color) { const matchers = getMatchers() let match @@ -368,5 +367,3 @@ const names = { yellow: 0xffff00ff, yellowgreen: 0x9acd32ff } - -module.exports = normalizeColor diff --git a/packages/taro-cli/src/rn/styleProcess.js b/packages/taro-cli/src/rn/styleProcess.ts similarity index 69% rename from packages/taro-cli/src/rn/styleProcess.js rename to packages/taro-cli/src/rn/styleProcess.ts index 630d29090ddd..b614556b8ab9 100644 --- a/packages/taro-cli/src/rn/styleProcess.js +++ b/packages/taro-cli/src/rn/styleProcess.ts @@ -1,13 +1,15 @@ -const path = require('path') -const fs = require('fs-extra') -const postcss = require('postcss') -const chalk = require('chalk') -const pxtransform = require('postcss-pxtransform') -const transformCSS = require('css-to-react-native-transform').default -const {StyleSheetValidation} = require('./StyleSheet/index') -const Util = require('../util') -const npmProcess = require('../util/npm') -const stylelintConfig = require('../config/rn-stylelint') +import path from 'path' +import fs from 'fs-extra' +import postcss from 'postcss' +import chalk from 'chalk' +import pxtransform from 'postcss-pxtransform' +import transformCSS from 'css-to-react-native-transform' + +import { StyleSheetValidation } from './StyleSheet/index' +import * as Util from '../util' +import * as npmProcess from '../util/npm' +import { FILE_PROCESSOR_MAP, processTypeEnum } from '../util/constants' +import stylelintConfig from '../config/rn-stylelint.json' const DEVICE_RATIO = 'deviceRatio' @@ -19,7 +21,7 @@ const DEVICE_RATIO = 'deviceRatio' */ function loadStyle ({filePath, pluginsConfig}) { const fileExt = path.extname(filePath) - const pluginName = Util.FILE_PROCESSOR_MAP[fileExt] + const pluginName = FILE_PROCESSOR_MAP[fileExt] if (pluginName) { return npmProcess.callPlugin(pluginName, null, filePath, pluginsConfig[pluginName] || {}) .then((item) => { @@ -28,7 +30,7 @@ function loadStyle ({filePath, pluginsConfig}) { filePath } }).catch((e) => { - Util.printLog(Util.pocessTypeEnum.ERROR, '样式预处理', filePath) + Util.printLog(processTypeEnum.ERROR, '样式预处理', filePath) console.log(e.stack) }) } @@ -52,8 +54,8 @@ function loadStyle ({filePath, pluginsConfig}) { * @param {object} projectConfig * @returns {Function | any} */ -function postCSS ({css, filePath, projectConfig}) { - let pxTransformConfig = { +function postCSS ({ css, filePath, projectConfig }) { + const pxTransformConfig = { designWidth: projectConfig.designWidth || 750 } if (projectConfig.hasOwnProperty(DEVICE_RATIO)) { @@ -79,22 +81,22 @@ function postCSS ({css, filePath, projectConfig}) { } function getStyleObject ({css, filePath}) { - var styleObject = {} + let styleObject = {} try { styleObject = transformCSS(css) } catch (err) { - Util.printLog(Util.pocessTypeEnum.WARNING, 'css-to-react-native 报错', filePath) + Util.printLog(processTypeEnum.WARNING, 'css-to-react-native 报错', filePath) console.log(chalk.red(err.stack)) } return styleObject } function validateStyle ({styleObject, filePath}) { - for (let name in styleObject) { + for (const name in styleObject) { try { StyleSheetValidation.validateStyle(name, styleObject) } catch (err) { - Util.printLog(Util.pocessTypeEnum.WARNING, '样式不支持', filePath) + Util.printLog(processTypeEnum.WARNING, '样式不支持', filePath) console.log(chalk.red(err.message)) } } @@ -104,10 +106,10 @@ function writeStyleFile ({css, tempFilePath}) { const fileContent = `import { StyleSheet } from 'react-native'\n\nexport default StyleSheet.create(${css})` fs.ensureDirSync(path.dirname(tempFilePath)) fs.writeFileSync(tempFilePath, fileContent) - Util.printLog(Util.pocessTypeEnum.GENERATE, '生成文件', tempFilePath) + Util.printLog(processTypeEnum.GENERATE, '生成文件', tempFilePath) } -module.exports = { +export { loadStyle, postCSS, getStyleObject, diff --git a/packages/taro-cli/src/rn/transformJS.js b/packages/taro-cli/src/rn/transformJS.ts similarity index 82% rename from packages/taro-cli/src/rn/transformJS.js rename to packages/taro-cli/src/rn/transformJS.ts index 4c45cb84f74b..1c550b7df203 100644 --- a/packages/taro-cli/src/rn/transformJS.js +++ b/packages/taro-cli/src/rn/transformJS.ts @@ -1,14 +1,16 @@ -const path = require('path') -const babel = require('babel-core') -const traverse = require('babel-traverse').default -const t = require('babel-types') -const _ = require('lodash') -const generate = require('babel-generator').default +import * as path from 'path' +import * as babel from 'babel-core' +import traverse from 'babel-traverse' +import * as t from 'babel-types' +import * as _ from 'lodash' +import generate from 'babel-generator' +import * as wxTransformer from '@tarojs/transformer-wx' +import * as Util from '../util' +import babylonConfig from '../config/babylon' +import { convertSourceStringToAstExpression as toAst } from '../util/astConvert' +import { REG_STYLE, REG_TYPESCRIPT, BUILD_TYPES, REG_SCRIPTS } from '../util/constants' + const template = require('babel-template') -const wxTransformer = require('@tarojs/transformer-wx') -const Util = require('../util') -const babylonConfig = require('../config/babylon') -const {source: toAst} = require('../util/ast_convert') const reactImportDefaultName = 'React' let taroImportDefaultName // import default from @tarojs/taro @@ -43,7 +45,7 @@ const PACKAGES = { } function getInitPxTransformNode (projectConfig) { - let pxTransformConfig = {designWidth: projectConfig.designWidth || 750} + const pxTransformConfig = {designWidth: projectConfig.designWidth || 750} if (projectConfig.hasOwnProperty(DEVICE_RATIO)) { pxTransformConfig[DEVICE_RATIO] = projectConfig.deviceRatio @@ -76,7 +78,7 @@ function getClassPropertyVisitor ({filePath, pages, iconPaths, isEntryFile}) { root = rootNode ? rootNode.value.value : '' value.elements.forEach(v => { - const pagePath = `${root}/${v.value}`.replace(/\/{2,}/g, '/') + const pagePath = `${root}/${(v as t.StringLiteral).value}`.replace(/\/{2,}/g, '/') pages.push(pagePath.replace(/^\//, '')) }) astPath.remove() @@ -88,15 +90,15 @@ function getClassPropertyVisitor ({filePath, pages, iconPaths, isEntryFile}) { if (key.name === 'tabBar' && t.isObjectExpression(value)) { astPath.traverse({ ObjectProperty (astPath) { - let node = astPath.node - let value = node.value.value + const node = astPath.node as any + const value = node.value.value if (node.key.name === 'iconPath' || node.key.value === 'iconPath' || node.key.name === 'selectedIconPath' || node.key.value === 'selectedIconPath' ) { if (typeof value !== 'string') return - let iconName = _.camelCase(value.split('/')) + const iconName = _.camelCase(value) if (iconPaths.indexOf(value) === -1) { iconPaths.push(value) } @@ -121,7 +123,7 @@ function getJSAst (code, filePath) { code, sourcePath: filePath, isNormal: true, - isTyped: Util.REG_TYPESCRIPT.test(filePath), + isTyped: REG_TYPESCRIPT.test(filePath), adapter: 'rn' }).ast } @@ -203,16 +205,16 @@ const ClassDeclarationOrExpression = { } } -function parseJSCode ({code, filePath, isEntryFile, projectConfig}) { +export function parseJSCode ({ code, filePath, isEntryFile, projectConfig }) { let ast try { ast = getJSAst(code, filePath) } catch (e) { throw e } - const styleFiles = [] - let pages = [] // app.js 里面的config 配置里面的 pages - let iconPaths = [] // app.js 里面的config 配置里面的需要引入的 iconPath + const styleFiles: string[] = [] + const pages: string[] = [] // app.js 里面的config 配置里面的 pages + const iconPaths: string[] = [] // app.js 里面的config 配置里面的需要引入的 iconPath let hasAddReactImportDefaultName = false let providorImportName let storeName @@ -223,7 +225,7 @@ function parseJSCode ({code, filePath, isEntryFile, projectConfig}) { ClassExpression: ClassDeclarationOrExpression, ClassDeclaration: ClassDeclarationOrExpression, ImportDeclaration (astPath) { - const node = astPath.node + const node = astPath.node as t.ImportDeclaration const source = node.source let value = source.value const valueExtname = path.extname(value) @@ -235,7 +237,7 @@ function parseJSCode ({code, filePath, isEntryFile, projectConfig}) { // 引入的包为 npm 包 if (!Util.isNpmPkg(value)) { // import 样式处理 - if (Util.REG_STYLE.test(valueExtname)) { + if (REG_STYLE.test(valueExtname)) { const stylePath = path.resolve(path.dirname(filePath), value) if (styleFiles.indexOf(stylePath) < 0) { styleFiles.push(stylePath) @@ -245,7 +247,7 @@ function parseJSCode ({code, filePath, isEntryFile, projectConfig}) { const pathArr = value.split('/') if (pathArr.indexOf('pages') >= 0) { astPath.remove() - } else if (Util.REG_SCRIPTS.test(value) || path.extname(value) === '') { + } else if (REG_SCRIPTS.test(value) || path.extname(value) === '') { const absolutePath = path.resolve(filePath, '..', value) const dirname = path.dirname(absolutePath) const extname = path.extname(absolutePath) @@ -257,7 +259,7 @@ function parseJSCode ({code, filePath, isEntryFile, projectConfig}) { return } if (value === PACKAGES['@tarojs/taro']) { - let specifier = specifiers.find(item => item.type === 'ImportDefaultSpecifier') + const specifier = specifiers.find(item => item.type === 'ImportDefaultSpecifier') if (specifier) { hasAddReactImportDefaultName = true taroImportDefaultName = specifier.local.name @@ -274,16 +276,16 @@ function parseJSCode ({code, filePath, isEntryFile, projectConfig}) { specifiers.splice(index, 1) } }) - const taroApisSpecifiers = [] + const taroApisSpecifiers: t.ImportSpecifier[] = [] specifiers.forEach((item, index) => { - if (item.imported && taroApis.indexOf(item.imported.name) >= 0) { - taroApisSpecifiers.push(t.importSpecifier(t.identifier(item.local.name), t.identifier(item.imported.name))) + if ((item as t.ImportSpecifier).imported && taroApis.indexOf((item as t.ImportSpecifier).imported.name) >= 0) { + taroApisSpecifiers.push(t.importSpecifier(t.identifier((item as t.ImportSpecifier).local.name), t.identifier((item as t.ImportSpecifier).imported.name))) specifiers.splice(index, 1) } }) source.value = PACKAGES['@tarojs/taro-rn'] // insert React - astPath.insertBefore(template(`import React from 'react'`, babylonConfig)()) + astPath.insertBefore(template(`import React from 'react'`, babylonConfig as any)()) if (taroApisSpecifiers.length) { astPath.insertBefore(t.importDeclaration(taroApisSpecifiers, t.stringLiteral(PACKAGES['@tarojs/taro-rn']))) @@ -320,13 +322,13 @@ function parseJSCode ({code, filePath, isEntryFile, projectConfig}) { ClassProperty: getClassPropertyVisitor({filePath, pages, iconPaths, isEntryFile}), // 获取 classRenderReturnJSX ClassMethod (astPath) { - let node = astPath.node - const key = node.key + const node = astPath.node as t.ClassMethod + const key = node.key as t.Identifier if (key.name !== 'render' || !isEntryFile) return astPath.traverse({ BlockStatement (astPath) { if (astPath.parent === node) { - node = astPath.node + const node = astPath.node astPath.traverse({ ReturnStatement (astPath) { if (astPath.parent === node) { @@ -350,10 +352,11 @@ function parseJSCode ({code, filePath, isEntryFile, projectConfig}) { }, JSXOpeningElement: { enter (astPath) { - if (astPath.node.name.name === 'Provider') { - for (let v of astPath.node.attributes) { + const node = astPath.node as t.JSXOpeningElement + if ((node.name as any).name === 'Provider') { + for (const v of node.attributes) { if (v.name.name !== 'store') continue - storeName = v.value.expression.name + storeName = (v.value as any).expression.name break } } @@ -361,11 +364,11 @@ function parseJSCode ({code, filePath, isEntryFile, projectConfig}) { }, Program: { exit (astPath) { - const node = astPath.node + const node = astPath.node as t.Program astPath.traverse({ ClassMethod (astPath) { const node = astPath.node - const key = node.key + const key = node.key as t.Identifier if (key.name !== 'render' || !isEntryFile) return let funcBody = ` @@ -387,18 +390,19 @@ function parseJSCode ({code, filePath, isEntryFile, projectConfig}) { ${funcBody} ` } - - node.body = template(`{return (${funcBody});}`, babylonConfig)() + node.body = template(`{return (${funcBody});}`, babylonConfig as any)() as any }, CallExpression (astPath) { const node = astPath.node - const callee = node.callee + const callee = node.callee as t.Identifier const calleeName = callee.name const parentPath = astPath.parentPath if (t.isMemberExpression(callee)) { - if (callee.object.name === taroImportDefaultName && callee.property.name === 'render') { + const object = callee.object as t.Identifier + const property = callee.property as t.Identifier + if (object.name === taroImportDefaultName && property.name === 'render') { astPath.remove() } } else { @@ -416,39 +420,39 @@ function parseJSCode ({code, filePath, isEntryFile, projectConfig}) { if (taroImportDefaultName) { const importTaro = template( `import ${taroImportDefaultName} from '${PACKAGES['@tarojs/taro-rn']}'`, - babylonConfig + babylonConfig as any )() - node.body.unshift(importTaro) + node.body.unshift(importTaro as any) } if (isEntryFile) { // 注入 import page from 'XXX' pages.forEach(item => { const pagePath = item.startsWith('/') ? item : `/${item}` - const screenName = _.camelCase(pagePath.split('/'), {pascalCase: true}) + const screenName = _.camelCase(pagePath) const importScreen = template( `import ${screenName} from '.${pagePath}'`, - babylonConfig + babylonConfig as any )() - node.body.unshift(importScreen) + node.body.unshift(importScreen as any) }) // import tabBar icon iconPaths.forEach(item => { const iconPath = item.startsWith('/') ? item : `/${item}` - const iconName = _.camelCase(iconPath.split('/')) + const iconName = _.camelCase(iconPath) const importIcon = template( `import ${iconName} from '.${iconPath}'`, - babylonConfig + babylonConfig as any )() - node.body.unshift(importIcon) + node.body.unshift(importIcon as any) }) // Taro.initRouter 生成 RootStack const routerPages = pages .map(item => { const pagePath = item.startsWith('/') ? item : `/${item}` - const screenName = _.camelCase(pagePath.split('/'), {pascalCase: true}) + const screenName = _.camelCase(pagePath) return `['${item}',${screenName}]` }) .join(',') @@ -458,22 +462,21 @@ function parseJSCode ({code, filePath, isEntryFile, projectConfig}) { ${taroImportDefaultName}, App.config )`, - babylonConfig - )()) - + babylonConfig as any + )() as any) // initNativeApi const initNativeApi = template( `${taroImportDefaultName}.initNativeApi(${taroImportDefaultName})`, - babylonConfig + babylonConfig as any )() - node.body.push(initNativeApi) + node.body.push(initNativeApi as any) // import @tarojs/taro-router-rn const importTaroRouter = template( `import TaroRouter from '${PACKAGES['@tarojs/taro-router-rn']}'`, - babylonConfig + babylonConfig as any )() - node.body.unshift(importTaroRouter) + node.body.unshift(importTaroRouter as any) // 根节点嵌套组件提供的 provider const importTCRNProvider = template( @@ -483,15 +486,15 @@ function parseJSCode ({code, filePath, isEntryFile, projectConfig}) { node.body.unshift(importTCRNProvider) // Taro.initPxTransform - node.body.push(getInitPxTransformNode(projectConfig)) + node.body.push(getInitPxTransformNode(projectConfig) as any) // export default App if (!hasAppExportDefault) { const appExportDefault = template( `export default ${componentClassName}`, - babylonConfig + babylonConfig as any )() - node.body.push(appExportDefault) + node.body.push(appExportDefault as any) } } } @@ -499,7 +502,7 @@ function parseJSCode ({code, filePath, isEntryFile, projectConfig}) { }) try { const constantsReplaceList = Object.assign({ - 'process.env.TARO_ENV': Util.BUILD_TYPES.RN + 'process.env.TARO_ENV': BUILD_TYPES.RN }, Util.generateEnvList(projectConfig.env || {}), Util.generateConstantsList(projectConfig.defineConstants || {})) // TODO 使用 babel-plugin-transform-jsx-to-stylesheet 处理 JSX 里面样式的处理,删除无效的样式引入待优化 ast = babel.transformFromAst(ast, code, { @@ -520,5 +523,3 @@ function parseJSCode ({code, filePath, isEntryFile, projectConfig}) { styleFiles } } - -module.exports = {transformJSCode: parseJSCode} diff --git a/packages/taro-cli/src/ui.js b/packages/taro-cli/src/ui.ts similarity index 87% rename from packages/taro-cli/src/ui.js rename to packages/taro-cli/src/ui.ts index 9dfa042f93a5..72eb2a4c9622 100644 --- a/packages/taro-cli/src/ui.js +++ b/packages/taro-cli/src/ui.ts @@ -1,28 +1,32 @@ -const fs = require('fs-extra') -const path = require('path') -const chokidar = require('chokidar') -const chalk = require('chalk') -const wxTransformer = require('@tarojs/transformer-wx') -const traverse = require('babel-traverse').default -const t = require('babel-types') -const generate = require('babel-generator').default -const _ = require('lodash') +import * as fs from 'fs-extra' +import * as path from 'path' -const { processFiles } = require('./h5') -const npmProcess = require('./util/npm') +import * as chokidar from 'chokidar' +import chalk from 'chalk' +import * as wxTransformer from '@tarojs/transformer-wx' +import * as t from 'babel-types' +import generate from 'babel-generator' +import traverse from 'babel-traverse' +import * as _ from 'lodash' -const CONFIG = require('./config') -const { +import { processFiles } from './h5' +import * as npmProcess from './util/npm' + +import CONFIG from './config' +import { resolveScriptPath, resolveStylePath, printLog, - pocessTypeEnum, + cssImports +} from './util' +import { + processTypeEnum, PROJECT_CONFIG, BUILD_TYPES, REG_STYLE, - REG_TYPESCRIPT, - cssImports -} = require('./util') + REG_TYPESCRIPT +} from './util/constants' +import { IComponentObj } from './mini/interface' const appPath = process.cwd() const configDir = path.join(appPath, PROJECT_CONFIG) @@ -74,14 +78,14 @@ async function buildH5Lib () { }) const { styleFiles, components, code: generateCode } = parseEntryAst(transformResult.ast, tempEntryFilePath) const relativePath = path.relative(appPath, tempEntryFilePath) - printLog(pocessTypeEnum.COPY, '发现文件', relativePath) + printLog(processTypeEnum.COPY, '发现文件', relativePath) fs.ensureDirSync(path.dirname(outputEntryFilePath)) fs.writeFileSync(outputEntryFilePath, generateCode) if (components.length) { components.forEach(item => { - copyFileToDist(item.path, tempPath, outputDir) + copyFileToDist(item.path as string, tempPath, outputDir) }) - analyzeFiles(components.map(item => item.path), tempPath, outputDir) + analyzeFiles(components.map(item => item.path as string), tempPath, outputDir) } if (styleFiles.length) { styleFiles.forEach(item => { @@ -94,14 +98,14 @@ async function buildH5Lib () { } } -function copyFileToDist (filePath, sourceDir, outputDir) { - if (!path.isAbsolute(filePath)) { +function copyFileToDist (filePath: string, sourceDir: string, outputDir: string) { + if (!filePath && !path.isAbsolute(filePath)) { return } const dirname = path.dirname(filePath) const distDirname = dirname.replace(sourceDir, outputDir) const relativePath = path.relative(appPath, filePath) - printLog(pocessTypeEnum.COPY, '发现文件', relativePath) + printLog(processTypeEnum.COPY, '发现文件', relativePath) fs.ensureDirSync(distDirname) fs.copyFileSync(filePath, path.format({ dir: distDirname, @@ -109,11 +113,11 @@ function copyFileToDist (filePath, sourceDir, outputDir) { })) } -function parseEntryAst (ast, relativeFile) { - const styleFiles = [] - const components = [] - const importExportName = [] - let exportDefaultName = null +function parseEntryAst (ast: t.File, relativeFile: string) { + const styleFiles: string[] = [] + const components: IComponentObj[] = [] + const importExportName: string[] = [] + let exportDefaultName: string | null = null traverse(ast, { ExportNamedDeclaration (astPath) { @@ -198,7 +202,7 @@ function parseEntryAst (ast, relativeFile) { } } -function analyzeFiles (files, sourceDir, outputDir) { +function analyzeFiles (files: string[], sourceDir: string, outputDir: string) { const { parseAst } = require('./weapp') files.forEach(file => { if (fs.existsSync(file)) { @@ -285,7 +289,7 @@ async function buildForWeapp () { await compileDepStyles(outputStylePath, styleFiles, false) } const relativePath = path.relative(appPath, entryFilePath) - printLog(pocessTypeEnum.COPY, '发现文件', relativePath) + printLog(processTypeEnum.COPY, '发现文件', relativePath) fs.ensureDirSync(path.dirname(outputEntryFilePath)) fs.copyFileSync(entryFilePath, path.format({ dir: path.dirname(outputEntryFilePath), @@ -293,20 +297,20 @@ async function buildForWeapp () { })) if (components.length) { components.forEach(item => { - copyFileToDist(item.path, sourceDir, outputDir) + copyFileToDist(item.path as string, sourceDir, outputDir) }) - analyzeFiles(components.map(item => item.path), sourceDir, outputDir) + analyzeFiles(components.map(item => item.path as string), sourceDir, outputDir) } } catch (err) { console.log(err) } } -async function buildForH5 (buildConfig) { +async function buildForH5 () { const { buildTemp } = require('./h5') console.log() console.log(chalk.green('开始编译 H5 端组件库!')) - await buildTemp(buildConfig) + await buildTemp() if (process.env.TARO_BUILD_TYPE === 'script') { await buildH5Script() } else { @@ -397,15 +401,15 @@ function watchFiles () { } watcher - .on('add', filePath => handleChange(filePath, pocessTypeEnum.CREATE, '添加文件')) - .on('change', filePath => handleChange(filePath, pocessTypeEnum.MODIFY, '文件变动')) + .on('add', filePath => handleChange(filePath, processTypeEnum.CREATE, '添加文件')) + .on('change', filePath => handleChange(filePath, processTypeEnum.MODIFY, '文件变动')) .on('unlink', filePath => { for (const path in extraWatchFiles) { if (filePath.indexOf(path.substr(2)) > -1) return } const relativePath = path.relative(appPath, filePath) - printLog(pocessTypeEnum.UNLINK, '删除文件', relativePath) + printLog(processTypeEnum.UNLINK, '删除文件', relativePath) const weappOutputPath = path.join(appPath, outputDirName, weappOutputName) const h5OutputPath = path.join(appPath, outputDirName, h5OutputName) const fileTempPath = filePath.replace(sourceDir, tempPath) @@ -417,7 +421,7 @@ function watchFiles () { }) } -async function build ({ watch }) { +export async function build ({ watch }) { buildEntry() await buildForWeapp() await buildForH5() @@ -425,7 +429,3 @@ async function build ({ watch }) { watchFiles() } } - -module.exports = { - build -} diff --git a/packages/taro-cli/src/util/ast_convert.js b/packages/taro-cli/src/util/astConvert.ts similarity index 62% rename from packages/taro-cli/src/util/ast_convert.js rename to packages/taro-cli/src/util/astConvert.ts index 255fd4b82519..ffb39a922025 100644 --- a/packages/taro-cli/src/util/ast_convert.js +++ b/packages/taro-cli/src/util/astConvert.ts @@ -1,9 +1,11 @@ -const t = require('babel-types') -const babylonConfig = require('../config/babylon') +import * as t from 'babel-types' +import generate from 'better-babel-generator' + +import babylonConfig from '../config/babylon' + const template = require('babel-template') -const generate = require('better-babel-generator').default -function convertObjectToAstExpression (obj) { +export function convertObjectToAstExpression (obj: object): t.ObjectProperty[] { const objArr = Object.keys(obj).map(key => { const value = obj[key] if (typeof value === 'string') { @@ -16,20 +18,18 @@ function convertObjectToAstExpression (obj) { return t.objectProperty(t.stringLiteral(key), t.booleanLiteral(value)) } if (Array.isArray(value)) { - return t.objectProperty(t.stringLiteral(key), t.arrayExpression(convertArrayToAstExpression(value))) - } - if (value == null) { - return t.objectProperty(t.stringLiteral(key), t.nullLiteral()) + return t.objectProperty(t.stringLiteral(key), t.arrayExpression(convertArrayToAstExpression(value as []))) } if (typeof value === 'object') { return t.objectProperty(t.stringLiteral(key), t.objectExpression(convertObjectToAstExpression(value))) } + return t.objectProperty(t.stringLiteral(key), t.nullLiteral()) }) return objArr } // 最低限度的转义: https://github.com/mathiasbynens/jsesc#minimal -function generateMinimalEscapeCode (ast) { +export function generateMinimalEscapeCode (ast: t.File) { return generate(ast, { jsescOption: { minimal: true @@ -37,7 +37,7 @@ function generateMinimalEscapeCode (ast) { }).code } -function convertArrayToAstExpression (arr) { +export function convertArrayToAstExpression (arr: any[]): any[] { return arr.map(value => { if (typeof value === 'string') { return t.stringLiteral(value) @@ -51,33 +51,33 @@ function convertArrayToAstExpression (arr) { if (Array.isArray(value)) { return convertArrayToAstExpression(value) } - if (value == null) { - return t.nullLiteral() - } if (typeof value === 'object') { return t.objectExpression(convertObjectToAstExpression(value)) } + return t.nullLiteral() }) } -function convertSourceStringToAstExpression (str, opts = {}) { +export function convertSourceStringToAstExpression (str: string, opts: object = {}) { return template(str, Object.assign({}, babylonConfig, opts))() } -const convertAstExpressionToVariable = (node) => { +export function convertAstExpressionToVariable (node) { if (t.isObjectExpression(node)) { const obj = {} const properties = node.properties properties.forEach(property => { - const key = convertAstExpressionToVariable(property.key) - const value = convertAstExpressionToVariable(property.value) - obj[key] = value + if (property.type === 'ObjectProperty' || property.type === 'ObjectMethod') { + const key = convertAstExpressionToVariable(property.key) + const value = convertAstExpressionToVariable(property.value) + obj[key] = value + } }) return obj } else if (t.isArrayExpression(node)) { return node.elements.map(convertAstExpressionToVariable) } else if (t.isLiteral(node)) { - return node.value + return node['value'] } else if (t.isIdentifier(node) || t.isJSXIdentifier(node)) { const name = node.name return name === 'undefined' @@ -88,8 +88,16 @@ const convertAstExpressionToVariable = (node) => { } } -exports.obj = convertObjectToAstExpression -exports.array = convertArrayToAstExpression -exports.source = convertSourceStringToAstExpression -exports.generateMinimalEscapeCode = generateMinimalEscapeCode -exports.toVariable = convertAstExpressionToVariable +export const getObjKey = (node) => { + if (t.isIdentifier(node)) { + return node.name + } else { + return node.value + } +} + +// exports.obj = convertObjectToAstExpression +// exports.array = convertArrayToAstExpression +// exports.source = convertSourceStringToAstExpression +// exports.getObjKey = getObjKey +// exports.generateMinimalEscapeCode = generateMinimalEscapeCode diff --git a/packages/taro-cli/src/util/constants.ts b/packages/taro-cli/src/util/constants.ts new file mode 100644 index 000000000000..878e3d5e88cd --- /dev/null +++ b/packages/taro-cli/src/util/constants.ts @@ -0,0 +1,259 @@ +import chalk, { Chalk } from 'chalk' + +export const enum processTypeEnum { + START = 'start', + CREATE = 'create', + COMPILE = 'compile', + CONVERT = 'convert', + COPY = 'copy', + GENERATE = 'generate', + MODIFY = 'modify', + ERROR = 'error', + WARNING = 'warning', + UNLINK = 'unlink', + REFERENCE = 'reference' +} + +export interface IProcessTypeMap { + [key: string] : { + name: string, + color: string | Chalk + } +} + +export const processTypeMap: IProcessTypeMap = { + [processTypeEnum.CREATE]: { + name: '创建', + color: 'cyan' + }, + [processTypeEnum.COMPILE]: { + name: '编译', + color: 'green' + }, + [processTypeEnum.CONVERT]: { + name: '转换', + color: chalk.rgb(255, 136, 0) + }, + [processTypeEnum.COPY]: { + name: '拷贝', + color: 'magenta' + }, + [processTypeEnum.GENERATE]: { + name: '生成', + color: 'blue' + }, + [processTypeEnum.MODIFY]: { + name: '修改', + color: 'yellow' + }, + [processTypeEnum.ERROR]: { + name: '错误', + color: 'red' + }, + [processTypeEnum.WARNING]: { + name: '警告', + color: 'yellow' + }, + [processTypeEnum.UNLINK]: { + name: '删除', + color: 'magenta' + }, + [processTypeEnum.START]: { + name: '启动', + color: 'green' + }, + [processTypeEnum.REFERENCE]: { + name: '引用', + color: 'blue' + } +} + +export const CSS_EXT: string[] = ['.css', '.scss', '.sass', '.less', '.styl', '.wxss', '.acss'] +export const SCSS_EXT: string[] = ['.scss'] +export const JS_EXT: string[] = ['.js', '.jsx'] +export const TS_EXT: string[] = ['.ts', '.tsx'] + +export const REG_JS: RegExp = /\.js(\?.*)?$/ +export const REG_SCRIPT: RegExp = /\.(js|jsx)(\?.*)?$/ +export const REG_TYPESCRIPT: RegExp = /\.(tsx|ts)(\?.*)?$/ +export const REG_SCRIPTS: RegExp = /\.[tj]sx?$/i +export const REG_STYLE: RegExp = /\.(css|scss|sass|less|styl|wxss)(\?.*)?$/ +export const REG_MEDIA: RegExp = /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/ +export const REG_IMAGE: RegExp = /\.(png|jpe?g|gif|bpm|svg|webp)(\?.*)?$/ +export const REG_FONT: RegExp = /\.(woff2?|eot|ttf|otf)(\?.*)?$/ +export const REG_JSON: RegExp = /\.json(\?.*)?$/ +export const REG_WXML_IMPORT: RegExp = / { - if (item.indexOf('..') >= 0) { - dotCount++ - } - }) - if (dotCount === 1) { - fPathArr.splice(0, 1, '.') - return fPathArr.join('/') - } - if (dotCount > 1) { - fPathArr.splice(0, 1) - return fPathArr.join('/') - } - return fPath.replace(/\\/g, '/') -} - -exports.replaceAsync = async function (str, regex, asyncFn) { - const promises = [] - str.replace(regex, (match, ...args) => { - const promise = asyncFn(match, ...args) - promises.push(promise) - }) - const data = await Promise.all(promises) - return str.replace(regex, () => data.shift()) -} - -exports.homedir = (function () { - let homedir = null - const env = process.env - const home = env.HOME - const user = env.LOGNAME || env.USER || env.LNAME || env.USERNAME - if (process.platform === 'win32') { - homedir = env.USERPROFILE || env.HOMEDRIVE + env.HOMEPATH || home || null - } else if (process.platform === 'darwin') { - homedir = home || (user ? `/Users/${user}` : null) - } else if (process.platform === 'linux') { - homedir = home || (process.getuid() === 0 ? '/root' : (user ? `/home/${user}` : null)) - } - return typeof os.homedir === 'function' ? os.homedir : function () { - return homedir - } -})() - -exports.getRootPath = function () { - return path.resolve(__dirname, '../../') -} - -exports.getTaroPath = function () { - const taroPath = path.join(exports.homedir(), '.taro') - if (!fs.existsSync(taroPath)) { - fs.ensureDirSync(taroPath) - } - return taroPath -} - -exports.setConfig = function (config) { - const taroPath = exports.getTaroPath() - if (typeof config === 'object') { - const oldConfig = exports.getConfig() - config = Object.assign({}, oldConfig, config) - fs.writeFileSync(path.join(taroPath, 'config.json'), JSON.stringify(config, null, 2)) - } -} - -exports.getConfig = function () { - const configPath = path.join(exports.getTaroPath(), 'config.json') - if (fs.existsSync(configPath)) { - return require(configPath) - } - return {} -} - -exports.getSystemUsername = function () { - const userHome = exports.homedir() - const systemUsername = process.env.USER || path.basename(userHome) - return systemUsername -} - -exports.getPkgVersion = function () { - return require(path.join(exports.getRootPath(), 'package.json')).version -} - -exports.getPkgItemByKey = function (key) { - const packageMap = require(path.join(exports.getRootPath(), 'package.json')) - if (Object.keys(packageMap).indexOf(key) === -1) { - return {} - } else { - return packageMap[key] - } -} - -exports.printPkgVersion = function () { - const taroVersion = exports.getPkgVersion() - console.log(`👽 Taro v${taroVersion}`) - console.log() -} - -exports.shouldUseYarn = function () { - try { - execSync('yarn --version', { stdio: 'ignore' }) - return true - } catch (e) { - return false - } -} - -exports.shouldUseCnpm = function () { - try { - execSync('cnpm --version', { stdio: 'ignore' }) - return true - } catch (e) { - return false - } -} - -exports.isPublic = function isPublic (addr) { - return !exports.isPrivate(addr) -} - -exports.isEmptyObject = function (obj) { - if (obj == null) { - return true - } - for (const key in obj) { - if (obj.hasOwnProperty(key)) { - return false - } - } - return true -} - -exports.urlJoin = function () { - function normalize (str) { - return str - .replace(/([/]+)/g, '/') - .replace(/\/\?(?!\?)/g, '?') - .replace(/\/#/g, '#') - .replace(/:\//g, '://') - } - - const joined = [].slice.call(arguments, 0).join('/') - return normalize(joined) -} - -exports.resolveScriptPath = function (p) { - let realPath = p - const taroEnv = process.env.TARO_ENV - const SCRIPT_EXT = exports.JS_EXT.concat(exports.TS_EXT) - for (let i = 0; i < SCRIPT_EXT.length; i++) { - const item = SCRIPT_EXT[i] - if (taroEnv) { - if (fs.existsSync(`${p}.${taroEnv}${item}`)) { - return `${p}.${taroEnv}${item}` - } - if (fs.existsSync(`${p}${path.sep}index.${taroEnv}${item}`)) { - return `${p}${path.sep}index.${taroEnv}${item}` - } - if (fs.existsSync(`${p.replace(/\/index$/, `.${taroEnv}/index`)}${item}`)) { - return `${p.replace(/\/index$/, `.${taroEnv}/index`)}${item}` - } - } - if (fs.existsSync(`${p}${item}`)) { - return `${p}${item}` - } - if (fs.existsSync(`${p}${path.sep}index${item}`)) { - return `${p}${path.sep}index${item}` - } - } - return realPath -} - -exports.resolveStylePath = function (p) { - let realPath = p - const CSS_EXT = exports.CSS_EXT - for (let i = 0; i < CSS_EXT.length; i++) { - const item = CSS_EXT[i] - if (fs.existsSync(`${p}${item}`)) { - return `${p}${item}` - } - } - return realPath -} - -exports.isDifferentArray = function (a, b) { - if (!Array.isArray(a) || !Array.isArray(b)) { - return true - } - if (a.length !== b.length) { - return true - } - a = a.sort() - b = b.sort() - for (let i = 0; i < a.length; i++) { - if (a[i] !== b[i]) { - return true - } - } - return false -} - -exports.checksum = function (buf, length) { - if (!Buffer.isBuffer(buf)) { - buf = Buffer.from(buf) - } - return crypto.createHash('md5').update(buf).digest('hex').slice(0, length || 8) -} - -exports.printLog = function (type, tag, filePath) { - const typeShow = processTypeMap[type] - const tagLen = tag.replace(/[\u0391-\uFFE5]/g, 'aa').length - const tagFormatLen = 8 - if (tagLen < tagFormatLen) { - const rightPadding = new Array(tagFormatLen - tagLen + 1).join(' ') - tag += rightPadding - } - const padding = '' - filePath = filePath || '' - if (typeof typeShow.color === 'string') { - console.log(chalk[typeShow.color](typeShow.name), padding, tag, padding, filePath) - } else { - console.log(typeShow.color(typeShow.name), padding, tag, padding, filePath) - } -} - -exports.replaceContentEnv = function (content, env) { - if (env && !exports.isEmptyObject(env)) { - for (const key in env) { - const reg = new RegExp(`process.env.${key}`, 'g') - content = content.replace(reg, env[key]) - } - return content - } - return content -} - -exports.generateEnvList = function (env) { - const res = { } - if (env && !exports.isEmptyObject(env)) { - for (const key in env) { - try { - res[`process.env.${key}`] = JSON.parse(env[key]) - } catch (err) { - res[`process.env.${key}`] = env[key] - } - } - } - return res -} - -exports.replaceContentConstants = function (content, constants) { - if (constants && !exports.isEmptyObject(constants)) { - for (const key in constants) { - const reg = new RegExp(key, 'g') - content = content.replace(reg, constants[key]) - } - return content - } - return content -} - -exports.generateConstantsList = function (constants) { - const res = { } - if (constants && !exports.isEmptyObject(constants)) { - for (const key in constants) { - if (_.isPlainObject(constants[key])) { - res[key] = exports.generateConstantsList(constants[key]) - } else { - try { - res[key] = JSON.parse(constants[key]) - } catch (err) { - res[key] = constants[key] - } - } - } - } - return res -} - -exports.cssImports = function (content) { - let match = {} - const results = [] - content = String(content).replace(/\/\*.+?\*\/|\/\/.*(?=[\n\r])/g, '') - while ((match = exports.CSS_IMPORT_REG.exec(content))) { - results.push(match[2]) - } - return results -} - -exports.processStyleImports = function (content, adapter, process) { - const style = [] - const imports = [] - const styleReg = new RegExp(`\\${exports.MINI_APP_FILES[adapter].STYLE}`) - content = content.replace(exports.CSS_IMPORT_REG, (m, $1, $2) => { - if (styleReg.test($2)) { - style.push(m) - imports.push($2) - if (process && typeof process === 'function') { - return process(m, $2) - } - return '' - } - if (process && typeof process === 'function') { - return process(m, $2) - } - return m - }) - return { - content, - style, - imports - } -} -/*eslint-disable*/ -const retries = (process.platform === 'win32') ? 100 : 1 -exports.emptyDirectory = function (dirPath, opts = { excludes: [] }) { - if (fs.existsSync(dirPath)) { - fs.readdirSync(dirPath).forEach(file => { - const curPath = path.join(dirPath, file) - if (fs.lstatSync(curPath).isDirectory()) { - let removed = false - let i = 0 // retry counter - - do { - try { - if (!opts.excludes.length || !opts.excludes.some(item => curPath.indexOf(item) >= 0)) { - exports.emptyDirectory(curPath) - fs.rmdirSync(curPath) - } - removed = true - } catch (e) { - } finally { - if (++i < retries) { - continue - } - } - } while (!removed) - } else { - fs.unlinkSync(curPath) - } - }) - } -} -/* eslint-enable */ - -exports.recursiveFindNodeModules = function (filePath) { - const dirname = path.dirname(filePath) - const nodeModules = path.join(dirname, 'node_modules') - if (fs.existsSync(nodeModules)) { - return nodeModules - } - return exports.recursiveFindNodeModules(dirname) -} - -exports.UPDATE_PACKAGE_LIST = [ - '@tarojs/taro', - '@tarojs/async-await', - '@tarojs/cli', - '@tarojs/components', - '@tarojs/components-rn', - '@tarojs/taro-h5', - '@tarojs/taro-swan', - '@tarojs/taro-alipay', - '@tarojs/taro-tt', - '@tarojs/plugin-babel', - '@tarojs/plugin-csso', - '@tarojs/plugin-sass', - '@tarojs/plugin-less', - '@tarojs/plugin-stylus', - '@tarojs/plugin-uglifyjs', - '@tarojs/redux', - '@tarojs/redux-h5', - '@tarojs/taro-redux-rn', - '@tarojs/taro-router-rn', - '@tarojs/taro-rn', - '@tarojs/rn-runner', - '@tarojs/router', - '@tarojs/taro-weapp', - '@tarojs/webpack-runner', - 'postcss-plugin-constparse', - 'eslint-config-taro', - 'eslint-plugin-taro', - 'taro-transformer-wx', - 'postcss-pxtransform', - 'babel-plugin-transform-jsx-to-stylesheet', - '@tarojs/mobx', - '@tarojs/mobx-h5', - '@tarojs/mobx-rn', - '@tarojs/mobx-common', - '@tarojs/mobx-prop-types', - 'stylelint-taro-rn', - 'styleint-config-taro-rn' -] - -exports.pascalCase = (str) => str.charAt(0).toUpperCase() + _.camelCase(str.substr(1)) - -exports.getInstalledNpmPkgVersion = function (pkgName, basedir) { - const resolvePath = require('resolve') - try { - const pkg = resolvePath.sync(`${pkgName}/package.json`, { basedir }) - const pkgJson = fs.readJSONSync(pkg) - return pkgJson.version - } catch (err) { - return null - } -} diff --git a/packages/taro-cli/src/util/index.ts b/packages/taro-cli/src/util/index.ts new file mode 100644 index 000000000000..f8b200eeab67 --- /dev/null +++ b/packages/taro-cli/src/util/index.ts @@ -0,0 +1,406 @@ +import * as fs from 'fs-extra' +import * as path from 'path' +import * as crypto from 'crypto' +import * as os from 'os' +import * as child_process from 'child_process' +import * as chalk from 'chalk' +import * as _ from 'lodash' + +import { + TS_EXT, + JS_EXT, + CSS_EXT, + CSS_IMPORT_REG, + processTypeMap, + processTypeEnum, + MINI_APP_FILES, + BUILD_TYPES +} from './constants' + +const execSync = child_process.execSync + +export function isNpmPkg (name: string): boolean { + if (/^(\.|\/)/.test(name)) { + return false + } + return true +} + +export function isAliasPath (name: string, pathAlias: object = {}): boolean { + const prefixs = Object.keys(pathAlias) + if (prefixs.length === 0) { + return false + } + return prefixs.includes(name) || (new RegExp(`^(${prefixs.join('|')})/`).test(name)) +} + +export function replaceAliasPath (filePath: string, name: string, pathAlias: object = {}) { + // 后续的 path.join 在遇到符号链接时将会解析为真实路径,如果 + // 这里的 filePath 没有做同样的处理,可能会导致 import 指向 + // 源代码文件,导致文件被意外修改 + filePath = fs.realpathSync(filePath) + + const prefixs = Object.keys(pathAlias) + if (prefixs.includes(name)) { + return promoteRelativePath(path.relative(filePath, fs.realpathSync(pathAlias[name]))) + } + const reg = new RegExp(`^(${prefixs.join('|')})/(.*)`) + name = name.replace(reg, function (m, $1, $2) { + return promoteRelativePath(path.relative(filePath, path.join(pathAlias[$1], $2))) + }) + return name +} + +export function promoteRelativePath (fPath: string): string { + const fPathArr = fPath.split(path.sep) + let dotCount = 0 + fPathArr.forEach(item => { + if (item.indexOf('..') >= 0) { + dotCount++ + } + }) + if (dotCount === 1) { + fPathArr.splice(0, 1, '.') + return fPathArr.join('/') + } + if (dotCount > 1) { + fPathArr.splice(0, 1) + return fPathArr.join('/') + } + return fPath.replace(/\\/g, '/') +} + +export const homedir = (function () { + let homedir: any + const env: NodeJS.ProcessEnv = process.env + const home = env.HOME + const user = env.LOGNAME || env.USER || env.LNAME || env.USERNAME + if (process.platform === 'win32') { + homedir = env.USERPROFILE || (env.HOMEDRIVE as string) + (env.HOMEPATH as string) || home || null + } else if (process.platform === 'darwin') { + homedir = home || (user ? `/Users/${user}` : null) + } else if (process.platform === 'linux') { + homedir = home || (process.getuid() === 0 ? '/root' : (user ? `/home/${user}` : null)) + } + return typeof os.homedir === 'function' ? os.homedir : function () { + return homedir + } +})() + +export function getRootPath (): string { + return path.resolve(__dirname, '../../') +} + +export function getTaroPath (): string { + const taroPath = path.join(homedir(), '.taro') + if (!fs.existsSync(taroPath)) { + fs.ensureDirSync(taroPath) + } + return taroPath +} + +export function setConfig (config: object): void { + const taroPath = getTaroPath() + if (typeof config === 'object') { + const oldConfig = getConfig() + config = Object.assign({}, oldConfig, config) + fs.writeFileSync(path.join(taroPath, 'config.json'), JSON.stringify(config, null, 2)) + } +} + +export function getConfig (): object { + const configPath = path.join(getTaroPath(), 'config.json') + if (fs.existsSync(configPath)) { + return require(configPath) + } + return {} +} + +export function getSystemUsername (): string { + const userHome = homedir() + const systemUsername = process.env.USER || path.basename(userHome) + return systemUsername +} + +export function getPkgVersion (): string { + return require(path.join(getRootPath(), 'package.json')).version +} + +export function getPkgItemByKey (key: string) { + const packageMap = require(path.join(getRootPath(), 'package.json')) + if (Object.keys(packageMap).indexOf(key) === -1) { + return {} + } else { + return packageMap[key] + } +} + +export function printPkgVersion () { + const taroVersion = getPkgVersion() + console.log(`👽 Taro v${taroVersion}`) + console.log() +} + +export function shouldUseYarn (): boolean { + try { + execSync('yarn --version', { stdio: 'ignore' }) + return true + } catch (e) { + return false + } +} + +export function shouldUseCnpm (): boolean { + try { + execSync('cnpm --version', { stdio: 'ignore' }) + return true + } catch (e) { + return false + } +} + +export function isEmptyObject (obj: any): boolean { + if (obj == null) { + return true + } + for (const key in obj) { + if (obj.hasOwnProperty(key)) { + return false + } + } + return true +} + +export function urlJoin (...agrs: string[]): string { + function normalize (str) { + return str + .replace(/([/]+)/g, '/') + .replace(/\/\?(?!\?)/g, '?') + .replace(/\/#/g, '#') + .replace(/:\//g, '://') + } + + const joined = [].slice.call(agrs, 0).join('/') + return normalize(joined) +} + +export function resolveScriptPath (p: string): string { + const realPath = p + const taroEnv = process.env.TARO_ENV + const SCRIPT_EXT = exports.JS_EXT.concat(exports.TS_EXT) + for (let i = 0; i < SCRIPT_EXT.length; i++) { + const item = SCRIPT_EXT[i] + if (taroEnv) { + if (fs.existsSync(`${p}.${taroEnv}${item}`)) { + return `${p}.${taroEnv}${item}` + } + if (fs.existsSync(`${p}${path.sep}index.${taroEnv}${item}`)) { + return `${p}${path.sep}index.${taroEnv}${item}` + } + if (fs.existsSync(`${p.replace(/\/index$/, `.${taroEnv}/index`)}${item}`)) { + return `${p.replace(/\/index$/, `.${taroEnv}/index`)}${item}` + } + } + if (fs.existsSync(`${p}${item}`)) { + return `${p}${item}` + } + if (fs.existsSync(`${p}${path.sep}index${item}`)) { + return `${p}${path.sep}index${item}` + } + } + return realPath +} + +export function resolveStylePath (p: string): string { + const realPath = p + for (let i = 0; i < CSS_EXT.length; i++) { + const item = CSS_EXT[i] + if (fs.existsSync(`${p}${item}`)) { + return `${p}${item}` + } + } + return realPath +} + +export function isDifferentArray (a: any[], b: any[]): boolean { + if (!Array.isArray(a) || !Array.isArray(b)) { + return true + } + if (a.length !== b.length) { + return true + } + a = a.sort() + b = b.sort() + for (let i = 0; i < a.length; i++) { + if (a[i] !== b[i]) { + return true + } + } + return false +} + +export function checksum (buf: Buffer | string, length?): string { + if (!Buffer.isBuffer(buf)) { + buf = Buffer.from(buf) + } + return crypto.createHash('md5').update(buf).digest('hex').slice(0, length || 8) +} + +export function printLog (type: processTypeEnum, tag: string, filePath?: string) { + const typeShow = processTypeMap[type] + const tagLen = tag.replace(/[\u0391-\uFFE5]/g, 'aa').length + const tagFormatLen = 8 + if (tagLen < tagFormatLen) { + const rightPadding = new Array(tagFormatLen - tagLen + 1).join(' ') + tag += rightPadding + } + const padding = '' + filePath = filePath || '' + if (typeof typeShow.color === 'string') { + console.log(chalk[typeShow.color](typeShow.name), padding, tag, padding, filePath) + } else { + console.log(typeShow.color(typeShow.name), padding, tag, padding, filePath) + } +} + +export function replaceContentEnv (content: string, env: object): string { + if (env && !isEmptyObject(env)) { + for (const key in env) { + const reg = new RegExp(`process.env.${key}`, 'g') + content = content.replace(reg, env[key]) + } + return content + } + return content +} + +export function generateEnvList (env: object): object { + const res = { } + if (env && !isEmptyObject(env)) { + for (const key in env) { + try { + res[`process.env.${key}`] = JSON.parse(env[key]) + } catch (err) { + res[`process.env.${key}`] = env[key] + } + } + } + return res +} + +export function replaceContentConstants (content: string, constants: object): string { + if (constants && !isEmptyObject(constants)) { + for (const key in constants) { + const reg = new RegExp(key, 'g') + content = content.replace(reg, constants[key]) + } + return content + } + return content +} + +export function generateConstantsList (constants: object): object { + const res = { } + if (constants && !isEmptyObject(constants)) { + for (const key in constants) { + if (_.isPlainObject(constants[key])) { + res[key] = generateConstantsList(constants[key]) + } else { + try { + res[key] = JSON.parse(constants[key]) + } catch (err) { + res[key] = constants[key] + } + } + } + } + return res +} + +export function cssImports (content: string): string[] { + let match: RegExpExecArray | null + const results: string[] = [] + content = String(content).replace(/\/\*.+?\*\/|\/\/.*(?=[\n\r])/g, '') + while ((match = CSS_IMPORT_REG.exec(content))) { + results.push(match[2]) + } + return results +} + +export function processStyleImports (content: string, adapter: BUILD_TYPES, processFn: (a: string, b: string) => string) { + const style: string[] = [] + const imports: string[] = [] + const styleReg = new RegExp(`\\${MINI_APP_FILES[adapter].STYLE}`) + content = content.replace(CSS_IMPORT_REG, (m, $1, $2) => { + if (styleReg.test($2)) { + style.push(m) + imports.push($2) + if (processFn && typeof processFn === 'function') { + return processFn(m, $2) + } + return '' + } + if (processFn && typeof processFn === 'function') { + return processFn(m, $2) + } + return m + }) + return { + content, + style, + imports + } +} +/*eslint-disable*/ +const retries = (process.platform === 'win32') ? 100 : 1 +export function emptyDirectory (dirPath: string, opts: { excludes: string[] } = { excludes: [] }) { + if (fs.existsSync(dirPath)) { + fs.readdirSync(dirPath).forEach(file => { + const curPath = path.join(dirPath, file) + if (fs.lstatSync(curPath).isDirectory()) { + let removed = false + let i = 0 // retry counter + do { + try { + if (!opts.excludes.length || !opts.excludes.some(item => curPath.indexOf(item) >= 0)) { + emptyDirectory(curPath) + fs.rmdirSync(curPath) + } + removed = true + } catch (e) { + } finally { + if (++i < retries) { + continue + } + } + } while (!removed) + } else { + fs.unlinkSync(curPath) + } + }) + } +} +/* eslint-enable */ + +export function recursiveFindNodeModules (filePath: string): string { + const dirname = path.dirname(filePath) + const nodeModules = path.join(dirname, 'node_modules') + if (fs.existsSync(nodeModules)) { + return nodeModules + } + return recursiveFindNodeModules(dirname) +} + +export const pascalCase: (str: string) => string + = (str: string): string => str.charAt(0).toUpperCase() + _.camelCase(str.substr(1)) + +export function getInstalledNpmPkgVersion (pkgName: string, basedir: string): string | null { + const resolvePath = require('resolve') + try { + const pkg = resolvePath.sync(`${pkgName}/package.json`, { basedir }) + const pkgJson = fs.readJSONSync(pkg) + return pkgJson.version + } catch (err) { + return null + } +} diff --git a/packages/taro-cli/src/util/npm.js b/packages/taro-cli/src/util/npm.ts similarity index 71% rename from packages/taro-cli/src/util/npm.js rename to packages/taro-cli/src/util/npm.ts index 05821fb90436..accb12051e75 100644 --- a/packages/taro-cli/src/util/npm.js +++ b/packages/taro-cli/src/util/npm.ts @@ -1,20 +1,26 @@ -const resolvePath = require('resolve') -const spawn = require('cross-spawn') -const chalk = require('chalk') +import * as resolvePath from 'resolve' +import * as spawn from 'cross-spawn' +import chalk from 'chalk' -const Util = require('./') +import * as Util from './' +import { IInstallOptions } from './types' const basedir = process.cwd() -const taroPluginPrefix = '@tarojs/plugin-' const PEERS = /UNMET PEER DEPENDENCY ([a-z\-0-9.]+)@(.+)/gm const npmCached = {} -const erroneous = [] -const defaultInstallOptions = { + +const erroneous: string[] = [] + +type pluginFunction = (pluginName: string, content: string | null, file: string, config: object) => any + +const defaultInstallOptions: IInstallOptions = { dev: false, peerDependencies: true } -function resolveNpm (pluginName) { +export const taroPluginPrefix = '@tarojs/plugin-' + +export function resolveNpm (pluginName: string): Promise { if (!npmCached[pluginName]) { return new Promise((resolve, reject) => { resolvePath(`${pluginName}`, {basedir}, (err, res) => { @@ -29,7 +35,7 @@ function resolveNpm (pluginName) { return Promise.resolve(npmCached[pluginName]) } -function resolveNpmSync (pluginName) { +export function resolveNpmSync (pluginName: string): string { try { if (!npmCached[pluginName]) { const res = resolvePath.sync(pluginName, {basedir}) @@ -39,17 +45,20 @@ function resolveNpmSync (pluginName) { } catch (err) { if (err.code === 'MODULE_NOT_FOUND') { console.log(chalk.cyan(`缺少npm包${pluginName},开始安装...`)) - const installOptions = {} + const installOptions: IInstallOptions = { + dev: false + } if (pluginName.indexOf(taroPluginPrefix) >= 0) { installOptions.dev = true } installNpmPkg(pluginName, installOptions) return resolveNpmSync(pluginName) } + return '' } } -function installNpmPkg (pkgList, options) { +export function installNpmPkg (pkgList: string[] | string, options: IInstallOptions) { if (!pkgList) { return } @@ -65,7 +74,7 @@ function installNpmPkg (pkgList, options) { } options = Object.assign({}, defaultInstallOptions, options) let installer = '' - let args = [] + let args: string[] = [] if (Util.shouldUseYarn()) { installer = 'yarn' @@ -98,8 +107,8 @@ function installNpmPkg (pkgList, options) { erroneous.push(dep) }) } - let matches = null - const peers = [] + let matches: RegExpExecArray | null = null + const peers: string[] = [] while ((matches = PEERS.exec(output.stdout))) { const pkg = matches[1] @@ -117,30 +126,32 @@ function installNpmPkg (pkgList, options) { return output } -async function callPlugin (pluginName, content, file, config) { +export const callPlugin: pluginFunction = async (pluginName: string, content: string | null, file: string, config: object) => { const pluginFn = await getNpmPkg(`${taroPluginPrefix}${pluginName}`) return pluginFn(content, file, config) } -function callPluginSync (pluginName, content, file, config) { +export const callPluginSync: pluginFunction = (pluginName: string, content: string | null, file: string, config: object) => { const pluginFn = getNpmPkgSync(`${taroPluginPrefix}${pluginName}`) return pluginFn(content, file, config) } -function getNpmPkgSync (npmName) { +export function getNpmPkgSync (npmName: string) { const npmPath = resolveNpmSync(npmName) const npmFn = require(npmPath) return npmFn } -async function getNpmPkg (npmName) { +export async function getNpmPkg (npmName: string) { let npmPath try { npmPath = resolveNpmSync(npmName) } catch (err) { if (err.code === 'MODULE_NOT_FOUND') { console.log(chalk.cyan(`缺少npm包${npmName},开始安装...`)) - const installOptions = {} + const installOptions: IInstallOptions = { + dev: false + } if (npmName.indexOf(taroPluginPrefix) >= 0) { installOptions.dev = true } @@ -151,14 +162,3 @@ async function getNpmPkg (npmName) { const npmFn = require(npmPath) return npmFn } - -module.exports = { - taroPluginPrefix, - installNpmPkg, - resolveNpm, - resolveNpmSync, - callPlugin, - callPluginSync, - getNpmPkg, - getNpmPkgSync -} diff --git a/packages/taro-cli/src/util/resolve_npm_files.js b/packages/taro-cli/src/util/resolve_npm_files.ts similarity index 70% rename from packages/taro-cli/src/util/resolve_npm_files.js rename to packages/taro-cli/src/util/resolve_npm_files.ts index b7f06688103d..0bba2c0698b0 100644 --- a/packages/taro-cli/src/util/resolve_npm_files.js +++ b/packages/taro-cli/src/util/resolve_npm_files.ts @@ -1,36 +1,39 @@ -const fs = require('fs-extra') -const path = require('path') -const resolvePath = require('resolve') -const wxTransformer = require('@tarojs/transformer-wx') -const babel = require('babel-core') -const traverse = require('babel-traverse').default -const t = require('babel-types') -const generate = require('babel-generator').default -const _ = require('lodash') +import * as fs from 'fs-extra' +import * as path from 'path' +import * as resolvePath from 'resolve' +import * as wxTransformer from '@tarojs/transformer-wx' +import * as babel from 'babel-core' +import * as t from 'babel-types' +import traverse from 'babel-traverse' +import generate from 'babel-generator' +import * as _ from 'lodash' -const defaultUglifyConfig = require('../config/uglify') - -const { +import { isNpmPkg, promoteRelativePath, printLog, - pocessTypeEnum, + recursiveFindNodeModules, + generateEnvList +} from './index' + +import { + processTypeEnum, PROJECT_CONFIG, - generateEnvList, REG_TYPESCRIPT, BUILD_TYPES, - REG_STYLE, - recursiveFindNodeModules -} = require('./index') + REG_STYLE +} from './constants' -const CONFIG = require('../config') -const defaultBabelConfig = require('../config/babel') +import defaultUglifyConfig from '../config/uglify' +import defaultBabelConfig from '../config/babel' +import CONFIG from '../config' -const npmProcess = require('./npm') +import * as npmProcess from './npm' +import { IInstallOptions, INpmConfig, IResolvedCache } from './types' const excludeNpmPkgs = ['ReactPropTypes'] -const resolvedCache = {} +const resolvedCache: IResolvedCache = {} const copyedFiles = {} const basedir = process.cwd() @@ -45,13 +48,21 @@ const babelConfig = _.mergeWith({}, defaultBabelConfig, pluginsConfig.babel, (ob } }) -function resolveNpmPkgMainPath (pkgName, isProduction, npmConfig, buildAdapter = BUILD_TYPES.WEAPP, root = basedir) { +export function resolveNpmPkgMainPath ( + pkgName: string, + isProduction: boolean, + npmConfig: INpmConfig, + buildAdapter: BUILD_TYPES = BUILD_TYPES.WEAPP, + root: string = basedir +) { try { return resolvePath.sync(pkgName, { basedir: root }) } catch (err) { if (err.code === 'MODULE_NOT_FOUND') { console.log(`缺少npm包${pkgName},开始安装...`) - const installOptions = {} + const installOptions: IInstallOptions = { + dev: false + } if (pkgName.indexOf(npmProcess.taroPluginPrefix) >= 0) { installOptions.dev = true } @@ -61,7 +72,14 @@ function resolveNpmPkgMainPath (pkgName, isProduction, npmConfig, buildAdapter = } } -function resolveNpmFilesPath (pkgName, isProduction, npmConfig, buildAdapter = BUILD_TYPES.WEAPP, root = basedir, compileInclude = []) { +export function resolveNpmFilesPath ( + pkgName: string, + isProduction: boolean, + npmConfig: INpmConfig, + buildAdapter: BUILD_TYPES = BUILD_TYPES.WEAPP, + root: string = basedir, + compileInclude: string[] = [] +) { if (!resolvedCache[pkgName]) { const res = resolveNpmPkgMainPath(pkgName, isProduction, npmConfig, buildAdapter, root) resolvedCache[pkgName] = { @@ -74,27 +92,38 @@ function resolveNpmFilesPath (pkgName, isProduction, npmConfig, buildAdapter = B return resolvedCache[pkgName] } -function parseAst (ast, filePath, files, isProduction, npmConfig, buildAdapter = BUILD_TYPES.WEAPP, compileInclude) { - const excludeRequire = [] +function parseAst ( + ast: t.File, + filePath: string, + files: string[], + isProduction: boolean, + npmConfig: INpmConfig, + buildAdapter: BUILD_TYPES = BUILD_TYPES.WEAPP, + compileInclude: string[] = [] +) { + const excludeRequire: string[] = [] traverse(ast, { IfStatement (astPath) { astPath.traverse({ BinaryExpression (astPath) { const node = astPath.node const left = node.left - if (generate(left).code === 'process.env.TARO_ENV' && - node.right.value !== buildAdapter) { - const consequentSibling = astPath.getSibling('consequent') - consequentSibling.traverse({ - CallExpression (astPath) { - if (astPath.get('callee').isIdentifier({ name: 'require' })) { - const arg = astPath.get('arguments')[0] - if (t.isStringLiteral(arg.node)) { - excludeRequire.push(arg.node.value) + const right = node.right + if (t.isMemberExpression(left) && t.isStringLiteral(right)) { + if (generate(left).code === 'process.env.TARO_ENV' && + (node.right as t.StringLiteral).value !== buildAdapter) { + const consequentSibling = astPath.getSibling('consequent') + consequentSibling.traverse({ + CallExpression (astPath) { + if (astPath.get('callee').isIdentifier({ name: 'require' })) { + const arg = astPath.get('arguments')[0] + if (t.isStringLiteral(arg.node)) { + excludeRequire.push(arg.node.value) + } } } - } - }) + }) + } } } }) @@ -104,9 +133,9 @@ function parseAst (ast, filePath, files, isProduction, npmConfig, buildAdapter = astPath.traverse({ CallExpression (astPath) { const node = astPath.node - const callee = node.callee + const callee = node.callee as t.Identifier if (callee.name === 'require') { - const args = node.arguments + const args = node.arguments as Array let requirePath = args[0].value if (excludeRequire.indexOf(requirePath) < 0) { if (isNpmPkg(requirePath)) { @@ -121,8 +150,8 @@ function parseAst (ast, filePath, files, isProduction, npmConfig, buildAdapter = } } else { let realRequirePath = path.resolve(path.dirname(filePath), requirePath) - let tempPathWithJS = `${realRequirePath}.js` - let tempPathWithIndexJS = `${realRequirePath}${path.sep}index.js` + const tempPathWithJS = `${realRequirePath}.js` + const tempPathWithIndexJS = `${realRequirePath}${path.sep}index.js` if (fs.existsSync(tempPathWithJS)) { realRequirePath = tempPathWithJS requirePath += '.js' @@ -146,7 +175,14 @@ function parseAst (ast, filePath, files, isProduction, npmConfig, buildAdapter = return generate(ast).code } -async function recursiveRequire (filePath, files, isProduction, npmConfig = {}, buildAdapter, compileInclude = []) { +async function recursiveRequire ( + filePath: string, + files: string[], + isProduction: boolean, + npmConfig: INpmConfig, + buildAdapter: BUILD_TYPES, + compileInclude: string[] = [] +) { let fileContent = fs.readFileSync(filePath).toString() let outputNpmPath if (!npmConfig.dir) { @@ -157,9 +193,12 @@ async function recursiveRequire (filePath, files, isProduction, npmConfig = {}, outputNpmPath = filePath.replace('node_modules', path.join(cwdRelate2Npm, outputDirName, npmConfig.name)) outputNpmPath = outputNpmPath.replace(/node_modules/g, npmConfig.name) } else { - let npmFilePath = filePath.match(/(?=(node_modules)).*/)[0] - npmFilePath = npmFilePath.replace(/node_modules/g, npmConfig.name) - outputNpmPath = path.join(path.resolve(configDir, '..', npmConfig.dir), npmFilePath) + const matches = filePath.match(/(?=(node_modules)).*/) + if (matches) { + let npmFilePath = matches[0] + npmFilePath = npmFilePath.replace(/node_modules/g, npmConfig.name) + outputNpmPath = path.join(path.resolve(configDir, '..', npmConfig.dir), npmFilePath) + } } if (buildAdapter === BUILD_TYPES.ALIPAY) { outputNpmPath = outputNpmPath.replace(/@/g, '_') @@ -185,7 +224,7 @@ async function recursiveRequire (filePath, files, isProduction, npmConfig = {}, plugins: [ [require('babel-plugin-transform-define').default, constantsReplaceList] ] - }).ast + }).ast as t.File fileContent = parseAst(ast, filePath, files, isProduction, npmConfig, buildAdapter, compileInclude) } catch (err) { console.log(err) @@ -206,7 +245,7 @@ async function recursiveRequire (filePath, files, isProduction, npmConfig = {}, const uglifyConfig = Object.assign(defaultUglifyConfig, uglifyPluginConfig.config || {}) const uglifyResult = npmProcess.callPluginSync('uglifyjs', fileContent, outputNpmPath, uglifyConfig) if (uglifyResult.error) { - printLog(pocessTypeEnum.ERROR, '压缩错误', `文件${filePath}`) + printLog(processTypeEnum.ERROR, '压缩错误', `文件${filePath}`) console.log(uglifyResult.error) } else { fileContent = uglifyResult.code @@ -217,12 +256,12 @@ async function recursiveRequire (filePath, files, isProduction, npmConfig = {}, fs.writeFileSync(outputNpmPath, fileContent) let modifyOutput = outputNpmPath.replace(basedir + path.sep, '') modifyOutput = modifyOutput.split(path.sep).join('/') - printLog(pocessTypeEnum.COPY, 'NPM文件', modifyOutput) + printLog(processTypeEnum.COPY, 'NPM文件', modifyOutput) copyedFiles[outputNpmPath] = true } } -function npmCodeHack (filePath, content, buildAdapter) { +function npmCodeHack (filePath: string, content: string, buildAdapter: BUILD_TYPES): string { const basename = path.basename(filePath) switch (basename) { case 'lodash.js': @@ -259,12 +298,6 @@ function npmCodeHack (filePath, content, buildAdapter) { return content } -function getResolvedCache () { +export function getResolvedCache (): IResolvedCache { return resolvedCache } - -module.exports = { - getResolvedCache, - resolveNpmFilesPath, - resolveNpmPkgMainPath -} diff --git a/packages/taro-cli/src/util/types.ts b/packages/taro-cli/src/util/types.ts new file mode 100644 index 000000000000..483cd0432a89 --- /dev/null +++ b/packages/taro-cli/src/util/types.ts @@ -0,0 +1,182 @@ +import * as webpack from 'webpack' +import * as webpackDevServer from 'webpack-dev-server' +import * as t from 'babel-types' + +import { BUILD_TYPES } from './constants' +import { IBabelOptions } from '../config/babel' + +export interface IInstallOptions { + dev: boolean, + peerDependencies?: boolean +} + +export interface INpmConfig { + dir: string, + name: string +} + +export interface IResolvedCache { + [key: string]: { + main: string, + files: string[] + } +} + +export interface IPrettierConfig { + printWidth?: number, + tabWidth?: number, + useTabs?: boolean, + semi?: boolean, + singleQuote?: boolean, + jsxSingleQuote?: boolean, + trailingComma?: 'none' | 'es5' | 'all', + bracketSpacing?: boolean, + jsxBracketSameLine?: boolean, + arrowParens?: 'avoid' | 'always', + rangeStart?: number, + rangeEnd?: number, + parser?: 'babylon' | 'flow' | 'typescript' | 'css' | 'scss' | 'less' | 'json' | 'json5' | 'json-stringify' | 'graphql' | 'markdown' | 'mdx' | 'html' | 'vue' | 'angular' | 'yaml' | 'babel', + filepath?: string, + requirePragma?: boolean, + insertPragma?: boolean, + proseWrap?: 'always' | 'never' | 'preserve', + htmlWhitespaceSensitivity?: 'css' | 'strict' | 'ignore', + endOfLine?: 'auto' | 'lf' | 'crlf' | 'cr' +} + +export interface IBuildConfig { + type?: BUILD_TYPES, + watch?: boolean, + platform?: string +} + +export interface IMiniAppBuildConfig { + adapter: BUILD_TYPES, + watch?: boolean, + envHasBeenSet?: boolean +} + +export interface IOption { + [key: string]: any +} + +export interface ICopyOptions { + patterns: { + from: string, + to: string, + ignore?: string[] + }[], + options: { + ignore?: string[] + } +} + +export interface IWxTransformResult { + code: string, + ast: t.File, + template: string, + compressedTemplate: string, + components: { + name: string, + path: string, + type: string + }[], + componentProperies: string[] +} + +export namespace PostcssOption { + export type cssModules = TogglableOptions<{ + namingPattern: 'global' | string + generateScopedName: string + }> + export type url = TogglableOptions<{ + limit: number + }> +} + +export interface IPostcssOption { + autoprefixer?: TogglableOptions, + pxtransform?: TogglableOptions, + cssModules?: PostcssOption.cssModules, + url?: PostcssOption.url, + [key: string]: any +} + +export interface ICompileOption { + exclude?: string[], + include?: string[] +} + +export interface IMiniAppConfig { + appOutput: boolean, + module?: { + postcss?: IPostcssOption + }, + compile?: ICompileOption +} + +type TogglableOptions = { + enable?: boolean, + config?: T +} + +export interface IH5Config { + webpack: ((webpackConfig: webpack.Configuration, webpack) => webpack.Configuration) | webpack.Configuration, + webpackChain: (chain: any, webpack: any) => void, + dllWebpackChain: (chain: any, webpack: any) => void, + + alias: IOption, + entry: webpack.Entry, + output: webpack.Output, + router?: { + mode?: 'hash' | 'browser', + custouRoutes?: IOption + }, + devServer: webpackDevServer.Configuration, + enableSourceMap: boolean, + enableExtract: boolean, + enableDll: boolean, + + cssLoaderOption: IOption, + styleLoaderOption: IOption, + sassLoaderOption: IOption, + lessLoaderOption: IOption, + stylusLoaderOption: IOption, + mediaUrlLoaderOption: IOption, + fontUrlLoaderOption: IOption, + imageUrlLoaderOption: IOption, + miniCssExtractPluginOption: IOption, + dllDirectory: string, + dllFilename: string, + dllEntry: { + [key: string]: string[] + }, + esnextModules: string[], + + module?: { + postcss?: IPostcssOption + } +} + +export interface IProjectConfig { + projectName?: string, + date?: string, + designWidth?: number, + watcher?: [], + deviceRatio?: { + [key: string]: number + }, + sourceRoot?: string, + outputRoot?: string, + plugins?: { + babel?: IBabelOptions, + csso?: TogglableOptions, + uglify?: TogglableOptions + }, + env?: IOption, + alias?: IOption, + defineConstants?: IOption, + copy?: ICopyOptions, + weapp?: IMiniAppConfig, + h5?: IH5Config +} diff --git a/packages/taro-cli/src/weapp.js b/packages/taro-cli/src/weapp.js deleted file mode 100644 index 81118f65007c..000000000000 --- a/packages/taro-cli/src/weapp.js +++ /dev/null @@ -1,2275 +0,0 @@ -const fs = require('fs-extra') -const os = require('os') -const path = require('path') -const chalk = require('chalk') -const chokidar = require('chokidar') -const wxTransformer = require('@tarojs/transformer-wx') -const babel = require('babel-core') -const traverse = require('babel-traverse').default -const t = require('babel-types') -const generate = require('babel-generator').default -const template = require('babel-template') -const autoprefixer = require('autoprefixer') -const minimatch = require('minimatch') -const _ = require('lodash') - -const postcss = require('postcss') -const pxtransform = require('postcss-pxtransform') -const cssUrlParse = require('postcss-url') -const Scope = require('postcss-modules-scope') -const Values = require('postcss-modules-values') -const genericNames = require('generic-names') -const LocalByDefault = require('postcss-modules-local-by-default') -const ExtractImports = require('postcss-modules-extract-imports') -const ResolveImports = require('postcss-modules-resolve-imports') - -const Util = require('./util') -const CONFIG = require('./config') -const npmProcess = require('./util/npm') -const { resolveNpmFilesPath, resolveNpmPkgMainPath } = require('./util/resolve_npm_files') -const babylonConfig = require('./config/babylon') -const browserList = require('./config/browser_list') -const defaultUglifyConfig = require('./config/uglify') -const defaultBabelConfig = require('./config/babel') -const astConvert = require('./util/ast_convert') - -const appPath = process.cwd() -const configDir = path.join(appPath, Util.PROJECT_CONFIG) -const projectConfig = require(configDir)(_.merge) -const sourceDirName = projectConfig.sourceRoot || CONFIG.SOURCE_DIR -const outputDirName = projectConfig.outputRoot || CONFIG.OUTPUT_DIR -const sourceDir = path.join(appPath, sourceDirName) -const outputDir = path.join(appPath, outputDirName) -const entryFilePath = Util.resolveScriptPath(path.join(sourceDir, CONFIG.ENTRY)) -const entryFileName = path.basename(entryFilePath) -const outputEntryFilePath = path.join(outputDir, entryFileName) -const watcherDirs = projectConfig.watcher || [] -const pathAlias = projectConfig.alias || {} - -const pluginsConfig = projectConfig.plugins || {} -const weappConf = projectConfig.weapp || {} -const weappNpmConfig = Object.assign({ - name: CONFIG.NPM_DIR, - dir: null -}, weappConf.npm) -const appOutput = typeof weappConf.appOutput === 'boolean' ? weappConf.appOutput : true -const useCompileConf = Object.assign({}, weappConf.compile) -const compileInclude = useCompileConf.include || [] - -const notExistNpmList = [] -const taroJsFramework = '@tarojs/taro' -const taroJsComponents = '@tarojs/components' -const taroJsRedux = '@tarojs/redux' -let appConfig = {} -const dependencyTree = {} -const depComponents = {} -const hasBeenBuiltComponents = [] -const componentsBuildResult = {} -const componentsNamedMap = {} -const componentExportsMap = {} -const wxssDepTree = {} -let isBuildingScripts = {} -let isBuildingStyles = {} -let isCopyingFiles = {} -let isProduction = false -let buildAdapter = Util.BUILD_TYPES.WEAPP -let outputFilesTypes = Util.MINI_APP_FILES[buildAdapter] -let notTaroComponents = [] - -const NODE_MODULES = 'node_modules' -const NODE_MODULES_REG = /(.*)node_modules/ - -const nodeModulesPath = Util.recursiveFindNodeModules(path.join(appPath, NODE_MODULES)) -let npmOutputDir - -if (!weappNpmConfig.dir) { - npmOutputDir = path.join(outputDir, weappNpmConfig.name) -} else { - npmOutputDir = path.join(path.resolve(configDir, '..', weappNpmConfig.dir), weappNpmConfig.name) -} - -const PARSE_AST_TYPE = { - ENTRY: 'ENTRY', - PAGE: 'PAGE', - COMPONENT: 'COMPONENT', - NORMAL: 'NORMAL' -} - -const DEVICE_RATIO = 'deviceRatio' - -const isWindows = os.platform() === 'win32' - -let constantsReplaceList = Object.assign({}, Util.generateEnvList(projectConfig.env || {}), Util.generateConstantsList(projectConfig.defineConstants || {})) - -function getExactedNpmFilePath (npmName, filePath) { - try { - const npmInfo = resolveNpmFilesPath(npmName, isProduction, weappNpmConfig, buildAdapter, appPath, compileInclude) - const npmInfoMainPath = npmInfo.main - let outputNpmPath - if (Util.REG_STYLE.test(npmInfoMainPath)) { - outputNpmPath = npmInfoMainPath - } else { - if (!weappNpmConfig.dir) { - const cwdRelate2Npm = path.relative(npmInfoMainPath.slice(0, npmInfoMainPath.search('node_modules')), process.cwd()) - outputNpmPath = npmInfoMainPath.replace(NODE_MODULES, path.join(cwdRelate2Npm, outputDirName, weappNpmConfig.name)) - outputNpmPath = outputNpmPath.replace(/node_modules/g, weappNpmConfig.name) - } else { - let npmFilePath = npmInfoMainPath.match(/(?=(node_modules)).*/)[0] - npmFilePath = npmFilePath.replace(/node_modules/g, weappNpmConfig.name) - outputNpmPath = path.join(path.resolve(configDir, '..', weappNpmConfig.dir), npmFilePath) - } - } - if (buildAdapter === Util.BUILD_TYPES.ALIPAY) { - outputNpmPath = outputNpmPath.replace(/@/g, '_') - } - const relativePath = path.relative(filePath, outputNpmPath) - return Util.promoteRelativePath(relativePath) - } catch (err) { - console.log(err) - if (notExistNpmList.indexOf(npmName) < 0) { - notExistNpmList.push(npmName) - } - return npmName - } -} - -function traverseObjectNode (node, obj) { - if (node.type === 'ClassProperty' || node.type === 'ObjectProperty') { - const properties = node.value.properties - obj = {} - properties.forEach(p => { - let key = t.isIdentifier(p.key) ? p.key.name : p.key.value - if (Util.CONFIG_MAP[buildAdapter][key]) { - key = Util.CONFIG_MAP[buildAdapter][key] - } - obj[key] = traverseObjectNode(p.value) - }) - return obj - } - if (node.type === 'ObjectExpression') { - const properties = node.properties - obj = {} - properties.forEach(p => { - let key = t.isIdentifier(p.key) ? p.key.name : p.key.value - if (Util.CONFIG_MAP[buildAdapter][key]) { - key = Util.CONFIG_MAP[buildAdapter][key] - } - obj[key] = traverseObjectNode(p.value) - }) - return obj - } - if (node.type === 'ArrayExpression') { - return node.elements.map(item => traverseObjectNode(item)) - } - if (node.type === 'NullLiteral') { - return null - } - return node.value -} - -function analyzeImportUrl ({ astPath, value, depComponents, sourceFilePath, filePath, styleFiles, scriptFiles, jsonFiles, mediaFiles }) { - const valueExtname = path.extname(value) - const node = astPath.node - if (value.indexOf('.') === 0) { - let importPath = path.resolve(path.dirname(sourceFilePath), value) - importPath = Util.resolveScriptPath(importPath) - if (isFileToBePage(importPath)) { - astPath.remove() - } else { - if (Util.REG_SCRIPT.test(valueExtname) || Util.REG_TYPESCRIPT.test(valueExtname)) { - const vpath = path.resolve(sourceFilePath, '..', value) - let fPath = value - if (fs.existsSync(vpath) && vpath !== sourceFilePath) { - fPath = vpath - } - if (scriptFiles.indexOf(fPath) < 0) { - scriptFiles.push(fPath) - } - } else if (Util.REG_JSON.test(valueExtname)) { - const vpath = path.resolve(sourceFilePath, '..', value) - if (jsonFiles.indexOf(vpath) < 0) { - jsonFiles.push(vpath) - } - if (fs.existsSync(vpath)) { - const obj = JSON.parse(fs.readFileSync(vpath).toString()) - const specifiers = node.specifiers - let defaultSpecifier = null - specifiers.forEach(item => { - if (item.type === 'ImportDefaultSpecifier') { - defaultSpecifier = item.local.name - } - }) - if (defaultSpecifier) { - let objArr = [t.nullLiteral()] - if (Array.isArray(obj)) { - objArr = t.arrayExpression(astConvert.array(obj)) - } else { - objArr = t.objectExpression(astConvert.obj(obj)) - } - astPath.replaceWith(t.variableDeclaration('const', [t.variableDeclarator(t.identifier(defaultSpecifier), objArr)])) - } - } - } else if (Util.REG_FONT.test(valueExtname) || Util.REG_IMAGE.test(valueExtname) || Util.REG_MEDIA.test(valueExtname)) { - const vpath = path.resolve(sourceFilePath, '..', value) - if (!fs.existsSync(vpath)) { - Util.printLog(Util.pocessTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) - return - } - if (mediaFiles.indexOf(vpath) < 0) { - mediaFiles.push(vpath) - } - const specifiers = node.specifiers - let defaultSpecifier = null - specifiers.forEach(item => { - if (item.type === 'ImportDefaultSpecifier') { - defaultSpecifier = item.local.name - } - }) - let showPath - if (NODE_MODULES_REG.test(vpath)) { - showPath = vpath.replace(nodeModulesPath, `/${weappNpmConfig.name}`) - } else { - showPath = vpath.replace(sourceDir, '') - } - - if (defaultSpecifier) { - astPath.replaceWith(t.variableDeclaration('const', [t.variableDeclarator(t.identifier(defaultSpecifier), t.stringLiteral(showPath.replace(/\\/g, '/')))])) - } else { - astPath.remove() - } - } else if (Util.REG_STYLE.test(valueExtname)) { - const stylePath = path.resolve(path.dirname(sourceFilePath), value) - if (styleFiles.indexOf(stylePath) < 0) { - styleFiles.push(stylePath) - } - astPath.remove() - } else { - let vpath = Util.resolveScriptPath(path.resolve(sourceFilePath, '..', value)) - let outputVpath - if (NODE_MODULES_REG.test(vpath)) { - outputVpath = vpath.replace(nodeModulesPath, npmOutputDir) - } else { - outputVpath = vpath.replace(sourceDir, outputDir) - } - let relativePath = path.relative(filePath, outputVpath) - if (vpath && vpath !== sourceFilePath) { - if (!fs.existsSync(vpath)) { - Util.printLog(Util.pocessTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) - } else { - if (fs.lstatSync(vpath).isDirectory()) { - if (fs.existsSync(path.join(vpath, 'index.js'))) { - vpath = path.join(vpath, 'index.js') - relativePath = path.join(relativePath, 'index.js') - } else { - Util.printLog(Util.pocessTypeEnum.ERROR, '引用目录', `文件 ${sourceFilePath} 中引用了目录 ${value}!`) - return - } - } - if (scriptFiles.indexOf(vpath) < 0) { - scriptFiles.push(vpath) - } - relativePath = Util.promoteRelativePath(relativePath) - relativePath = relativePath.replace(path.extname(relativePath), '.js') - node.source.value = relativePath - } - } - } - } - } -} - -function parseAst (type, ast, depComponents, sourceFilePath, filePath, npmSkip = false) { - const styleFiles = [] - const scriptFiles = [] - const jsonFiles = [] - const mediaFiles = [] - let configObj = {} - let componentClassName = null - let taroJsReduxConnect = null - let taroMiniAppFramework = `@tarojs/taro-${buildAdapter}` - let taroImportDefaultName - let needExportDefault = false - let exportTaroReduxConnected = null - ast = babel.transformFromAst(ast, '', { - plugins: [ - [require('babel-plugin-danger-remove-unused-import'), { ignore: ['@tarojs/taro', 'react', 'nervjs'] }], - [require('babel-plugin-transform-define').default, constantsReplaceList] - ] - }).ast - traverse(ast, { - ClassDeclaration (astPath) { - const node = astPath.node - let hasCreateData = false - if (node.superClass) { - astPath.traverse({ - ClassMethod (astPath) { - if (astPath.get('key').isIdentifier({ name: '_createData' })) { - hasCreateData = true - } - } - }) - if (hasCreateData) { - needExportDefault = true - astPath.traverse({ - ClassMethod (astPath) { - const node = astPath.node - if (node.kind === 'constructor') { - astPath.traverse({ - ExpressionStatement (astPath) { - const node = astPath.node - if (node.expression && - node.expression.type === 'AssignmentExpression' && - node.expression.operator === '=') { - const left = node.expression.left - if (left.type === 'MemberExpression' && - left.object.type === 'ThisExpression' && - left.property.type === 'Identifier' && - left.property.name === 'config') { - configObj = traverseObjectNode(node.expression.right) - } - } - } - }) - } - } - }) - if (node.id === null) { - componentClassName = '_TaroComponentClass' - astPath.replaceWith(t.classDeclaration(t.identifier(componentClassName), node.superClass, node.body, node.decorators || [])) - } else if (node.id.name === 'App') { - componentClassName = '_App' - astPath.replaceWith(t.classDeclaration(t.identifier(componentClassName), node.superClass, node.body, node.decorators || [])) - } else { - componentClassName = node.id.name - } - } - } - }, - - ClassExpression (astPath) { - const node = astPath.node - if (node.superClass) { - let hasCreateData = false - astPath.traverse({ - ClassMethod (astPath) { - if (astPath.get('key').isIdentifier({ name: '_createData' })) { - hasCreateData = true - } - } - }) - if (hasCreateData) { - needExportDefault = true - if (node.id === null) { - const parentNode = astPath.parentPath.node - if (t.isVariableDeclarator(astPath.parentPath)) { - componentClassName = parentNode.id.name - } else { - componentClassName = '_TaroComponentClass' - } - astPath.replaceWith(t.ClassExpression(t.identifier(componentClassName), node.superClass, node.body, node.decorators || [])) - } else if (node.id.name === 'App') { - componentClassName = '_App' - astPath.replaceWith(t.ClassExpression(t.identifier(componentClassName), node.superClass, node.body, node.decorators || [])) - } else { - componentClassName = node.id.name - } - } - } - }, - - ClassProperty (astPath) { - const node = astPath.node - if (node.key.name === 'config') { - configObj = traverseObjectNode(node) - } - }, - - ImportDeclaration (astPath) { - const node = astPath.node - const source = node.source - let value = source.value - const specifiers = node.specifiers - // alias 替换 - if (Util.isAliasPath(value, pathAlias)) { - value = Util.replaceAliasPath(sourceFilePath, value, pathAlias) - source.value = value - } - if (Util.isNpmPkg(value) && notExistNpmList.indexOf(value) < 0) { - if (value === taroJsComponents) { - astPath.remove() - } else { - let isDepComponent = false - if (depComponents && depComponents.length) { - depComponents.forEach(item => { - if (item.path === value) { - isDepComponent = true - } - }) - } - if (isDepComponent) { - astPath.remove() - } else { - const specifiers = node.specifiers - if (value === taroJsFramework) { - let defaultSpecifier = null - specifiers.forEach(item => { - if (item.type === 'ImportDefaultSpecifier') { - defaultSpecifier = item.local.name - } - }) - if (defaultSpecifier) { - taroImportDefaultName = defaultSpecifier - } - value = taroMiniAppFramework - } else if (value === taroJsRedux) { - specifiers.forEach(item => { - if (item.type === 'ImportSpecifier') { - const local = item.local - if (local.type === 'Identifier' && local.name === 'connect') { - taroJsReduxConnect = item.imported.name - } - } - }) - } - if (!npmSkip) { - source.value = getExactedNpmFilePath(value, filePath) - } else { - source.value = value - } - } - } - } else if (Util.CSS_EXT.indexOf(path.extname(value)) !== -1 && specifiers.length > 0) { // 对 使用 import style from './style.css' 语法引入的做转化处理 - Util.printLog(Util.pocessTypeEnum.GENERATE, '替换代码', `为文件 ${sourceFilePath} 生成 css modules`) - const styleFilePath = path.join(path.dirname(sourceFilePath), value) - const styleCode = fs.readFileSync(styleFilePath).toString() - const result = processStyleUseCssModule({ - css: styleCode, - filePath: styleFilePath - }) - const tokens = result.root.exports || {} - const cssModuleMapFile = createCssModuleMap(styleFilePath, tokens) - astPath.node.source = t.stringLiteral(astPath.node.source.value.replace(path.basename(styleFilePath), path.basename(cssModuleMapFile))) - if (styleFiles.indexOf(styleFilePath) < 0) { // add this css file to queue - styleFiles.push(styleFilePath) - } - } else if (path.isAbsolute(value)) { - Util.printLog(Util.pocessTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 是绝对路径!`) - } - }, - - CallExpression (astPath) { - const node = astPath.node - const callee = node.callee - if (t.isMemberExpression(callee)) { - if (taroImportDefaultName && callee.object.name === taroImportDefaultName && callee.property.name === 'render') { - astPath.remove() - } - } else if (callee.name === 'require') { - const args = node.arguments - let value = args[0].value - if (Util.isAliasPath(value, pathAlias)) { - value = Util.replaceAliasPath(sourceFilePath, value, pathAlias) - args[0].value = value - } - if (Util.isNpmPkg(value) && notExistNpmList.indexOf(value) < 0) { - if (value === taroJsComponents) { - astPath.remove() - } else { - let isDepComponent = false - if (depComponents && depComponents.length) { - depComponents.forEach(item => { - if (item.path === value) { - isDepComponent = true - } - }) - } - if (isDepComponent) { - astPath.remove() - } else { - if (t.isVariableDeclaration(astPath.parentPath.parentPath)) { - const parentNode = astPath.parentPath.parentPath.node - if (parentNode.declarations.length === 1 && parentNode.declarations[0].init) { - const id = parentNode.declarations[0].id - if (value === taroJsFramework && id.type === 'Identifier') { - taroImportDefaultName = id.name - value = taroMiniAppFramework - } else if (value === taroJsRedux) { - const declarations = parentNode.declarations - declarations.forEach(item => { - const id = item.id - if (id.type === 'ObjectPattern') { - const properties = id.properties - properties.forEach(p => { - if (p.type === 'ObjectProperty') { - if (p.value.type === 'Identifier' && p.value.name === 'connect') { - taroJsReduxConnect = p.key.name - } - } - }) - } - }) - } - } - } - if (!npmSkip) { - args[0].value = getExactedNpmFilePath(value, filePath) - } else { - args[0].value = value - } - } - } - } else if (Util.CSS_EXT.indexOf(path.extname(value)) !== -1 && t.isVariableDeclarator(astPath.parentPath)) { // 对 使用 const style = require('./style.css') 语法引入的做转化处理 - Util.printLog(Util.pocessTypeEnum.GENERATE, '替换代码', `为文件 ${sourceFilePath} 生成 css modules`) - const styleFilePath = path.join(path.dirname(sourceFilePath), value) - const styleCode = fs.readFileSync(styleFilePath).toString() - const result = processStyleUseCssModule({ - css: styleCode, - filePath: styleFilePath - }) - const tokens = result.root.exports || {} - const cssModuleMapFile = createCssModuleMap(styleFilePath, tokens) - astPath.node.arguments = [t.stringLiteral(astPath.node.arguments[0].value.replace(path.basename(styleFilePath), path.basename(cssModuleMapFile)))] - if (styleFiles.indexOf(styleFilePath) < 0) { // add this css file to queue - styleFiles.push(styleFilePath) - } - } else if (path.isAbsolute(value)) { - Util.printLog(Util.pocessTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 是绝对路径!`) - } - } - }, - - ExportDefaultDeclaration (astPath) { - const node = astPath.node - const declaration = node.declaration - needExportDefault = false - if ( - declaration && - (declaration.type === 'ClassDeclaration' || declaration.type === 'ClassExpression') - ) { - const superClass = declaration.superClass - if (superClass) { - let hasCreateData = false - astPath.traverse({ - ClassMethod (astPath) { - if (astPath.get('key').isIdentifier({ name: '_createData' })) { - hasCreateData = true - } - } - }) - if (hasCreateData) { - needExportDefault = true - if (declaration.id === null) { - componentClassName = '_TaroComponentClass' - } else if (declaration.id.name === 'App') { - componentClassName = '_App' - } else { - componentClassName = declaration.id.name - } - const isClassDcl = declaration.type === 'ClassDeclaration' - const classDclProps = [t.identifier(componentClassName), superClass, declaration.body, declaration.decorators || []] - astPath.replaceWith(isClassDcl ? t.classDeclaration.apply(null, classDclProps) : t.classExpression.apply(null, classDclProps)) - } - } - } else if (declaration.type === 'CallExpression') { - const callee = declaration.callee - if (callee && callee.type === 'CallExpression') { - const subCallee = callee.callee - if (subCallee.type === 'Identifier' && subCallee.name === taroJsReduxConnect) { - const args = declaration.arguments - if (args.length === 1 && args[0].name === componentClassName) { - needExportDefault = true - exportTaroReduxConnected = `${componentClassName}__Connected` - astPath.replaceWith(t.variableDeclaration('const', [t.variableDeclarator(t.identifier(`${componentClassName}__Connected`), t.CallExpression(declaration.callee, declaration.arguments))])) - } - } - } - } - }, - - ExportNamedDeclaration (astPath) { - const node = astPath.node - const source = node.source - if (source && source.type === 'StringLiteral') { - const value = source.value - analyzeImportUrl({ astPath, value, depComponents, sourceFilePath, filePath, styleFiles, scriptFiles, jsonFiles, mediaFiles }) - } - }, - - ExportAllDeclaration (astPath) { - const node = astPath.node - const source = node.source - if (source && source.type === 'StringLiteral') { - const value = source.value - analyzeImportUrl({ astPath, value, depComponents, sourceFilePath, filePath, styleFiles, scriptFiles, jsonFiles, mediaFiles }) - } - }, - - Program: { - exit (astPath) { - astPath.traverse({ - ImportDeclaration (astPath) { - const node = astPath.node - const source = node.source - let value = source.value - analyzeImportUrl({ astPath, value, depComponents, sourceFilePath, filePath, styleFiles, scriptFiles, jsonFiles, mediaFiles }) - }, - CallExpression (astPath) { - const node = astPath.node - const callee = node.callee - if (callee.name === 'require') { - const args = node.arguments - let value = args[0].value - const valueExtname = path.extname(value) - if (value.indexOf('.') === 0) { - let importPath = path.resolve(path.dirname(sourceFilePath), value) - importPath = Util.resolveScriptPath(importPath) - if (isFileToBePage(importPath)) { - if (astPath.parent.type === 'AssignmentExpression' || 'ExpressionStatement') { - astPath.parentPath.remove() - } else if (astPath.parent.type === 'VariableDeclarator') { - astPath.parentPath.parentPath.remove() - } else { - astPath.remove() - } - } else { - if (Util.REG_STYLE.test(valueExtname)) { - const stylePath = path.resolve(path.dirname(sourceFilePath), value) - if (styleFiles.indexOf(stylePath) < 0) { - styleFiles.push(stylePath) - } - if (astPath.parent.type === 'AssignmentExpression' || 'ExpressionStatement') { - astPath.parentPath.remove() - } else if (astPath.parent.type === 'VariableDeclarator') { - astPath.parentPath.parentPath.remove() - } else { - astPath.remove() - } - } else if (Util.REG_JSON.test(valueExtname)) { - const vpath = path.resolve(sourceFilePath, '..', value) - if (jsonFiles.indexOf(vpath) < 0) { - jsonFiles.push(vpath) - } - if (fs.existsSync(vpath)) { - const obj = JSON.parse(fs.readFileSync(vpath).toString()) - let objArr = [t.nullLiteral()] - if (Array.isArray(obj)) { - objArr = t.arrayExpression(astConvert.array(obj)) - } else { - objArr = astConvert.obj(obj) - } - astPath.replaceWith(t.objectExpression(objArr)) - } - } else if (Util.REG_SCRIPT.test(valueExtname) || Util.REG_TYPESCRIPT.test(valueExtname)) { - const vpath = path.resolve(sourceFilePath, '..', value) - let fPath = value - if (fs.existsSync(vpath) && vpath !== sourceFilePath) { - fPath = vpath - } - if (scriptFiles.indexOf(fPath) < 0) { - scriptFiles.push(fPath) - } - } else if (Util.REG_FONT.test(valueExtname) || Util.REG_IMAGE.test(valueExtname) || Util.REG_MEDIA.test(valueExtname)) { - const vpath = path.resolve(sourceFilePath, '..', value) - if (mediaFiles.indexOf(vpath) < 0) { - mediaFiles.push(vpath) - } - let showPath - if (NODE_MODULES_REG.test(vpath)) { - showPath = vpath.replace(nodeModulesPath, `/${weappNpmConfig.name}`) - } else { - showPath = vpath.replace(sourceDir, '') - } - astPath.replaceWith(t.stringLiteral(showPath.replace(/\\/g, '/'))) - } else { - let vpath = Util.resolveScriptPath(path.resolve(sourceFilePath, '..', value)) - let outputVpath - if (NODE_MODULES_REG.test(vpath)) { - outputVpath = vpath.replace(nodeModulesPath, npmOutputDir) - } else { - outputVpath = vpath.replace(sourceDir, outputDir) - } - let relativePath = path.relative(filePath, outputVpath) - if (vpath) { - if (!fs.existsSync(vpath)) { - Util.printLog(Util.pocessTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) - } else { - if (fs.lstatSync(vpath).isDirectory()) { - if (fs.existsSync(path.join(vpath, 'index.js'))) { - vpath = path.join(vpath, 'index.js') - relativePath = path.join(relativePath, 'index.js') - } else { - Util.printLog(Util.pocessTypeEnum.ERROR, '引用目录', `文件 ${sourceFilePath} 中引用了目录 ${value}!`) - return - } - } - if (scriptFiles.indexOf(vpath) < 0) { - scriptFiles.push(vpath) - } - relativePath = Util.promoteRelativePath(relativePath) - relativePath = relativePath.replace(path.extname(relativePath), '.js') - args[0].value = relativePath - } - } - } - } - } - } - } - }) - const node = astPath.node - const exportVariableName = exportTaroReduxConnected || componentClassName - if (needExportDefault) { - const exportDefault = template(`export default ${exportVariableName}`, babylonConfig)() - node.body.push(exportDefault) - } - const taroMiniAppFrameworkPath = !npmSkip ? getExactedNpmFilePath(taroMiniAppFramework, filePath) : taroMiniAppFramework - switch (type) { - case PARSE_AST_TYPE.ENTRY: - const pxTransformConfig = { - designWidth: projectConfig.designWidth || 750 - } - if (projectConfig.hasOwnProperty(DEVICE_RATIO)) { - pxTransformConfig[DEVICE_RATIO] = projectConfig.deviceRatio - } - node.body.push(template(`App(require('${taroMiniAppFrameworkPath}').default.createApp(${exportVariableName}))`, babylonConfig)()) - node.body.push(template(`Taro.initPxTransform(${JSON.stringify(pxTransformConfig)})`, babylonConfig)()) - break - case PARSE_AST_TYPE.PAGE: - if (buildAdapter === Util.BUILD_TYPES.WEAPP) { - node.body.push(template(`Component(require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}, true))`, babylonConfig)()) - } else { - node.body.push(template(`Page(require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}, true))`, babylonConfig)()) - } - break - case PARSE_AST_TYPE.COMPONENT: - node.body.push(template(`Component(require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}))`, babylonConfig)()) - break - default: - break - } - } - } - }) - return { - code: generate(ast).code, - styleFiles, - scriptFiles, - jsonFiles, - configObj, - mediaFiles, - componentClassName - } -} - -function parseComponentExportAst (ast, componentName, componentPath, componentType) { - let componentRealPath = null - let importExportName - ast = babel.transformFromAst(ast, '', { - plugins: [ - [require('babel-plugin-transform-define').default, constantsReplaceList] - ] - }).ast - traverse(ast, { - ExportNamedDeclaration (astPath) { - const node = astPath.node - const specifiers = node.specifiers - const source = node.source - if (source && source.type === 'StringLiteral') { - specifiers.forEach(specifier => { - const exported = specifier.exported - if (_.kebabCase(exported.name) === componentName) { - componentRealPath = Util.resolveScriptPath(path.resolve(path.dirname(componentPath), source.value)) - } - }) - } else { - specifiers.forEach(specifier => { - const exported = specifier.exported - if (_.kebabCase(exported.name) === componentName) { - importExportName = exported.name - } - }) - } - }, - - ExportDefaultDeclaration (astPath) { - const node = astPath.node - const declaration = node.declaration - if (componentType === 'default') { - importExportName = declaration.name - } - }, - - CallExpression (astPath) { - if (astPath.get('callee').isIdentifier({ name: 'require' })) { - const arg = astPath.get('arguments')[0] - if (t.isStringLiteral(arg.node)) { - componentRealPath = Util.resolveScriptPath(path.resolve(path.dirname(componentPath), arg.node.value)) - } - } - }, - - Program: { - exit (astPath) { - astPath.traverse({ - ImportDeclaration (astPath) { - const node = astPath.node - const specifiers = node.specifiers - const source = node.source - if (importExportName) { - specifiers.forEach(specifier => { - const local = specifier.local - if (local.name === importExportName) { - componentRealPath = Util.resolveScriptPath(path.resolve(path.dirname(componentPath), source.value)) - } - }) - } - } - }) - } - } - }) - return componentRealPath -} - -function isFileToBeTaroComponent (code, sourcePath, outputPath) { - const transformResult = wxTransformer({ - code, - sourcePath: sourcePath, - outputPath: outputPath, - isNormal: true, - isTyped: Util.REG_TYPESCRIPT.test(sourcePath), - adapter: buildAdapter, - env: constantsReplaceList, - jsxAttributeNameReplace: weappConf.jsxAttributeNameReplace - }) - const { ast } = transformResult - let isTaroComponent = false - - traverse(ast, { - ClassDeclaration (astPath) { - astPath.traverse({ - ClassMethod (astPath) { - if (astPath.get('key').isIdentifier({ name: 'render' })) { - astPath.traverse({ - JSXElement () { - isTaroComponent = true - } - }) - } - } - }) - }, - - ClassExpression (astPath) { - astPath.traverse({ - ClassMethod (astPath) { - if (astPath.get('key').isIdentifier({ name: 'render' })) { - astPath.traverse({ - JSXElement () { - isTaroComponent = true - } - }) - } - } - }) - } - }) - - return { - isTaroComponent, - transformResult - } -} - -function isFileToBePage (filePath) { - let isPage = false - const extname = path.extname(filePath) - const pages = appConfig.pages || [] - const filePathWithoutExt = filePath.replace(extname, '') - pages.forEach(page => { - if (filePathWithoutExt === path.join(sourceDir, page)) { - isPage = true - } - }) - return isPage && Util.REG_SCRIPTS.test(extname) -} - -function copyFilesFromSrcToOutput (files) { - files.forEach(file => { - let outputFilePath - if (NODE_MODULES_REG.test(file)) { - outputFilePath = file.replace(nodeModulesPath, npmOutputDir) - } else { - outputFilePath = file.replace(sourceDir, outputDir) - } - if (isCopyingFiles[outputFilePath]) { - return - } - isCopyingFiles[outputFilePath] = true - let modifySrc = file.replace(appPath + path.sep, '') - modifySrc = modifySrc.split(path.sep).join('/') - let modifyOutput = outputFilePath.replace(appPath + path.sep, '') - modifyOutput = modifyOutput.split(path.sep).join('/') - Util.printLog(Util.pocessTypeEnum.COPY, '文件', modifyOutput) - if (!fs.existsSync(file)) { - Util.printLog(Util.pocessTypeEnum.ERROR, '文件', `${modifySrc} 不存在`) - } else { - fs.ensureDir(path.dirname(outputFilePath)) - if (file === outputFilePath) { - return - } - fs.copySync(file, outputFilePath) - } - }) -} - -const babelConfig = _.mergeWith({}, defaultBabelConfig, pluginsConfig.babel, (objValue, srcValue) => { - if (Array.isArray(objValue)) { - return Array.from(new Set(srcValue.concat(objValue))) - } -}) - -const shouldTransformAgain = (function () { - const pluginsStr = JSON.stringify(babelConfig.plugins) - if (/transform-runtime/.test(pluginsStr)) { - return true - } - return false -})() - -async function compileScriptFile (content, sourceFilePath, outputFilePath, adapter) { - if (NODE_MODULES_REG.test(sourceFilePath) && fs.existsSync(outputFilePath)) { - return fs.readFileSync(outputFilePath).toString() - } - const compileScriptRes = await npmProcess.callPlugin('babel', content, sourceFilePath, babelConfig) - const code = compileScriptRes.code - if (!shouldTransformAgain) { - return code - } - const transformResult = wxTransformer({ - code, - sourcePath: sourceFilePath, - outputPath: outputFilePath, - isNormal: true, - isTyped: false, - adapter, - env: constantsReplaceList, - jsxAttributeNameReplace: weappConf.jsxAttributeNameReplace - }) - const res = parseAst(PARSE_AST_TYPE.NORMAL, transformResult.ast, [], sourceFilePath, outputFilePath) - return res.code -} - -// async function checkCliAndFrameworkVersion () { -// const frameworkName = `@tarojs/taro-${buildAdapter}` -// const frameworkVersion = Util.getInstalledNpmPkgVersion(frameworkName, nodeModulesPath) -// if (frameworkVersion) { -// if (frameworkVersion !== Util.getPkgVersion()) { -// Util.printLog(Util.pocessTypeEnum.ERROR, '版本问题', `Taro CLI 与本地安装的小程序框架 ${frameworkName} 版本不一致,请确保一致`) -// console.log(`Taro CLI: ${Util.getPkgVersion()}`) -// console.log(`${frameworkName}: ${frameworkVersion}`) -// process.exit(1) -// } -// } else { -// Util.printLog(Util.pocessTypeEnum.WARNING, '依赖安装', chalk.red(`项目依赖 ${frameworkName} 未安装,或安装有误!`)) -// } -// } - -function buildProjectConfig () { - let projectConfigFileName = `project.${buildAdapter}.json` - if (buildAdapter === Util.BUILD_TYPES.WEAPP) { - projectConfigFileName = 'project.config.json' - } - let projectConfigPath = path.join(appPath, projectConfigFileName) - - if (!fs.existsSync(projectConfigPath)) { - projectConfigPath = path.join(sourceDir, projectConfigFileName) - if (!fs.existsSync(projectConfigPath)) return - } - - const origProjectConfig = fs.readJSONSync(projectConfigPath) - if (buildAdapter === Util.BUILD_TYPES.TT) { - projectConfigFileName = 'project.config.json' - } - fs.ensureDirSync(outputDir) - fs.writeFileSync( - path.join(outputDir, projectConfigFileName), - JSON.stringify(Object.assign({}, origProjectConfig, { miniprogramRoot: './' }), null, 2) - ) - Util.printLog(Util.pocessTypeEnum.GENERATE, '工具配置', `${outputDirName}/${projectConfigFileName}`) -} - -async function buildFrameworkInfo () { - // 百度小程序编译出 .frameworkinfo 文件 - if (buildAdapter === Util.BUILD_TYPES.SWAN) { - const frameworkInfoFileName = '.frameworkinfo' - const frameworkName = `@tarojs/taro-${buildAdapter}` - const frameworkVersion = Util.getInstalledNpmPkgVersion(frameworkName, nodeModulesPath) - if (frameworkVersion) { - const frameworkinfo = { - toolName: 'Taro', - toolCliVersion: Util.getPkgVersion(), - toolFrameworkVersion: frameworkVersion, - createTime: new Date(projectConfig.date).getTime() - } - fs.writeFileSync( - path.join(outputDir, frameworkInfoFileName), - JSON.stringify(frameworkinfo, null, 2) - ) - Util.printLog(Util.pocessTypeEnum.GENERATE, '框架信息', `${outputDirName}/${frameworkInfoFileName}`) - } else { - Util.printLog(Util.pocessTypeEnum.WARNING, '依赖安装', chalk.red(`项目依赖 ${frameworkName} 未安装,或安装有误!`)) - } - } -} - -function buildWorkers (worker) { - Util.printLog(Util.pocessTypeEnum.COMPILE, 'Workers', '编译 worker 相关文件') - const workerDir = path.join(sourceDir, worker) - function fileRecursiveSearch (fileDir) { - fs.readdir(fileDir, (err, files) => { - if (err) { - console.warn(err) - } else { - files.forEach(filename => { - const filePath = path.join(fileDir, filename) - fs.stat(filePath, (err, stats) => { - if (err) { - console.warn(err) - } else { - const isFile = stats.isFile() - const isDir = stats.isDirectory() - if (isFile) { - if (Util.REG_SCRIPTS.test(filePath)) { - compileDepScripts([filePath]) - } else { - copyFilesFromSrcToOutput([filePath]) - } - } else if (isDir) { - fileRecursiveSearch(filePath) - } - } - }) - }) - } - }) - } - fileRecursiveSearch(workerDir) -} - -async function buildCustomTabbar () { - const customTabbarPath = path.join(sourceDir, 'custom-tab-bar') - const customTabbarJSPath = Util.resolveScriptPath(customTabbarPath) - await buildSingleComponent({ - path: customTabbarJSPath, - name: 'custom-tab-bar' - }) -} - -async function buildEntry () { - Util.printLog(Util.pocessTypeEnum.COMPILE, '入口文件', `${sourceDirName}/${entryFileName}`) - const entryFileCode = fs.readFileSync(entryFilePath).toString() - try { - const transformResult = wxTransformer({ - code: entryFileCode, - sourcePath: entryFilePath, - outputPath: outputEntryFilePath, - isApp: true, - isTyped: Util.REG_TYPESCRIPT.test(entryFilePath), - adapter: buildAdapter, - env: constantsReplaceList, - jsxAttributeNameReplace: weappConf.jsxAttributeNameReplace - }) - // app.js的template忽略 - const res = parseAst(PARSE_AST_TYPE.ENTRY, transformResult.ast, [], entryFilePath, outputEntryFilePath) - let resCode = res.code - resCode = await compileScriptFile(resCode, entryFilePath, outputEntryFilePath, buildAdapter) - if (isProduction) { - const uglifyPluginConfig = pluginsConfig.uglify || { enable: true } - if (uglifyPluginConfig.enable) { - const uglifyConfig = Object.assign(defaultUglifyConfig, uglifyPluginConfig.config || {}) - const uglifyResult = npmProcess.callPluginSync('uglifyjs', resCode, entryFilePath, uglifyConfig) - if (uglifyResult.error) { - Util.printLog(Util.pocessTypeEnum.ERROR, '压缩错误', `文件${entryFilePath}`) - console.log(uglifyResult.error) - } else { - resCode = uglifyResult.code - } - } - } - if (appOutput) { - fs.writeFileSync(path.join(outputDir, 'app.json'), JSON.stringify(res.configObj, null, 2)) - Util.printLog(Util.pocessTypeEnum.GENERATE, '入口配置', `${outputDirName}/app.json`) - fs.writeFileSync(path.join(outputDir, 'app.js'), resCode) - Util.printLog(Util.pocessTypeEnum.GENERATE, '入口文件', `${outputDirName}/app.js`) - } - if (res.configObj.workers) { - buildWorkers(res.configObj.workers) - } - if (res.configObj.tabBar && res.configObj.tabBar.custom) { - await buildCustomTabbar() - } - const fileDep = dependencyTree[entryFilePath] || {} - // 编译依赖的脚本文件 - if (Util.isDifferentArray(fileDep['script'], res.scriptFiles)) { - compileDepScripts(res.scriptFiles) - } - // 编译样式文件 - if (Util.isDifferentArray(fileDep['style'], res.styleFiles) && appOutput) { - await compileDepStyles(path.join(outputDir, `app${outputFilesTypes.STYLE}`), res.styleFiles, false) - Util.printLog(Util.pocessTypeEnum.GENERATE, '入口样式', `${outputDirName}/app${outputFilesTypes.STYLE}`) - } - // 拷贝依赖文件 - if (Util.isDifferentArray(fileDep['json'], res.jsonFiles)) { - copyFilesFromSrcToOutput(res.jsonFiles) - } - - // 处理res.configObj 中的tabBar配置 - const tabBar = res.configObj.tabBar - if (tabBar && typeof tabBar === 'object' && !Util.isEmptyObject(tabBar)) { - const { - list: listConfig, - iconPath: pathConfig, - selectedIconPath: selectedPathConfig - } = Util.CONFIG_MAP[buildAdapter] - const list = tabBar[listConfig] || [] - let tabBarIcons = [] - list.forEach(item => { - item[pathConfig] && tabBarIcons.push(item[pathConfig]) - item[selectedPathConfig] && tabBarIcons.push(item[selectedPathConfig]) - }) - tabBarIcons = tabBarIcons.map(item => path.resolve(sourceDir, item)) - if (tabBarIcons && tabBarIcons.length) { - res.mediaFiles = res.mediaFiles.concat(tabBarIcons) - } - } - if (Util.isDifferentArray(fileDep['media'], res.mediaFiles)) { - copyFilesFromSrcToOutput(res.mediaFiles) - } - fileDep['style'] = res.styleFiles - fileDep['script'] = res.scriptFiles - fileDep['json'] = res.jsonFiles - fileDep['media'] = res.mediaFiles - dependencyTree[entryFilePath] = fileDep - return res.configObj - } catch (err) { - console.log(err) - } -} - -async function buildPages () { - Util.printLog(Util.pocessTypeEnum.COMPILE, '所有页面') - // 支持分包,解析子包页面 - const pages = appConfig.pages || [] - const subPackages = appConfig.subPackages || appConfig.subpackages - if (subPackages && subPackages.length) { - subPackages.forEach(item => { - if (item.pages && item.pages.length) { - const root = item.root - item.pages.forEach(page => { - let pagePath = `${root}/${page}` - pagePath = pagePath.replace(/\/{2,}/g, '/') - if (pages.indexOf(pagePath) < 0) { - pages.push(pagePath) - } - }) - } - }) - } - const pagesPromises = pages.map(async page => { - return buildSinglePage(page) - }) - await Promise.all(pagesPromises) -} - -function processNativeWxml (componentWXMLPath, componentWXMLContent, outputComponentWXMLPath) { - let wxmlContent - let needCopy = true - if (componentWXMLPath && fs.existsSync(componentWXMLPath)) { - wxmlContent = fs.readFileSync(componentWXMLPath).toString() - } else { - needCopy = false - wxmlContent = componentWXMLContent - } - const importWxmlPathList = [] - let regResult - while ((regResult = Util.REG_WXML_IMPORT.exec(wxmlContent)) != null) { - importWxmlPathList.push(regResult[2] || regResult[3]) - } - if (importWxmlPathList.length) { - importWxmlPathList.forEach(item => { - const itemPath = path.resolve(componentWXMLPath, '..', item) - if (fs.existsSync(itemPath)) { - const outputItemPath = itemPath.replace(sourceDir, outputDir) - processNativeWxml(itemPath, null, outputItemPath) - } - }) - } - if (componentWXMLPath === outputComponentWXMLPath || !needCopy) { - return - } - copyFileSync(componentWXMLPath, outputComponentWXMLPath) -} - -function transfromNativeComponents (configFile, componentConfig) { - const usingComponents = componentConfig.usingComponents - if (usingComponents && !Util.isEmptyObject(usingComponents)) { - Object.keys(usingComponents).map(async item => { - let componentPath = usingComponents[item] - - if (Util.isAliasPath(componentPath, pathAlias)) { - componentPath = Util.replaceAliasPath(configFile, componentPath, pathAlias) - usingComponents[item] = componentPath - } - - if (/^plugin:\/\//.test(componentPath)) { - // 小程序 plugin - Util.printLog(Util.pocessTypeEnum.REFERENCE, '插件引用', `使用了插件 ${chalk.bold(componentPath)}`) - return - } - let componentJSPath = Util.resolveScriptPath(path.resolve(path.dirname(configFile), componentPath)) - if (!fs.existsSync(componentJSPath)) { - componentJSPath = Util.resolveScriptPath(path.join(sourceDir, componentPath)) - } - const componentJSONPath = componentJSPath.replace(path.extname(componentJSPath), outputFilesTypes.CONFIG) - const componentWXMLPath = componentJSPath.replace(path.extname(componentJSPath), outputFilesTypes.TEMPL) - const componentWXSSPath = componentJSPath.replace(path.extname(componentJSPath), outputFilesTypes.STYLE) - const outputComponentJSPath = componentJSPath.replace(sourceDir, outputDir).replace(path.extname(componentJSPath), outputFilesTypes.SCRIPT) - if (fs.existsSync(componentJSPath)) { - const componentJSContent = fs.readFileSync(componentJSPath).toString() - if (componentJSContent.indexOf(taroJsFramework) >= 0 && !fs.existsSync(componentWXMLPath)) { - const buildDepComponentsRes = await buildDepComponents([componentJSPath]) - return buildDepComponentsRes - } - compileDepScripts([componentJSPath]) - } else { - return Util.printLog(Util.pocessTypeEnum.ERROR, '编译错误', `原生组件文件 ${componentJSPath} 不存在!`) - } - if (fs.existsSync(componentWXMLPath)) { - const outputComponentWXMLPath = outputComponentJSPath.replace(path.extname(outputComponentJSPath), outputFilesTypes.TEMPL) - processNativeWxml(componentWXMLPath, null, outputComponentWXMLPath) - } - if (fs.existsSync(componentWXSSPath)) { - const outputComponentWXSSPath = outputComponentJSPath.replace(path.extname(outputComponentJSPath), outputFilesTypes.STYLE) - await compileDepStyles(outputComponentWXSSPath, [componentWXSSPath], true) - } - if (fs.existsSync(componentJSONPath)) { - const componentJSON = require(componentJSONPath) - const outputComponentJSONPath = outputComponentJSPath.replace(path.extname(outputComponentJSPath), outputFilesTypes.CONFIG) - copyFileSync(componentJSONPath, outputComponentJSONPath) - - // 解决组件循环依赖不断编译爆栈的问题 - if (componentJSON && componentJSON.usingComponents) { - Object.keys(componentJSON.usingComponents).forEach(key => { - if (key === item) { - delete componentJSON.usingComponents[key] - } - }) - } - - transfromNativeComponents(componentJSONPath, componentJSON) - } - }) - } -} - -// 小程序页面编译 -async function buildSinglePage (page) { - Util.printLog(Util.pocessTypeEnum.COMPILE, '页面文件', `${sourceDirName}/${page}`) - const pagePath = path.join(sourceDir, `${page}`) - let pageJs = Util.resolveScriptPath(pagePath) - if (!fs.existsSync(pageJs)) { - Util.printLog(Util.pocessTypeEnum.ERROR, '页面文件', `${sourceDirName}/${page} 不存在!`) - return - } - const pageJsContent = fs.readFileSync(pageJs).toString() - const outputPageJSPath = pageJs.replace(sourceDir, outputDir).replace(path.extname(pageJs), outputFilesTypes.SCRIPT) - const outputPagePath = path.dirname(outputPageJSPath) - const outputPageJSONPath = outputPageJSPath.replace(path.extname(outputPageJSPath), outputFilesTypes.CONFIG) - const outputPageWXMLPath = outputPageJSPath.replace(path.extname(outputPageJSPath), outputFilesTypes.TEMPL) - const outputPageWXSSPath = outputPageJSPath.replace(path.extname(outputPageJSPath), outputFilesTypes.STYLE) - // 判断是不是小程序原生代码页面 - const pageWXMLPath = pageJs.replace(path.extname(pageJs), outputFilesTypes.TEMPL) - if (fs.existsSync(pageWXMLPath) && pageJsContent.indexOf(taroJsFramework) < 0) { - const pageJSONPath = pageJs.replace(path.extname(pageJs), outputFilesTypes.CONFIG) - const pageWXSSPath = pageJs.replace(path.extname(pageJs), outputFilesTypes.STYLE) - if (fs.existsSync(pageJSONPath)) { - const pageJSON = require(pageJSONPath) - copyFileSync(pageJSONPath, outputPageJSONPath) - transfromNativeComponents(pageJSONPath, pageJSON) - } - compileDepScripts([pageJs]) - copyFileSync(pageWXMLPath, outputPageWXMLPath) - if (fs.existsSync(pageWXSSPath)) { - await compileDepStyles(outputPageWXSSPath, [pageWXSSPath], false) - } - return - } - try { - const transformResult = wxTransformer({ - code: pageJsContent, - sourcePath: pageJs, - outputPath: outputPageJSPath, - isRoot: true, - isTyped: Util.REG_TYPESCRIPT.test(pageJs), - adapter: buildAdapter, - env: constantsReplaceList, - jsxAttributeNameReplace: weappConf.jsxAttributeNameReplace - }) - const pageDepComponents = transformResult.components - const compressTemplate = useCompileConf.compressTemplate - const pageWXMLContent = (isProduction && compressTemplate) ? transformResult.compressedTemplate : transformResult.template - const res = parseAst(PARSE_AST_TYPE.PAGE, transformResult.ast, pageDepComponents, pageJs, outputPageJSPath) - let resCode = res.code - resCode = await compileScriptFile(resCode, pageJs, outputPageJSPath, buildAdapter) - if (isProduction) { - const uglifyPluginConfig = pluginsConfig.uglify || { enable: true } - if (uglifyPluginConfig.enable) { - const uglifyConfig = Object.assign(defaultUglifyConfig, uglifyPluginConfig.config || {}) - const uglifyResult = npmProcess.callPluginSync('uglifyjs', resCode, outputPageJSPath, uglifyConfig) - if (uglifyResult.error) { - Util.printLog(Util.pocessTypeEnum.ERROR, '压缩错误', `文件${pageJs}`) - console.log(uglifyResult.error) - } else { - resCode = uglifyResult.code - } - } - } - fs.ensureDirSync(outputPagePath) - const { usingComponents = {} } = res.configObj - if (usingComponents && !Util.isEmptyObject(usingComponents)) { - const keys = Object.keys(usingComponents) - keys.forEach(item => { - pageDepComponents.forEach(component => { - if (_.camelCase(item) === _.camelCase(component.name)) { - delete usingComponents[item] - } - }) - }) - transfromNativeComponents(outputPageJSONPath.replace(outputDir, sourceDir), res.configObj) - } - const fileDep = dependencyTree[pageJs] || {} - // 编译依赖的组件文件 - let buildDepComponentsResult = [] - let realComponentsPathList = [] - if (pageDepComponents.length) { - realComponentsPathList = getRealComponentsPathList(pageJs, pageDepComponents) - res.scriptFiles = res.scriptFiles.map(item => { - for (let i = 0; i < realComponentsPathList.length; i++) { - const componentObj = realComponentsPathList[i] - const componentPath = componentObj.path - if (item === componentPath) { - return null - } - } - return item - }).filter(item => item) - buildDepComponentsResult = await buildDepComponents(realComponentsPathList) - } - if (!Util.isEmptyObject(componentExportsMap) && realComponentsPathList.length) { - const mapKeys = Object.keys(componentExportsMap) - realComponentsPathList.forEach(component => { - if (mapKeys.indexOf(component.path) >= 0) { - const componentMap = componentExportsMap[component.path] - componentMap.forEach(component => { - pageDepComponents.forEach(depComponent => { - if (depComponent.name === component.name) { - let componentPath = component.path - let realPath - if (NODE_MODULES_REG.test(componentPath)) { - componentPath = componentPath.replace(nodeModulesPath, npmOutputDir) - realPath = Util.promoteRelativePath(path.relative(outputPageJSPath, componentPath)) - } else { - realPath = Util.promoteRelativePath(path.relative(pageJs, componentPath)) - } - depComponent.path = realPath.replace(path.extname(realPath), '') - } - }) - }) - } - }) - } - fs.writeFileSync(outputPageJSONPath, JSON.stringify(_.merge({}, buildUsingComponents(pageJs, pageDepComponents), res.configObj), null, 2)) - Util.printLog(Util.pocessTypeEnum.GENERATE, '页面配置', `${outputDirName}/${page}${outputFilesTypes.CONFIG}`) - fs.writeFileSync(outputPageJSPath, resCode) - Util.printLog(Util.pocessTypeEnum.GENERATE, '页面逻辑', `${outputDirName}/${page}${outputFilesTypes.SCRIPT}`) - fs.writeFileSync(outputPageWXMLPath, pageWXMLContent) - processNativeWxml(outputPageWXMLPath.replace(outputDir, sourceDir), pageWXMLContent, outputPageWXMLPath) - Util.printLog(Util.pocessTypeEnum.GENERATE, '页面模板', `${outputDirName}/${page}${outputFilesTypes.TEMPL}`) - // 编译依赖的脚本文件 - if (Util.isDifferentArray(fileDep['script'], res.scriptFiles)) { - compileDepScripts(res.scriptFiles) - } - // 编译样式文件 - if (Util.isDifferentArray(fileDep['style'], res.styleFiles) || Util.isDifferentArray(depComponents[pageJs], pageDepComponents)) { - Util.printLog(Util.pocessTypeEnum.GENERATE, '页面样式', `${outputDirName}/${page}${outputFilesTypes.STYLE}`) - const depStyleList = getDepStyleList(outputPageWXSSPath, buildDepComponentsResult) - wxssDepTree[outputPageWXSSPath] = depStyleList - await compileDepStyles(outputPageWXSSPath, res.styleFiles, false) - } - // 拷贝依赖文件 - if (Util.isDifferentArray(fileDep['json'], res.jsonFiles)) { - copyFilesFromSrcToOutput(res.jsonFiles) - } - if (Util.isDifferentArray(fileDep['media'], res.mediaFiles)) { - copyFilesFromSrcToOutput(res.mediaFiles) - } - depComponents[pageJs] = pageDepComponents - fileDep['style'] = res.styleFiles - fileDep['script'] = res.scriptFiles - fileDep['json'] = res.jsonFiles - fileDep['media'] = res.mediaFiles - dependencyTree[pageJs] = fileDep - } catch (err) { - Util.printLog(Util.pocessTypeEnum.ERROR, '页面编译', `页面${pagePath}编译失败!`) - console.log(err) - } -} - -/** - * css module processor - * @param styleObj { css: string, filePath: '' } - * @returns postcss.process() - */ -function processStyleUseCssModule (styleObj) { - const useModuleConf = weappConf.module || {} - const customPostcssConf = useModuleConf.postcss || {} - const customCssModulesConf = Object.assign({ - enable: false, - config: { - generateScopedName: '[name]__[local]___[hash:base64:5]', - namingPattern: 'global' - } - }, customPostcssConf.cssModules || {}) - if (!customCssModulesConf.enable) { - return styleObj - } - const namingPattern = customCssModulesConf.config.namingPattern - if (namingPattern === 'module') { - // 只对 xxx.module.[css|scss|less|styl] 等样式文件做处理 - const DO_USE_CSS_MODULE_REGEX = /^(.*\.module).*\.(css|scss|less|styl)$/ - if (!DO_USE_CSS_MODULE_REGEX.test(styleObj.filePath)) return styleObj - } else { - // 对 xxx.global.[css|scss|less|styl] 等样式文件不做处理 - const DO_NOT_USE_CSS_MODULE_REGEX = /^(.*\.global).*\.(css|scss|less|styl)$/ - if (DO_NOT_USE_CSS_MODULE_REGEX.test(styleObj.filePath)) return styleObj - } - const generateScopedName = customCssModulesConf.config.generateScopedName - const context = process.cwd() - let scopedName - if (generateScopedName) { - scopedName = typeof generateScopedName === 'function' - ? (local, filename) => generateScopedName(local, filename) - : genericNames(generateScopedName, { context }) - } else { - scopedName = (local, filename) => Scope.generateScopedName(local, path.relative(context, filename)) - } - const postcssPlugins = [ - Values, - LocalByDefault, - ExtractImports, - new Scope({ generateScopedName: scopedName }), - new ResolveImports({ resolve: Object.assign({}, { extensions: Util.CSS_EXT }) }) - ] - const runner = postcss(postcssPlugins) - const result = runner.process(styleObj.css, Object.assign({}, { from: styleObj.filePath })) - return result -} - -function createCssModuleMap (styleFilePath, tokens) { - const cssModuleMapFilename = path.basename(styleFilePath) + '.map.js' - const cssModuleMapFile = path.join(path.dirname(styleFilePath), cssModuleMapFilename).replace(sourceDir, outputDir) - Util.printLog(Util.pocessTypeEnum.GENERATE, 'CSS Modules map', cssModuleMapFile) - fs.ensureDirSync(path.dirname(cssModuleMapFile)) - fs.writeFileSync(cssModuleMapFile, `module.exports = ${JSON.stringify(tokens, null, 2)};\n`) - return cssModuleMapFile -} - -async function processStyleWithPostCSS (styleObj) { - const useModuleConf = weappConf.module || {} - const customPostcssConf = useModuleConf.postcss || {} - const customCssModulesConf = Object.assign({ - enable: false, - config: { - generateScopedName: '[name]__[local]___[hash:base64:5]' - } - }, customPostcssConf.cssModules || {}) - const customPxtransformConf = Object.assign({ - enable: true, - config: {} - }, customPostcssConf.pxtransform || {}) - const customUrlConf = Object.assign({ - enable: true, - config: { - limit: 10240 - } - }, customPostcssConf.url || {}) - const customAutoprefixerConf = Object.assign({ - enable: true, - config: { - browsers: browserList - } - }, customPostcssConf.autoprefixer || {}) - const postcssPxtransformOption = { - designWidth: projectConfig.designWidth || 750, - platform: 'weapp' - } - - if (projectConfig.hasOwnProperty(DEVICE_RATIO)) { - postcssPxtransformOption[DEVICE_RATIO] = projectConfig.deviceRatio - } - const cssUrlConf = Object.assign({ limit: 10240 }, customUrlConf) - const maxSize = Math.round((customUrlConf.config.limit || cssUrlConf.limit) / 1024) - const postcssPxtransformConf = Object.assign({}, postcssPxtransformOption, customPxtransformConf, customPxtransformConf.config) - const processors = [] - if (customAutoprefixerConf.enable) { - processors.push(autoprefixer(customAutoprefixerConf.config)) - } - if (customPxtransformConf.enable) { - processors.push(pxtransform(postcssPxtransformConf)) - } - if (cssUrlConf.enable) { - processors.push(cssUrlParse({ - url: 'inline', - maxSize, - encodeType: 'base64' - })) - } - - const defaultPostCSSPluginNames = ['autoprefixer', 'pxtransform', 'url', 'cssModules'] - Object.keys(customPostcssConf).forEach(pluginName => { - if (defaultPostCSSPluginNames.indexOf(pluginName) < 0) { - const pluginConf = customPostcssConf[pluginName] - if (pluginConf && pluginConf.enable) { - if (!Util.isNpmPkg(pluginName)) { // local plugin - pluginName = path.join(appPath, pluginName) - } - processors.push(require(resolveNpmPkgMainPath(pluginName, isProduction, weappNpmConfig, buildAdapter))(pluginConf.config || {})) - } - } - }) - let css = styleObj.css - if (customCssModulesConf.enable) { - const result = processStyleUseCssModule(styleObj) - css = result.css - if (result.root && result.root.exports) { - createCssModuleMap(styleObj.filePath, result.root.exports || {}) - } - } - const postcssResult = await postcss(processors).process(css, { - from: styleObj.filePath - }) - return postcssResult.css -} - -function compileImportStyles (filePath, importStyles) { - if (importStyles.length) { - importStyles.forEach(async importItem => { - const importFilePath = path.resolve(filePath, '..', importItem) - if (fs.existsSync(importFilePath)) { - await compileDepStyles(importFilePath.replace(sourceDir, outputDir), [importFilePath]) - } - }) - } -} - -function compileDepStyles (outputFilePath, styleFiles, isComponent) { - if (isBuildingStyles[outputFilePath]) { - return Promise.resolve({}) - } - isBuildingStyles[outputFilePath] = true - return Promise.all(styleFiles.map(async p => { - const filePath = path.join(p) - const fileExt = path.extname(filePath) - const pluginName = Util.FILE_PROCESSOR_MAP[fileExt] - const fileContent = fs.readFileSync(filePath).toString() - const cssImportsRes = Util.processStyleImports(fileContent, buildAdapter, (str, stylePath) => { - if (stylePath.indexOf('~') === 0) { - let newStylePath = stylePath - newStylePath = stylePath.replace('~', '') - const npmInfo = resolveNpmFilesPath(newStylePath, isProduction, weappNpmConfig, buildAdapter, appPath, compileInclude) - const importRelativePath = Util.promoteRelativePath(path.relative(filePath, npmInfo.main)) - return str.replace(stylePath, importRelativePath) - } - return str - }) - compileImportStyles(filePath, cssImportsRes.imports) - if (pluginName) { - return npmProcess.callPlugin(pluginName, cssImportsRes.content, filePath, pluginsConfig[pluginName] || {}) - .then(res => ({ - css: cssImportsRes.style.join('\n') + '\n' + res.css, - filePath - })).catch(err => { - if (err) { - console.log(err) - process.exit(0) - } - }) - } - return new Promise(resolve => { - resolve({ - css: cssImportsRes.style.join('\n') + '\n' + cssImportsRes.content, - filePath - }) - }) - })).then(async resList => { - await Promise.all(resList.map(res => processStyleWithPostCSS(res))) - .then(cssList => { - let resContent = cssList.map(res => res).join('\n') - if (isProduction) { - const cssoPuginConfig = pluginsConfig.csso || { enable: true } - if (cssoPuginConfig.enable) { - const cssoConfig = cssoPuginConfig.config || {} - const cssoResult = npmProcess.callPluginSync('csso', resContent, outputFilePath, cssoConfig) - resContent = cssoResult.css - } - } - fs.ensureDirSync(path.dirname(outputFilePath)) - fs.writeFileSync(outputFilePath, resContent) - }) - }) -} - -function getRealComponentsPathList (filePath, components) { - return components.map(component => { - let componentPath = component.path - if (Util.isAliasPath(componentPath, pathAlias)) { - componentPath = Util.replaceAliasPath(filePath, componentPath, pathAlias) - } - if (Util.isNpmPkg(componentPath)) { - try { - componentPath = resolveNpmPkgMainPath(componentPath, isProduction, weappNpmConfig, buildAdapter) - } catch (err) { - console.log(err) - } - } else { - componentPath = path.resolve(path.dirname(filePath), componentPath) - componentPath = Util.resolveScriptPath(componentPath) - } - if (isFileToBePage(componentPath)) { - Util.printLog(Util.pocessTypeEnum.ERROR, '组件引用', `文件${component.path}已经在 app.js 中被指定为页面,不能再作为组件来引用!`) - } - return { - path: componentPath, - name: component.name, - type: component.type - } - }) -} - -function buildDepComponents (componentPathList, buildConfig) { - return Promise.all(componentPathList.map(componentObj => buildSingleComponent(componentObj, buildConfig))) -} - -function getDepStyleList (outputFilePath, buildDepComponentsResult) { - let depWXSSList = [] - if (buildDepComponentsResult.length) { - depWXSSList = buildDepComponentsResult.map(item => { - let wxss = item.wxss - wxss = wxss.replace(sourceDir, outputDir) - wxss = Util.promoteRelativePath(path.relative(outputFilePath, wxss)) - return wxss - }) - } - return depWXSSList -} - -function buildUsingComponents (filePath, components, isComponent) { - const usingComponents = Object.create(null) - for (const component of components) { - let componentPath = component.path - if (Util.isAliasPath(componentPath, pathAlias)) { - componentPath = Util.replaceAliasPath(filePath, componentPath, pathAlias) - } - componentPath = Util.resolveScriptPath(path.resolve(filePath, '..', componentPath)) - if (fs.existsSync(componentPath)) { - componentPath = Util.promoteRelativePath(path.relative(filePath, componentPath)) - } else { - componentPath = component.path - } - usingComponents[component.name] = componentPath.replace(path.extname(componentPath), '') - } - return Object.assign({}, isComponent ? { component: true } : { usingComponents: {} }, components.length ? { - usingComponents - } : {}) -} - -async function buildSingleComponent (componentObj, buildConfig = {}) { - if (hasBeenBuiltComponents.indexOf(componentObj.path) >= 0 && componentsBuildResult[componentObj.path]) { - return componentsBuildResult[componentObj.path] - } - componentsNamedMap[componentObj.path] = { - name: componentObj.name, - type: componentObj.type - } - const component = componentObj.path - if (!component) { - Util.printLog(Util.pocessTypeEnum.ERROR, '组件错误', `组件${_.upperFirst(_.camelCase(componentObj.name))}路径错误,请检查!(可能原因是导出的组件名不正确)`) - return { - js: null, - wxss: null, - wxml: null - } - } - let componentShowPath = component.replace(appPath + path.sep, '') - componentShowPath = componentShowPath.split(path.sep).join('/') - let isComponentFromNodeModules = false - let sourceDirPath = sourceDir - let buildOutputDir = outputDir - // 来自 node_modules 的组件 - if (NODE_MODULES_REG.test(componentShowPath)) { - isComponentFromNodeModules = true - sourceDirPath = nodeModulesPath - buildOutputDir = npmOutputDir - } - let outputComponentShowPath = componentShowPath.replace(isComponentFromNodeModules ? NODE_MODULES : sourceDirName, buildConfig.outputDirName || outputDirName) - outputComponentShowPath = outputComponentShowPath.replace(path.extname(outputComponentShowPath), '') - Util.printLog(Util.pocessTypeEnum.COMPILE, '组件文件', componentShowPath) - const componentContent = fs.readFileSync(component).toString() - const outputComponentJSPath = component.replace(sourceDirPath, buildConfig.outputDir || buildOutputDir).replace(path.extname(component), outputFilesTypes.SCRIPT) - const outputComponentWXMLPath = outputComponentJSPath.replace(path.extname(outputComponentJSPath), outputFilesTypes.TEMPL) - const outputComponentWXSSPath = outputComponentJSPath.replace(path.extname(outputComponentJSPath), outputFilesTypes.STYLE) - const outputComponentJSONPath = outputComponentJSPath.replace(path.extname(outputComponentJSPath), outputFilesTypes.CONFIG) - if (hasBeenBuiltComponents.indexOf(component) < 0) { - hasBeenBuiltComponents.push(component) - } - try { - let isTaroComponentRes = isFileToBeTaroComponent(componentContent, component, outputComponentJSPath) - if (!isTaroComponentRes.isTaroComponent) { - const transformResult = isTaroComponentRes.transformResult - const componentRealPath = parseComponentExportAst(transformResult.ast, componentObj.name, component, componentObj.type) - const realComponentObj = { - path: componentRealPath, - name: componentObj.name, - type: componentObj.type - } - let isInMap = false - if (notTaroComponents.indexOf(component) < 0) { - notTaroComponents.push(component) - } - if (!Util.isEmptyObject(componentExportsMap)) { - Object.keys(componentExportsMap).forEach(key => { - componentExportsMap[key].forEach(item => { - if (item.path === component) { - isInMap = true - item.path = componentRealPath - } - }) - }) - } - if (!isInMap) { - componentExportsMap[component] = componentExportsMap[component] || [] - componentExportsMap[component].push(realComponentObj) - } - return await buildSingleComponent(realComponentObj, buildConfig) - } - const transformResult = wxTransformer({ - code: componentContent, - sourcePath: component, - outputPath: outputComponentJSPath, - isRoot: false, - isTyped: Util.REG_TYPESCRIPT.test(component), - isNormal: false, - adapter: buildAdapter, - env: constantsReplaceList, - jsxAttributeNameReplace: weappConf.jsxAttributeNameReplace - }) - const compressTemplate = useCompileConf.compressTemplate - const componentWXMLContent = (isProduction && compressTemplate) ? transformResult.compressedTemplate : transformResult.template - const componentDepComponents = transformResult.components - const res = parseAst(PARSE_AST_TYPE.COMPONENT, transformResult.ast, componentDepComponents, component, outputComponentJSPath, buildConfig.npmSkip) - let resCode = res.code - resCode = await compileScriptFile(resCode, component, outputComponentJSPath, buildAdapter) - fs.ensureDirSync(path.dirname(outputComponentJSPath)) - if (isProduction) { - const uglifyPluginConfig = pluginsConfig.uglify || { enable: true } - if (uglifyPluginConfig.enable) { - const uglifyConfig = Object.assign(defaultUglifyConfig, uglifyPluginConfig.config || {}) - const uglifyResult = npmProcess.callPluginSync('uglifyjs', resCode, outputComponentJSPath, uglifyConfig) - if (uglifyResult.error) { - Util.printLog(Util.pocessTypeEnum.ERROR, '压缩错误', `文件${component}`) - console.log(uglifyResult.error) - } else { - resCode = uglifyResult.code - } - } - } - const { usingComponents = {} } = res.configObj - if (usingComponents && !Util.isEmptyObject(usingComponents)) { - const keys = Object.keys(usingComponents) - keys.forEach(item => { - componentDepComponents.forEach(component => { - if (_.camelCase(item) === _.camelCase(component.name)) { - delete usingComponents[item] - } - }) - }) - transfromNativeComponents(outputComponentJSONPath.replace(buildConfig.outputDir || buildOutputDir, sourceDirPath), res.configObj) - } - - const fileDep = dependencyTree[component] || {} - // 编译依赖的组件文件 - let buildDepComponentsResult = [] - let realComponentsPathList = [] - if (componentDepComponents.length) { - realComponentsPathList = getRealComponentsPathList(component, componentDepComponents) - res.scriptFiles = res.scriptFiles.map(item => { - for (let i = 0; i < realComponentsPathList.length; i++) { - const componentObj = realComponentsPathList[i] - const componentPath = componentObj.path - if (item === componentPath) { - return null - } - } - return item - }).filter(item => item) - realComponentsPathList = realComponentsPathList.filter(item => hasBeenBuiltComponents.indexOf(item.path) < 0 || notTaroComponents.indexOf(item.path) >= 0) - buildDepComponentsResult = await buildDepComponents(realComponentsPathList) - } - if (!Util.isEmptyObject(componentExportsMap) && realComponentsPathList.length) { - const mapKeys = Object.keys(componentExportsMap) - realComponentsPathList.forEach(componentObj => { - if (mapKeys.indexOf(componentObj.path) >= 0) { - const componentMap = componentExportsMap[componentObj.path] - componentMap.forEach(componentObj => { - componentDepComponents.forEach(depComponent => { - if (depComponent.name === componentObj.name) { - let componentPath = componentObj.path - let realPath - if (NODE_MODULES_REG.test(componentPath)) { - componentPath = componentPath.replace(nodeModulesPath, npmOutputDir) - realPath = Util.promoteRelativePath(path.relative(outputComponentJSPath, componentPath)) - } else { - realPath = Util.promoteRelativePath(path.relative(component, componentPath)) - } - depComponent.path = realPath.replace(path.extname(realPath), '') - } - }) - }) - } - }) - } - fs.writeFileSync(outputComponentJSONPath, JSON.stringify(_.merge({}, buildUsingComponents(component, componentDepComponents, true), res.configObj), null, 2)) - Util.printLog(Util.pocessTypeEnum.GENERATE, '组件配置', `${outputDirName}/${outputComponentShowPath}${outputFilesTypes.CONFIG}`) - fs.writeFileSync(outputComponentJSPath, resCode) - Util.printLog(Util.pocessTypeEnum.GENERATE, '组件逻辑', `${outputDirName}/${outputComponentShowPath}${outputFilesTypes.SCRIPT}`) - fs.writeFileSync(outputComponentWXMLPath, componentWXMLContent) - processNativeWxml(outputComponentWXMLPath.replace(outputDir, sourceDir), componentWXMLContent, outputComponentWXMLPath) - Util.printLog(Util.pocessTypeEnum.GENERATE, '组件模板', `${outputDirName}/${outputComponentShowPath}${outputFilesTypes.TEMPL}`) - // 编译依赖的脚本文件 - if (Util.isDifferentArray(fileDep['script'], res.scriptFiles)) { - compileDepScripts(res.scriptFiles) - } - // 编译样式文件 - if (Util.isDifferentArray(fileDep['style'], res.styleFiles) || Util.isDifferentArray(depComponents[component], componentDepComponents)) { - Util.printLog(Util.pocessTypeEnum.GENERATE, '组件样式', `${outputDirName}/${outputComponentShowPath}${outputFilesTypes.STYLE}`) - const depStyleList = getDepStyleList(outputComponentWXSSPath, buildDepComponentsResult) - wxssDepTree[outputComponentWXSSPath] = depStyleList - await compileDepStyles(outputComponentWXSSPath, res.styleFiles, true) - } - // 拷贝依赖文件 - if (Util.isDifferentArray(fileDep['json'], res.jsonFiles)) { - copyFilesFromSrcToOutput(res.jsonFiles) - } - if (Util.isDifferentArray(fileDep['media'], res.mediaFiles)) { - copyFilesFromSrcToOutput(res.mediaFiles) - } - fileDep['style'] = res.styleFiles - fileDep['script'] = res.scriptFiles - fileDep['json'] = res.jsonFiles - fileDep['media'] = res.mediaFiles - dependencyTree[component] = fileDep - depComponents[component] = componentDepComponents - componentsBuildResult[component] = { - js: outputComponentJSPath, - wxss: outputComponentWXSSPath, - wxml: outputComponentWXMLPath - } - return componentsBuildResult[component] - } catch (err) { - Util.printLog(Util.pocessTypeEnum.ERROR, '组件编译', `组件${componentShowPath}编译失败!`) - console.log(err) - } -} - -function compileDepScripts (scriptFiles, buildDepSync) { - return scriptFiles.map(async item => { - if (path.isAbsolute(item)) { - let outputItem - if (NODE_MODULES_REG.test(item)) { - outputItem = item.replace(nodeModulesPath, npmOutputDir).replace(path.extname(item), '.js') - } else { - outputItem = item.replace(path.join(sourceDir), path.join(outputDir)).replace(path.extname(item), '.js') - } - const useCompileConf = Object.assign({}, weappConf.compile) - const compileExclude = useCompileConf.exclude || [] - let isInCompileExclude = false - compileExclude.forEach(excludeItem => { - if (item.indexOf(path.join(appPath, excludeItem)) >= 0) { - isInCompileExclude = true - } - }) - if (isInCompileExclude) { - copyFileSync(item, outputItem) - return - } - if (!isBuildingScripts[outputItem]) { - isBuildingScripts[outputItem] = true - try { - const code = fs.readFileSync(item).toString() - const transformResult = wxTransformer({ - code, - sourcePath: item, - outputPath: outputItem, - isNormal: true, - isTyped: Util.REG_TYPESCRIPT.test(item), - adapter: buildAdapter, - env: constantsReplaceList, - jsxAttributeNameReplace: weappConf.jsxAttributeNameReplace - }) - const ast = transformResult.ast - const res = parseAst(PARSE_AST_TYPE.NORMAL, ast, [], item, outputItem) - const fileDep = dependencyTree[item] || {} - let resCode = res.code - resCode = await compileScriptFile(res.code, item, outputItem, buildAdapter) - fs.ensureDirSync(path.dirname(outputItem)) - if (isProduction) { - const uglifyPluginConfig = pluginsConfig.uglify || { enable: true } - if (uglifyPluginConfig.enable) { - const uglifyConfig = Object.assign(defaultUglifyConfig, uglifyPluginConfig.config || {}) - const uglifyResult = npmProcess.callPluginSync('uglifyjs', resCode, item, uglifyConfig) - if (uglifyResult.error) { - Util.printLog(Util.pocessTypeEnum.ERROR, '压缩错误', `文件${item}`) - console.log(uglifyResult.error) - } else { - resCode = uglifyResult.code - } - } - } - fs.writeFileSync(outputItem, resCode) - let modifyOutput = outputItem.replace(appPath + path.sep, '') - modifyOutput = modifyOutput.split(path.sep).join('/') - Util.printLog(Util.pocessTypeEnum.GENERATE, '依赖文件', modifyOutput) - // 编译依赖的脚本文件 - if (Util.isDifferentArray(fileDep['script'], res.scriptFiles)) { - if (buildDepSync) { - await Promise.all(compileDepScripts(res.scriptFiles)) - } else { - compileDepScripts(res.scriptFiles) - } - } - // 拷贝依赖文件 - if (Util.isDifferentArray(fileDep['json'], res.jsonFiles)) { - copyFilesFromSrcToOutput(res.jsonFiles) - } - if (Util.isDifferentArray(fileDep['media'], res.mediaFiles)) { - copyFilesFromSrcToOutput(res.mediaFiles) - } - fileDep['script'] = res.scriptFiles - fileDep['json'] = res.jsonFiles - fileDep['media'] = res.mediaFiles - dependencyTree[item] = fileDep - } catch (err) { - Util.printLog(Util.pocessTypeEnum.ERROR, '编译失败', item.replace(appPath + path.sep, '')) - console.log(err) - } - } - } - }) -} - -function copyFileSync (from, to, options) { - const filename = path.basename(from) - if (fs.statSync(from).isFile() && !path.extname(to)) { - fs.ensureDir(to) - if (from === path.join(to, filename)) { - return - } - return fs.copySync(from, path.join(to, filename), options) - } - if (from === to) { - return - } - fs.ensureDir(path.dirname(to)) - return fs.copySync(from, to, options) -} - -function copyFiles () { - const copyConfig = projectConfig.copy || { patterns: [], options: {} } - if (copyConfig.patterns && copyConfig.patterns.length) { - copyConfig.options = copyConfig.options || {} - const globalIgnore = copyConfig.options.ignore - const projectDir = appPath - copyConfig.patterns.forEach(pattern => { - if (typeof pattern === 'object' && pattern.from && pattern.to) { - const from = path.join(projectDir, pattern.from) - const to = path.join(projectDir, pattern.to) - let ignore = pattern.ignore || globalIgnore - if (fs.existsSync(from)) { - const copyOptions = {} - if (ignore) { - ignore = Array.isArray(ignore) ? ignore : [ignore] - copyOptions.filter = src => { - let isMatch = false - ignore.forEach(iPa => { - if (minimatch(path.basename(src), iPa)) { - isMatch = true - } - }) - return !isMatch - } - } - copyFileSync(from, to, copyOptions) - } else { - Util.printLog(Util.pocessTypeEnum.ERROR, '拷贝失败', `${pattern.from} 文件不存在!`) - } - } - }) - } -} - -function watchFiles () { - console.log() - console.log(chalk.gray('监听文件修改中...')) - console.log() - isBuildingScripts = {} - isBuildingStyles = {} - isCopyingFiles = {} - const watcherPaths = [path.join(sourceDir)].concat(watcherDirs) - const watcher = chokidar.watch(watcherPaths, { - ignored: /(^|[/\\])\../, - persistent: true, - ignoreInitial: true - }) - watcher - .on('addDir', dirPath => { - console.log(dirPath) - }) - .on('add', filePath => { - console.log(filePath) - }) - .on('change', async filePath => { - const extname = path.extname(filePath) - // 编译JS文件 - if (Util.REG_SCRIPT.test(extname) || Util.REG_TYPESCRIPT.test(extname)) { - if (entryFilePath === filePath) { - Util.printLog(Util.pocessTypeEnum.MODIFY, '入口文件', `${sourceDirName}/${entryFileName}.js`) - const config = await buildEntry() - // TODO 此处待优化 - if ((Util.checksum(JSON.stringify(config.pages)) !== Util.checksum(JSON.stringify(appConfig.pages))) || - (Util.checksum(JSON.stringify(config.subPackages || config.subpackages || {})) !== Util.checksum(JSON.stringify(appConfig.subPackages || appConfig.subpackages || {})))) { - appConfig = config - await buildPages() - } - } else { - const filePathWithoutExt = filePath.replace(extname, '') - if (isFileToBePage(filePath)) { // 编译页面 - filePath = filePathWithoutExt - filePath = filePath.replace(path.join(sourceDir) + path.sep, '') - filePath = filePath.split(path.sep).join('/') - Util.printLog(Util.pocessTypeEnum.MODIFY, '页面文件', `${sourceDirName}/${filePath}`) - await buildSinglePage(filePath) - } else if (hasBeenBuiltComponents.indexOf(filePath) >= 0) { // 编译组件 - let outoutShowFilePath = filePath.replace(appPath + path.sep, '') - outoutShowFilePath = outoutShowFilePath.split(path.sep).join('/') - Util.printLog(Util.pocessTypeEnum.MODIFY, '组件文件', outoutShowFilePath) - const hasbeenBuiltIndex = hasBeenBuiltComponents.indexOf(filePath) - if (hasbeenBuiltIndex >= 0) { - hasBeenBuiltComponents.splice(hasbeenBuiltIndex, 1) - } - - if (isWindows) { - await new Promise((resolve, reject) => { - setTimeout(async () => { - await buildSingleComponent(Object.assign({ - path: filePath - }, componentsNamedMap[filePath])) - resolve() - }, 300) - }) - } else { - await buildSingleComponent(Object.assign({ - path: filePath - }, componentsNamedMap[filePath])) - } - } else { - let isImported = false - for (const key in dependencyTree) { - const scripts = dependencyTree[key].script || [] - if (scripts.indexOf(filePath) >= 0) { - isImported = true - } - } - let modifySource = filePath.replace(appPath + path.sep, '') - modifySource = modifySource.split(path.sep).join('/') - if (isImported) { - Util.printLog(Util.pocessTypeEnum.MODIFY, 'JS文件', modifySource) - compileDepScripts([filePath]) - } else { - Util.printLog(Util.pocessTypeEnum.WARNING, 'JS文件', `${modifySource} 没有被引用到,不会被编译`) - } - } - } - } else if (Util.REG_STYLE.test(extname)) { - const includeStyleJSPath = [] - for (const key in dependencyTree) { - const styles = dependencyTree[key]['style'] || [] - styles.forEach(item => { - if (item === filePath) { - includeStyleJSPath.push({ - filePath: key, - styles - }) - } - }) - } - if (includeStyleJSPath.length) { - includeStyleJSPath.forEach(async item => { - let outputWXSSPath = null - outputWXSSPath = item.filePath.replace(path.extname(item.filePath), outputFilesTypes.STYLE) - let modifySource = outputWXSSPath.replace(appPath + path.sep, '') - modifySource = modifySource.split(path.sep).join('/') - Util.printLog(Util.pocessTypeEnum.MODIFY, '样式文件', modifySource) - if (NODE_MODULES_REG.test(outputWXSSPath)) { - let sourceNodeModulesDir = nodeModulesPath - let outputNodeModulesDir = npmOutputDir - outputWXSSPath = outputWXSSPath.replace(sourceNodeModulesDir, outputNodeModulesDir) - } else { - outputWXSSPath = outputWXSSPath.replace(sourceDir, outputDir) - } - let modifyOutput = outputWXSSPath.replace(appPath + path.sep, '') - modifyOutput = modifyOutput.split(path.sep).join('/') - let isComponent = false - if (!isFileToBePage(item.filePath) && item.filePath !== entryFilePath) { - isComponent = true - } - if (isWindows) { - await new Promise((resolve, reject) => { - setTimeout(async () => { - await compileDepStyles(outputWXSSPath, item.styles, isComponent) - resolve() - }, 300) - }) - } else { - await compileDepStyles(outputWXSSPath, item.styles, isComponent) - } - Util.printLog(Util.pocessTypeEnum.GENERATE, '样式文件', modifyOutput) - }) - } else { - let outputWXSSPath = filePath.replace(path.extname(filePath), outputFilesTypes.STYLE) - let modifySource = outputWXSSPath.replace(appPath + path.sep, '') - modifySource = modifySource.split(path.sep).join('/') - Util.printLog(Util.pocessTypeEnum.MODIFY, '样式文件', modifySource) - if (NODE_MODULES_REG.test(outputWXSSPath)) { - let sourceNodeModulesDir = nodeModulesPath - let outputNodeModulesDir = npmOutputDir - outputWXSSPath = outputWXSSPath.replace(sourceNodeModulesDir, outputNodeModulesDir) - } else { - outputWXSSPath = outputWXSSPath.replace(sourceDir, outputDir) - } - let modifyOutput = outputWXSSPath.replace(appPath + path.sep, '') - modifyOutput = modifyOutput.split(path.sep).join('/') - if (isWindows) { - await new Promise((resolve, reject) => { - setTimeout(async () => { - await compileDepStyles(outputWXSSPath, [filePath], false) - resolve() - }, 300) - }) - } else { - await compileDepStyles(outputWXSSPath, [filePath], false) - } - Util.printLog(Util.pocessTypeEnum.GENERATE, '样式文件', modifyOutput) - } - } else { - let modifySource = filePath.replace(appPath + path.sep, '') - modifySource = modifySource.split(path.sep).join('/') - Util.printLog(Util.pocessTypeEnum.MODIFY, '文件', modifySource) - copyFilesFromSrcToOutput([filePath]) - } - isBuildingScripts = {} - isBuildingStyles = {} - isCopyingFiles = {} - }) -} - -async function build ({ watch, adapter, envHasBeenSet = false }) { - process.env.TARO_ENV = adapter - if (!envHasBeenSet) isProduction = process.env.NODE_ENV === 'production' || !watch - buildAdapter = adapter - outputFilesTypes = Util.MINI_APP_FILES[buildAdapter] - // 可以自定义输出文件类型 - if (weappConf.customFilesTypes && !Util.isEmptyObject(weappConf.customFilesTypes)) { - outputFilesTypes = Object.assign({}, outputFilesTypes, weappConf.customFilesTypes[buildAdapter] || {}) - } - constantsReplaceList = Object.assign({}, constantsReplaceList, { - 'process.env.TARO_ENV': buildAdapter - }) - buildProjectConfig() - await buildFrameworkInfo() - copyFiles() - appConfig = await buildEntry() - await buildPages() - if (watch) { - watchFiles() - } -} - -function getHasBeenBuiltComponents () { - return hasBeenBuiltComponents || [] -} - -function spliceHasBeenBuiltComponents (index) { - index >= 0 && hasBeenBuiltComponents.splice(index, 1) -} - -function getDependencyTree () { - return dependencyTree || {} -} - -function getAppConfig () { - return appConfig -} - -function setAppConfig (config) { - appConfig = config -} - -function getComponentsNamedMap () { - return componentsNamedMap -} - -function setEnv (watch) { - isProduction = process.env.NODE_ENV === 'production' || !watch -} - -function resetIsBuildingScripts () { - isBuildingScripts = {} -} - -function resetIsBuildingStyles () { - isBuildingStyles = {} -} - -module.exports = { - build, - buildEntry, - buildPages, - buildSinglePage, - buildDepComponents, - buildSingleComponent, - getRealComponentsPathList, - compileDepStyles, - compileDepScripts, - parseAst, - isFileToBePage, - getHasBeenBuiltComponents, - spliceHasBeenBuiltComponents, - getDependencyTree, - getAppConfig, - setAppConfig, - getComponentsNamedMap, - setEnv, - resetIsBuildingScripts, - resetIsBuildingStyles -} diff --git a/packages/taro-cli/tsconfig.json b/packages/taro-cli/tsconfig.json new file mode 100644 index 000000000000..28033d388ab9 --- /dev/null +++ b/packages/taro-cli/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "allowJs": true, + "baseUrl": ".", + "experimentalDecorators": true, + "lib": ["esnext", "dom"], + "module": "commonjs", + "moduleResolution": "node", + "resolveJsonModule": true, + "noImplicitAny": false, + "noUnusedLocals": true, + "outDir": "dist/", + "preserveConstEnums": true, + "removeComments": false, + "rootDir": "./src", + "sourceMap": false, + "strictNullChecks": true, + "target": "es2015", + "traceResolution": false, + "types" : ["node"] + }, + "include": [ + "./src" + ] +} diff --git a/packages/taro-cli/tslint.json b/packages/taro-cli/tslint.json new file mode 100644 index 000000000000..fa1c9fc90ffb --- /dev/null +++ b/packages/taro-cli/tslint.json @@ -0,0 +1,31 @@ +{ + "extends": [ + "tslint-config-standard", + "tslint-config-prettier" + ], + "defaultSeverity": "error", + "rules": { + "ban-types": false, + "forin": false, + "interface-name": false, + "member-access": false, + "no-bitwise": false, + "no-conditional-assignment": false, + "no-console": false, + "no-empty": false, + "no-object-literal-type-assertion": false, + "no-string-literal": false, + "no-var-keyword": true, + "object-literal-key-quotes": [ false, "as-needed" ], + "object-literal-sort-keys": false, + "one-variable-per-declaration": false, + "ordered-imports": false, + "prefer-for-of": false, + "quotemark": [ true, "single", "avoid-escape", "jsx-double" ], + "semicolon": [ false, "never" ], + "space-before-function-paren": false, + "trailing-comma": [ true, { "multiline": "never", "singleline": "never" } ], + "variable-name": [ true, "allow-leading-underscore", "ban-keywords" ], + "prefer-const": true + } +} diff --git a/packages/taro-cli/yarn.lock b/packages/taro-cli/yarn.lock index f7f4d3aa4cd9..55837066576f 100644 --- a/packages/taro-cli/yarn.lock +++ b/packages/taro-cli/yarn.lock @@ -597,9 +597,13 @@ version "0.7.0" resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" -"@tarojs/taroize@1.2.22": - version "1.2.22" - resolved "http://registry.npm.taobao.org/@tarojs/taroize/download/@tarojs/taroize-1.2.22.tgz#34f6a8c2bb2b41c2cb396c8bd47c019d2cedc654" +"@tarojs/taro@^1.2.2": + version "1.2.26" + resolved "https://registry.npmjs.org/@tarojs/taro/-/taro-1.2.26.tgz#486c9acce62751e2e3110421a06c0e1bb7174034" + +"@tarojs/taroize@1.2.27-beta.0": + version "1.2.27-beta.0" + resolved "https://registry.npmjs.org/@tarojs/taroize/-/taroize-1.2.27-beta.0.tgz#572b668e3b8fd6083c1c5c95cefc35657084d7b4" dependencies: "@babel/code-frame" "^7.0.0" babel-core "^6.26.3" @@ -612,9 +616,9 @@ lodash "^4.17.5" typescript "^3.0.1" -"@tarojs/transformer-wx@1.2.22": - version "1.2.22" - resolved "http://registry.npm.taobao.org/@tarojs/transformer-wx/download/@tarojs/transformer-wx-1.2.22.tgz#a520829b0a930c9ec946706d2ff67b730015607b" +"@tarojs/transformer-wx@1.2.27-beta.0": + version "1.2.27-beta.0" + resolved "https://registry.npmjs.org/@tarojs/transformer-wx/-/transformer-wx-1.2.27-beta.0.tgz#3d639e8f236d8144a6184dff14a2f3e48dc80dc3" dependencies: "@babel/code-frame" "^7.0.0-beta.44" babel-core "^6.26.3" @@ -628,22 +632,84 @@ babel-plugin-syntax-dynamic-import "^6.18.0" babel-plugin-transform-class-properties "^6.24.1" babel-plugin-transform-define "^1.3.0" + babel-plugin-transform-do-expressions "^6.22.0" babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-export-extensions "^6.22.0" babel-plugin-transform-flow-strip-types "^6.22.0" babel-traverse "^6.26.0" babel-types "^6.26.0" eslint "^4.15.0" - eslint-plugin-taro "1.2.22" + eslint-plugin-react "7.10.0" + eslint-plugin-taro "1.2.27-beta.0" html "^1.0.0" lodash "^4.17.5" prettier "^1.14.2" typescript "^3.2.2" +"@types/autoprefixer@^9.1.1": + version "9.4.0" + resolved "https://registry.npmjs.org/@types/autoprefixer/-/autoprefixer-9.4.0.tgz#b72589130765cf8f7f403b9cec8ea81e507e759b" + dependencies: + postcss "7.x.x" + +"@types/babel-core@^6.25.5": + version "6.25.6" + resolved "https://registry.npmjs.org/@types/babel-core/-/babel-core-6.25.6.tgz#9e4faefcb300fd3abf0d2c2d85c505071462c1e1" + dependencies: + "@types/babel-generator" "*" + "@types/babel-template" "*" + "@types/babel-traverse" "*" + "@types/babel-types" "*" + "@types/babylon" "*" + +"@types/babel-generator@*", "@types/babel-generator@^6.25.2": + version "6.25.3" + resolved "https://registry.npmjs.org/@types/babel-generator/-/babel-generator-6.25.3.tgz#8f06caa12d0595a0538560abe771966d77d29286" + dependencies: + "@types/babel-types" "*" + +"@types/babel-template@*": + version "6.25.2" + resolved "https://registry.npmjs.org/@types/babel-template/-/babel-template-6.25.2.tgz#3c4cde02dbcbbf461a58d095a9f69f35eabd5f06" + dependencies: + "@types/babel-types" "*" + "@types/babylon" "*" + +"@types/babel-traverse@*", "@types/babel-traverse@^6.25.4": + version "6.25.5" + resolved "https://registry.npmjs.org/@types/babel-traverse/-/babel-traverse-6.25.5.tgz#6d293cf7523e48b524faa7b86dc3c488191484e5" + dependencies: + "@types/babel-types" "*" + +"@types/babel-types@*": + version "7.0.6" + resolved "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.6.tgz#a7cfaaeee96e90c4c54da0e580aaff3f4cffacac" + +"@types/babel-types@^6.25.2": + version "6.25.2" + resolved "https://registry.npmjs.org/@types/babel-types/-/babel-types-6.25.2.tgz#5c57f45973e4f13742dbc5273dd84cffe7373a9e" + +"@types/babylon@*": + version "6.16.5" + resolved "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.5.tgz#1c5641db69eb8cdf378edd25b4be7754beeb48b4" + dependencies: + "@types/babel-types" "*" + +"@types/ejs@^2.6.3": + version "2.6.3" + resolved "https://registry.npmjs.org/@types/ejs/-/ejs-2.6.3.tgz#b6509e9925d7eb5e95c8c73b6492e5baae7c1e6a" + "@types/events@*": version "3.0.0" resolved "http://registry.npm.taobao.org/@types/events/download/@types/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" -"@types/glob@^7.1.1": +"@types/fs-extra@^5.0.4": + version "5.0.5" + resolved "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.0.5.tgz#080d90a792f3fa2c5559eb44bd8ef840aae9104b" + dependencies: + "@types/node" "*" + +"@types/glob@*", "@types/glob@^7.1.1": version "7.1.1" resolved "http://registry.npm.taobao.org/@types/glob/download/@types/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" dependencies: @@ -651,6 +717,20 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/jest@^23.3.10": + version "23.3.14" + resolved "https://registry.npmjs.org/@types/jest/-/jest-23.3.14.tgz#37daaf78069e7948520474c87b80092ea912520a" + +"@types/klaw@^3.0.0": + version "3.0.0" + resolved "https://registry.npmjs.org/@types/klaw/-/klaw-3.0.0.tgz#97f70ba844c0c70b8e280eeeebb83caf054fc726" + dependencies: + "@types/node" "*" + +"@types/lodash@^4.14.119": + version "4.14.123" + resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.123.tgz#39be5d211478c8dd3bdae98ee75bb7efe4abfe4d" + "@types/minimatch@*": version "3.0.3" resolved "http://registry.npm.taobao.org/@types/minimatch/download/@types/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -659,6 +739,17 @@ version "11.12.2" resolved "http://registry.npm.taobao.org/@types/node/download/@types/node-11.12.2.tgz#d7f302e74b10e9801d52852137f652d9ee235da8" +"@types/node@^10.12.18": + version "10.14.5" + resolved "https://registry.npmjs.org/@types/node/-/node-10.14.5.tgz#27733a949f5d9972d87109297cffb62207ace70f" + +"@types/shelljs@^0.8.5": + version "0.8.5" + resolved "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.5.tgz#1e507b2f6d1f893269bd3e851ec24419ef9beeea" + dependencies: + "@types/glob" "*" + "@types/node" "*" + "@types/unist@*", "@types/unist@^2.0.0": version "2.0.3" resolved "http://registry.npm.taobao.org/@types/unist/download/@types/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" @@ -757,6 +848,12 @@ ajv@^6.9.1: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + dependencies: + string-width "^2.0.0" + ansi-colors@^1.0.1: version "1.1.0" resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" @@ -769,6 +866,10 @@ ansi-cyan@^0.1.1: dependencies: ansi-wrap "0.1.0" +ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + ansi-escapes@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" @@ -900,6 +1001,13 @@ array-find-index@^1.0.1: version "1.0.2" resolved "http://registry.npm.taobao.org/array-find-index/download/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" +array-includes@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" + array-map@~0.0.0: version "0.0.0" resolved "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" @@ -1645,9 +1753,9 @@ babel-plugin-transform-function-bind@^6.22.0: babel-plugin-syntax-function-bind "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-jsx-to-stylesheet@1.2.22: - version "1.2.22" - resolved "http://registry.npm.taobao.org/babel-plugin-transform-jsx-to-stylesheet/download/babel-plugin-transform-jsx-to-stylesheet-1.2.22.tgz#70b13c39ce28053caa0b3b3ba8f5f97a9a30747b" +babel-plugin-transform-jsx-to-stylesheet@1.2.27-beta.0: + version "1.2.27-beta.0" + resolved "https://registry.npmjs.org/babel-plugin-transform-jsx-to-stylesheet/-/babel-plugin-transform-jsx-to-stylesheet-1.2.27-beta.0.tgz#2d8a050b963b00dea39111857df7f6cd7e125164" babel-plugin-transform-object-assign@^6.5.0: version "6.22.0" @@ -1893,7 +2001,7 @@ babel-register@^6.24.1, babel-register@^6.26.0, babel-register@^6.9.0: mkdirp "^0.5.1" source-map-support "^0.4.15" -babel-runtime@^6.0.0, babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0, babel-runtime@^6.9.1: +babel-runtime@^6.0.0, babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0, babel-runtime@^6.6.1, babel-runtime@^6.9.1: version "6.26.0" resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" dependencies: @@ -1910,7 +2018,7 @@ babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0, babel-te babylon "^6.18.0" lodash "^4.17.4" -babel-traverse@^6.0.0, babel-traverse@^6.10.4, babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0: +babel-traverse@^6.0.0, babel-traverse@^6.10.4, babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0, babel-traverse@^6.7.3: version "6.26.0" resolved "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" dependencies: @@ -1937,7 +2045,7 @@ babylon@7.0.0-beta.44: version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d" -babylon@^6.18.0, babylon@^6.7.0: +babylon@^6.1.21, babylon@^6.18.0, babylon@^6.7.0: version "6.18.0" resolved "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" @@ -2014,6 +2122,18 @@ binary-extensions@^1.0.0: version "1.12.0" resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" +boxen@^1.2.1: + version "1.3.0" + resolved "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + bplist-creator@0.0.7: version "0.0.7" resolved "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz#37df1536092824b87c42f957b01344117372ae45" @@ -2110,7 +2230,7 @@ buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" -builtin-modules@^1.0.0: +builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -2166,6 +2286,21 @@ caller-path@^2.0.0: dependencies: caller-callsite "^2.0.0" +callsite-record@^3.0.0: + version "3.2.2" + resolved "https://registry.npmjs.org/callsite-record/-/callsite-record-3.2.2.tgz#9a0390642e43fe8bb823945e51464f69f41643de" + dependencies: + callsite "^1.0.0" + chalk "^1.1.1" + error-stack-parser "^1.3.3" + highlight-es "^1.0.0" + lodash "4.6.1 || ^4.16.1" + pinkie-promise "^2.0.0" + +callsite@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" @@ -2174,6 +2309,13 @@ callsites@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/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 "http://registry.npm.taobao.org/camelcase-keys/download/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" @@ -2182,7 +2324,11 @@ camelcase-keys@^4.0.0: map-obj "^2.0.0" quick-lru "^1.0.0" -camelcase@^4.1.0: +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + +camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -2200,6 +2346,10 @@ capture-exit@^1.2.0: dependencies: rsvp "^3.3.3" +capture-stack-trace@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + caseless@~0.12.0: version "0.12.0" resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -2208,7 +2358,7 @@ ccount@^1.0.0: version "1.0.3" resolved "http://registry.npm.taobao.org/ccount/download/ccount-1.0.3.tgz#f1cec43f332e2ea5a569fd46f9f5bde4e6102aff" -chalk@2.4.2, chalk@^2.1.0, chalk@^2.4.2: +chalk@2.4.2, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" dependencies: @@ -2216,7 +2366,7 @@ chalk@2.4.2, chalk@^2.1.0, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: @@ -2294,12 +2444,26 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + +cli-cursor@^1.0.1, cli-cursor@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + dependencies: + restore-cursor "^1.0.1" + cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" dependencies: restore-cursor "^2.0.0" +cli-spinners@^0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" + cli-spinners@^1.1.0: version "1.3.1" resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz#002c1990912d0d59580c93bd36c056de99e4259a" @@ -2411,6 +2575,10 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" +commander@^2.12.1: + version "2.20.0" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + commander@^2.19.0, commander@^2.9.0: version "2.19.0" resolved "http://registry.npm.taobao.org/commander/download/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" @@ -2462,6 +2630,17 @@ concat-stream@^1.4.7, concat-stream@^1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" +configstore@^3.0.0: + version "3.1.2" + resolved "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + connect@^3.6.5: version "3.6.6" resolved "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524" @@ -2475,6 +2654,10 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.5.1: version "1.6.0" resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" @@ -2510,6 +2693,12 @@ cosmiconfig@^5.0.0: js-yaml "^3.13.0" parse-json "^4.0.0" +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + dependencies: + capture-stack-trace "^1.0.0" + create-react-class@^15.6.3: version "15.6.3" resolved "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz#2d73237fb3f970ae6ebe011a9e66f46dbca80036" @@ -2518,6 +2707,13 @@ create-react-class@^15.6.3: loose-envify "^1.3.1" object-assign "^4.1.1" +cross-spawn-async@^2.1.1: + version "2.2.5" + resolved "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz#845ff0c0834a3ded9d160daca6d390906bb288cc" + dependencies: + lru-cache "^4.0.0" + which "^1.2.8" + cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -2536,6 +2732,10 @@ cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + css-color-keywords@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" @@ -2640,9 +2840,9 @@ decamelize-keys@^1.0.0: decamelize "^1.1.0" map-obj "^1.0.0" -decamelize@^1.1.0, decamelize@^1.1.1: +decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" - resolved "http://registry.npm.taobao.org/decamelize/download/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" decode-uri-component@^0.2.0: version "0.2.0" @@ -2711,10 +2911,34 @@ denodeify@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631" +depcheck@^0.6.11: + version "0.6.11" + resolved "https://registry.npmjs.org/depcheck/-/depcheck-0.6.11.tgz#6b616f2cf8c44ddcfdc5d7c7f7759bc53b479262" + dependencies: + babel-traverse "^6.7.3" + babylon "^6.1.21" + builtin-modules "^1.1.1" + deprecate "^1.0.0" + deps-regex "^0.1.4" + js-yaml "^3.4.2" + lodash "^4.5.1" + minimatch "^3.0.2" + require-package-name "^2.0.1" + walkdir "0.0.11" + yargs "^8.0.2" + depd@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" +deprecate@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/deprecate/-/deprecate-1.1.0.tgz#bbd069d62b232175b4e8459b2650cd2bad51f4b8" + +deps-regex@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/deps-regex/-/deps-regex-0.1.4.tgz#518667b7691460a5e7e0a341be76eb7ce8090184" + destroy@~1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" @@ -2750,6 +2974,20 @@ dir-glob@^2.2.1: dependencies: path-type "^3.0.0" +doctrine@0.7.2: + version "0.7.2" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz#7cb860359ba3be90e040b26b729ce4bfa654c523" + dependencies: + esutils "^1.1.6" + isarray "0.0.1" + +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + doctrine@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -2790,9 +3028,9 @@ domutils@^1.5.1: dom-serializer "0" domelementtype "1" -dot-prop@^4.1.1: +dot-prop@^4.1.0, dot-prop@^4.1.1: version "4.2.0" - resolved "http://registry.npm.taobao.org/dot-prop/download/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" dependencies: is-obj "^1.0.0" @@ -2880,6 +3118,12 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +error-stack-parser@^1.3.3: + version "1.3.6" + resolved "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-1.3.6.tgz#e0e73b93e417138d1cd7c0b746b1a4a14854c292" + dependencies: + stackframe "^0.3.1" + errorhandler@^1.5.0: version "1.5.0" resolved "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.0.tgz#eaba64ca5d542a311ac945f582defc336165d9f4" @@ -2887,7 +3131,7 @@ errorhandler@^1.5.0: accepts "~1.3.3" escape-html "~1.0.3" -es-abstract@^1.5.1: +es-abstract@^1.11.0, es-abstract@^1.4.3, es-abstract@^1.5.1, es-abstract@^1.7.0: version "1.13.0" resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" dependencies: @@ -2925,6 +3169,42 @@ escodegen@^1.9.1: optionalDependencies: source-map "~0.6.1" +eslint-config-taro@^1.1.4: + version "1.2.26" + resolved "https://registry.npmjs.org/eslint-config-taro/-/eslint-config-taro-1.2.26.tgz#b75100c656d2ee9d5c38c3c5a9e0d54f9c8b3cfb" + dependencies: + eslint-plugin-taro "1.2.26" + +eslint-import-resolver-node@^0.3.2: + version "0.3.2" + resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + dependencies: + debug "^2.6.9" + resolve "^1.5.0" + +eslint-module-utils@^2.4.0: + version "2.4.0" + resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz#8b93499e9b00eab80ccb6614e69f03678e84e09a" + dependencies: + debug "^2.6.8" + pkg-dir "^2.0.0" + +eslint-plugin-import@^2.8.0: + version "2.17.2" + resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.17.2.tgz#d227d5c6dc67eca71eb590d2bb62fb38d86e9fcb" + dependencies: + array-includes "^3.0.3" + contains-path "^0.1.0" + debug "^2.6.9" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.2" + eslint-module-utils "^2.4.0" + has "^1.0.3" + lodash "^4.17.11" + minimatch "^3.0.4" + read-pkg-up "^2.0.0" + resolve "^1.10.0" + eslint-plugin-react-native-globals@^0.1.1: version "0.1.2" resolved "https://registry.npmjs.org/eslint-plugin-react-native-globals/-/eslint-plugin-react-native-globals-0.1.2.tgz#ee1348bc2ceb912303ce6bdbd22e2f045ea86ea2" @@ -2935,12 +3215,45 @@ eslint-plugin-react-native@^3.2.1: dependencies: eslint-plugin-react-native-globals "^0.1.1" -eslint-plugin-taro@1.2.22: - version "1.2.22" - resolved "http://registry.npm.taobao.org/eslint-plugin-taro/download/eslint-plugin-taro-1.2.22.tgz#6b27090341ff8d9e31e08e33c55745092bf0885e" +eslint-plugin-react@7.10.0: + version "7.10.0" + resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.10.0.tgz#af5c1fef31c4704db02098f9be18202993828b50" + dependencies: + doctrine "^2.1.0" + has "^1.0.3" + jsx-ast-utils "^2.0.1" + prop-types "^15.6.2" + +eslint-plugin-react@^7.4.0: + version "7.12.4" + resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz#b1ecf26479d61aee650da612e425c53a99f48c8c" + dependencies: + array-includes "^3.0.3" + doctrine "^2.1.0" + has "^1.0.3" + jsx-ast-utils "^2.0.1" + object.fromentries "^2.0.0" + prop-types "^15.6.2" + resolve "^1.9.0" + +eslint-plugin-taro@1.2.26, eslint-plugin-taro@^1.1.4: + version "1.2.26" + resolved "https://registry.npmjs.org/eslint-plugin-taro/-/eslint-plugin-taro-1.2.26.tgz#19bcbe9838ee744dc33925d4d9b9690c8606c0d5" + dependencies: + has "^1.0.1" + +eslint-plugin-taro@1.2.27-beta.0: + version "1.2.27-beta.0" + resolved "https://registry.npmjs.org/eslint-plugin-taro/-/eslint-plugin-taro-1.2.27-beta.0.tgz#cc1bef2d8310408a665981eb7fc466af7c96a16c" dependencies: has "^1.0.1" +eslint-plugin-typescript@^0.12.0: + version "0.12.0" + resolved "https://registry.npmjs.org/eslint-plugin-typescript/-/eslint-plugin-typescript-0.12.0.tgz#e23d58cb27fe28e89fc641a1f20e8d862cb99aef" + dependencies: + requireindex "~1.1.0" + eslint-scope@3.7.1: version "3.7.1" resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" @@ -3033,6 +3346,10 @@ estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" +esutils@^1.1.6: + version "1.1.6" + resolved "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz#c01ccaa9ae4b897c6d0c3e210ae52f3c7a844375" + esutils@^2.0.0, esutils@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -3055,6 +3372,16 @@ exec-sh@^0.2.0: dependencies: merge "^1.2.0" +execa@^0.2.2: + version "0.2.2" + resolved "https://registry.npmjs.org/execa/-/execa-0.2.2.tgz#e2ead472c2c31aad6f73f1ac956eef45e12320cb" + dependencies: + cross-spawn-async "^2.1.1" + npm-run-path "^1.0.0" + object-assign "^4.0.1" + path-key "^1.0.0" + strip-eof "^1.0.0" + execa@^0.7.0: version "0.7.0" resolved "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" @@ -3085,6 +3412,10 @@ execall@^1.0.0: dependencies: clone-regexp "^1.0.0" +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + exit@^0.1.2: version "0.1.2" resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -3113,6 +3444,12 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + dependencies: + homedir-polyfill "^1.0.1" + expect@^23.6.0: version "23.6.0" resolved "https://registry.npmjs.org/expect/-/expect-23.6.0.tgz#1e0c8d3ba9a581c87bd71fb9bc8862d443425f98" @@ -3272,6 +3609,13 @@ fbjs@^1.0.0: setimmediate "^1.0.5" ua-parser-js "^0.7.18" +figures@^1.3.5: + version "1.7.0" + resolved "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + figures@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -3467,7 +3811,7 @@ fsevents@^1.2.2, fsevents@^1.2.3: nan "^2.9.2" node-pre-gyp "^0.10.0" -function-bind@^1.1.1: +function-bind@^1.0.2, function-bind@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -3508,6 +3852,10 @@ get-caller-file@^1.0.1: version "1.0.3" resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + get-stdin@^6.0.0: version "6.0.0" resolved "http://registry.npm.taobao.org/get-stdin/download/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" @@ -3526,6 +3874,10 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +giturl@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/giturl/-/giturl-1.0.1.tgz#926c69bda5c48a3d8f74254e99f826835e6a4aa0" + glob-base@^0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" @@ -3565,6 +3917,16 @@ glob-to-regexp@^0.3.0: version "0.3.0" resolved "http://registry.npm.taobao.org/glob-to-regexp/download/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" +glob@^6.0.1: + version "6.0.4" + resolved "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: version "7.1.3" resolved "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" @@ -3576,12 +3938,36 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + dependencies: + ini "^1.3.4" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + global-modules@^2.0.0: version "2.0.0" resolved "http://registry.npm.taobao.org/global-modules/download/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" dependencies: global-prefix "^3.0.0" +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + global-prefix@^3.0.0: version "3.0.0" resolved "http://registry.npm.taobao.org/global-prefix/download/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" @@ -3609,6 +3995,17 @@ globals@^9.18.0: version "9.18.0" resolved "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" +globby@^4.0.0: + version "4.1.0" + resolved "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz#080f54549ec1b82a6c60e631fc82e1211dbe95f8" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^6.0.1" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + globby@^7.1.1: version "7.1.1" resolved "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" @@ -3643,6 +4040,22 @@ gonzales-pe@^4.2.3: dependencies: minimist "1.1.x" +got@^6.7.1: + version "6.7.1" + resolved "https://registry.npmjs.org/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + got@^8.3.1: version "8.3.2" resolved "https://registry.npmjs.org/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" @@ -3669,7 +4082,7 @@ graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, version "4.1.11" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" -graceful-fs@^4.1.3: +graceful-fs@^4.1.3, graceful-fs@^4.1.5: version "4.1.15" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" @@ -3763,10 +4176,22 @@ has@^1.0.1, has@^1.0.3: dependencies: function-bind "^1.1.1" +highlight-es@^1.0.0: + version "1.0.3" + resolved "https://registry.npmjs.org/highlight-es/-/highlight-es-1.0.3.tgz#12abc300a27e686f6f18010134e3a5c6d2fe6930" + dependencies: + chalk "^2.4.0" + is-es2016-keyword "^1.0.0" + js-tokens "^3.0.0" + himalaya-wxml@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/himalaya-wxml/-/himalaya-wxml-1.1.0.tgz#85d0341af1c5f53f3b021be8e4be890cc8b4d7af" +hoek@6.x.x: + version "6.1.3" + resolved "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz#73b7d33952e01fe27a38b0457294b79dd8da242c" + home-or-tmp@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" @@ -3778,6 +4203,12 @@ home-or-tmp@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-3.0.0.tgz#57a8fe24cf33cdd524860a15821ddc25c86671fb" +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + dependencies: + parse-passwd "^1.0.0" + hosted-git-info@^2.1.4: version "2.7.1" resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" @@ -3875,6 +4306,10 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + import-lazy@^3.1.0: version "3.1.0" resolved "http://registry.npm.taobao.org/import-lazy/download/import-lazy-3.1.0.tgz#891279202c8a2280fdbd6674dbd8da1a1dfc67cc" @@ -3890,6 +4325,12 @@ imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + dependencies: + repeating "^2.0.0" + indent-string@^3.0.0: version "3.2.0" resolved "http://registry.npm.taobao.org/indent-string/download/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" @@ -3909,10 +4350,28 @@ inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: version "2.0.3" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" -ini@^1.3.5, ini@~1.3.0: +ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: version "1.3.5" resolved "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" +inquirer@^0.12.0: + version "0.12.0" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" + dependencies: + ansi-escapes "^1.1.0" + ansi-regex "^2.0.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + figures "^1.3.5" + lodash "^4.3.0" + readline2 "^1.0.1" + run-async "^0.1.0" + rx-lite "^3.1.2" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + inquirer@^3.0.6: version "3.3.0" resolved "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" @@ -4037,7 +4496,7 @@ is-callable@^1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" -is-ci@^1.0.10: +is-ci@^1.0.10, is-ci@^1.0.8: version "1.2.1" resolved "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" dependencies: @@ -4093,6 +4552,10 @@ is-equal-shallow@^0.1.3: dependencies: is-primitive "^2.0.0" +is-es2016-keyword@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-es2016-keyword/-/is-es2016-keyword-1.0.0.tgz#f6e54e110c5e4f8d265e69d2ed0eaf8cf5f47718" + is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -4153,10 +4616,21 @@ is-hexadecimal@^1.0.0: version "1.0.2" resolved "http://registry.npm.taobao.org/is-hexadecimal/download/is-hexadecimal-1.0.2.tgz#b6e710d7d07bb66b98cb8cece5c9b4921deeb835" +is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + is-negated-glob@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + is-number@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" @@ -4181,6 +4655,12 @@ is-object@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + dependencies: + path-is-inside "^1.0.1" + is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" @@ -4203,6 +4683,10 @@ is-promise@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + is-regex@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" @@ -4223,11 +4707,11 @@ is-resolvable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" -is-retry-allowed@^1.1.0: +is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" -is-stream@^1.0.1, is-stream@^1.1.0: +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -4271,7 +4755,11 @@ is-word-character@^1.0.0: version "1.0.2" resolved "http://registry.npm.taobao.org/is-word-character/download/is-word-character-1.0.2.tgz#46a5dac3f2a1840898b91e576cd40d493f3ae553" -isarray@1.0.0, isarray@~1.0.0: +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -4281,6 +4769,12 @@ isbinaryfile@^3.0.2: dependencies: buffer-alloc "^1.2.0" +isemail@3.x.x: + version "3.2.0" + resolved "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz#59310a021931a9fb06bbb51e155ce0b3f236832c" + dependencies: + punycode "2.x.x" + isexe@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -4710,6 +5204,14 @@ jest@^23.6.0: import-local "^1.0.0" jest-cli "^23.6.0" +joi@^14.0.6: + version "14.3.1" + resolved "https://registry.npmjs.org/joi/-/joi-14.3.1.tgz#164a262ec0b855466e0c35eea2a885ae8b6c703c" + dependencies: + hoek "6.x.x" + isemail "3.x.x" + topo "3.x.x" + js-base64@^2.1.9: version "2.4.9" resolved "https://registry.npmjs.org/js-base64/-/js-base64-2.4.9.tgz#748911fb04f48a60c4771b375cac45a80df11c03" @@ -4729,6 +5231,13 @@ js-yaml@^3.13.0: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^3.4.2: + version "3.13.1" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + js-yaml@^3.7.0: version "3.12.1" resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600" @@ -4869,6 +5378,12 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" +jsx-ast-utils@^2.0.1: + version "2.1.0" + resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.1.0.tgz#0ee4e2c971fb9601c67b5641b71be80faecf0b36" + dependencies: + array-includes "^3.0.3" + keyv@3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" @@ -4919,6 +5434,12 @@ known-css-properties@^0.11.0: version "0.11.0" resolved "http://registry.npm.taobao.org/known-css-properties/download/known-css-properties-0.11.0.tgz#0da784f115ea77c76b81536d7052e90ee6c86a8a" +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + dependencies: + package-json "^4.0.0" + latest-version@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/latest-version/-/latest-version-4.0.0.tgz#9542393ac55a585861a4c4ebc02389a0b4a9c332" @@ -4986,6 +5507,15 @@ load-json-file@^4.0.0: pify "^3.0.0" strip-bom "^3.0.0" +load-yaml-file@^0.1.0: + version "0.1.1" + resolved "https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.1.1.tgz#dc9b8e89cee96757f6f15a5707ac53f76aa529e9" + dependencies: + graceful-fs "^4.1.5" + js-yaml "^3.13.0" + pify "^2.3.0" + strip-bom "^3.0.0" + loader-utils@^1.1.0: version "1.2.3" resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" @@ -5029,18 +5559,22 @@ lodash.throttle@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" +lodash.toarray@^4.4.0: + version "4.4.0" + resolved "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" + lodash@4.17.4: version "4.17.4" resolved "http://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" +"lodash@4.6.1 || ^4.16.1", lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.5.1, lodash@^4.6.1, lodash@^4.7.0: + version "4.17.11" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + lodash@^3.5.0: version "3.10.1" resolved "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" -lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1: - version "4.17.11" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" - log-symbols@^2.0.0, log-symbols@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" @@ -5072,7 +5606,7 @@ lowercase-keys@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" -lru-cache@^4.0.1: +lru-cache@^4.0.0, lru-cache@^4.0.1: version "4.1.5" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" dependencies: @@ -5099,7 +5633,7 @@ map-cache@^0.2.2: version "0.2.2" resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" -map-obj@^1.0.0: +map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" resolved "http://registry.npm.taobao.org/map-obj/download/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" @@ -5165,6 +5699,25 @@ mem@^1.1.0: dependencies: mimic-fn "^1.0.0" +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + +meow@^3.7.0: + version "3.7.0" + resolved "https://registry.npmjs.org/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@^5.0.0: version "5.0.0" resolved "http://registry.npm.taobao.org/meow/download/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" @@ -5397,7 +5950,7 @@ min-document@^2.19.0: dependencies: dom-walk "^0.1.0" -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -5418,7 +5971,7 @@ minimist@1.1.x: version "1.1.3" resolved "http://registry.npm.taobao.org/minimist/download/minimist-1.1.3.tgz#3bedfd91a92d39016fcfaa1c681e8faa1a1efda8" -minimist@^1.1.1, minimist@^1.2.0: +minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" @@ -5479,6 +6032,10 @@ multimatch@^2.0.0: arrify "^1.0.0" minimatch "^3.0.0" +mute-stream@0.0.5: + version "0.0.5" + resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" + mute-stream@0.0.7: version "0.0.7" resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" @@ -5523,6 +6080,12 @@ nice-try@^1.0.4: version "1.0.5" resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" +node-emoji@^1.0.3: + version "1.10.0" + resolved "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" + dependencies: + lodash.toarray "^4.4.0" + node-fetch@^1.0.1, node-fetch@^1.3.3: version "1.7.3" resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" @@ -5625,6 +6188,37 @@ npm-bundled@^1.0.1: version "1.0.5" resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" +npm-check@^5.9.0: + version "5.9.0" + resolved "https://registry.npmjs.org/npm-check/-/npm-check-5.9.0.tgz#f9666af7d3c02442e16a9c56a32abc62023fa019" + dependencies: + babel-runtime "^6.6.1" + callsite-record "^3.0.0" + chalk "^1.1.3" + co "^4.6.0" + depcheck "^0.6.11" + execa "^0.2.2" + giturl "^1.0.0" + global-modules "^1.0.0" + globby "^4.0.0" + inquirer "^0.12.0" + is-ci "^1.0.8" + lodash "^4.7.0" + meow "^3.7.0" + minimatch "^3.0.2" + node-emoji "^1.0.3" + ora "^0.2.1" + package-json "^4.0.1" + path-exists "^2.1.0" + pkg-dir "^1.0.0" + preferred-pm "^1.0.1" + semver "^5.0.1" + semver-diff "^2.0.0" + text-table "^0.2.0" + throat "^2.0.2" + update-notifier "^2.1.0" + xtend "^4.0.1" + npm-packlist@^1.1.6: version "1.1.11" resolved "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.11.tgz#84e8c683cbe7867d34b1d357d893ce29e28a02de" @@ -5632,6 +6226,26 @@ npm-packlist@^1.1.6: ignore-walk "^3.0.1" npm-bundled "^1.0.1" +npm-run-all@^4.1.5: + version "4.1.5" + resolved "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" + dependencies: + ansi-styles "^3.2.1" + chalk "^2.4.1" + cross-spawn "^6.0.5" + memorystream "^0.3.1" + minimatch "^3.0.4" + pidtree "^0.3.0" + read-pkg "^3.0.0" + shell-quote "^1.6.1" + string.prototype.padend "^3.0.0" + +npm-run-path@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz#f5c32bf595fe81ae927daec52e82f8b000ac3c8f" + dependencies: + path-key "^1.0.0" + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -5702,6 +6316,15 @@ object.assign@^4.0.4: has-symbols "^1.0.0" object-keys "^1.0.11" +object.fromentries@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz#49a543d92151f8277b3ac9600f1e930b189d30ab" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.11.0" + function-bind "^1.1.1" + has "^1.0.1" + object.getownpropertydescriptors@^2.0.3: version "2.0.3" resolved "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" @@ -5738,6 +6361,10 @@ once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: dependencies: wrappy "1" +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + onetime@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" @@ -5772,6 +6399,15 @@ options@>=0.0.5: version "0.0.6" resolved "https://registry.npmjs.org/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" +ora@^0.2.1: + version "0.2.3" + resolved "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" + dependencies: + chalk "^1.1.1" + cli-cursor "^1.0.2" + cli-spinners "^0.1.2" + object-assign "^4.0.1" + ora@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/ora/-/ora-2.1.0.tgz#6caf2830eb924941861ec53a173799e008b51e5b" @@ -5853,6 +6489,15 @@ p-try@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" +package-json@^4.0.0, package-json@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + package-json@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/package-json/-/package-json-5.0.0.tgz#a7dbe2725edcc7dc9bcee627672275e323882433" @@ -5899,6 +6544,10 @@ parse-node-version@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.0.tgz#33d9aa8920dcc3c0d33658ec18ce237009a56d53" +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + parse5@4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" @@ -5919,7 +6568,7 @@ path-exists@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz#d5a8998eb71ef37a74c34eb0d9eba6e878eea081" -path-exists@^2.0.0: +path-exists@^2.0.0, path-exists@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" dependencies: @@ -5933,10 +6582,14 @@ path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -path-is-inside@^1.0.2: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" +path-key@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz#5d53d578019646c0d68800db4e146e6bdc2ac7af" + path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" @@ -5973,6 +6626,10 @@ performance-now@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" +pidtree@^0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/pidtree/-/pidtree-0.3.0.tgz#f6fada10fccc9f99bf50e90d0b23d72c9ebc2e6b" + pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -6001,6 +6658,12 @@ pirates@^4.0.0: dependencies: node-modules-regexp "^1.0.0" +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + dependencies: + find-up "^1.0.0" + pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" @@ -6117,9 +6780,9 @@ postcss-pxtorem@^4.0.1: object-assign "^4.1.0" postcss "^5.2.10" -postcss-pxtransform@1.2.22: - version "1.2.22" - resolved "http://registry.npm.taobao.org/postcss-pxtransform/download/postcss-pxtransform-1.2.22.tgz#be4f2f8a2bdd18d57844697f5da9790dddf18480" +postcss-pxtransform@1.2.27-beta.0: + version "1.2.27-beta.0" + resolved "https://registry.npmjs.org/postcss-pxtransform/-/postcss-pxtransform-1.2.27-beta.0.tgz#28a33cc1c2748f5484000643b48b064617a5787e" dependencies: postcss "^6.0.16" postcss-pxtorem "^4.0.1" @@ -6192,6 +6855,14 @@ postcss-value-parser@^3.3.1: version "3.3.1" resolved "http://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" +postcss@7.x.x, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.7: + version "7.0.14" + resolved "http://registry.npm.taobao.org/postcss/download/postcss-7.0.14.tgz#4527ed6b1ca0d82c53ce5ec1a2041c2346bbd6e5" + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + postcss@^5.2.10: version "5.2.18" resolved "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" @@ -6209,18 +6880,21 @@ postcss@^6.0.1, postcss@^6.0.16, postcss@^6.0.2, postcss@^6.0.21, postcss@^6.0.2 source-map "^0.6.1" supports-color "^5.4.0" -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.7: - version "7.0.14" - resolved "http://registry.npm.taobao.org/postcss/download/postcss-7.0.14.tgz#4527ed6b1ca0d82c53ce5ec1a2041c2346bbd6e5" +preferred-pm@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/preferred-pm/-/preferred-pm-1.0.1.tgz#539df37ce944b1b765ae944a8ba34a7e68694e8d" dependencies: - chalk "^2.4.2" - source-map "^0.6.1" - supports-color "^6.1.0" + path-exists "^3.0.0" + which-pm "^1.0.1" prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + prepend-http@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" @@ -6233,9 +6907,9 @@ prettier@^1.14.2: version "1.14.3" resolved "https://registry.npmjs.org/prettier/-/prettier-1.14.3.tgz#90238dd4c0684b7edce5f83b0fb7328e48bd0895" -prettier@^1.14.3: - version "1.15.3" - resolved "https://registry.npmjs.org/prettier/-/prettier-1.15.3.tgz#1feaac5bdd181237b54dbe65d874e02a1472786a" +prettier@^1.15.3: + version "1.17.0" + resolved "https://registry.npmjs.org/prettier/-/prettier-1.17.0.tgz#53b303676eed22cc14a9f0cec09b477b3026c008" pretty-format@^23.6.0: version "23.6.0" @@ -6284,9 +6958,9 @@ prop-types@^15.5.8: loose-envify "^1.3.1" object-assign "^4.1.1" -prop-types@^15.6.1: +prop-types@^15.6.2: version "15.7.2" - resolved "http://registry.npm.taobao.org/prop-types/download/prop-types-15.7.2.tgz?cache=0&other_urls=http%3A%2F%2Fregistry.npm.taobao.org%2Fprop-types%2Fdownload%2Fprop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" dependencies: loose-envify "^1.4.0" object-assign "^4.1.1" @@ -6315,14 +6989,14 @@ pumpify@^1.3.5: inherits "^2.0.3" pump "^2.0.0" +punycode@2.x.x, punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + punycode@^1.4.1: version "1.4.1" resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - qs@~6.5.2: version "6.5.2" resolved "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -6383,9 +7057,9 @@ react-native-known-styling-properties@^1.0.4: version "1.0.5" resolved "http://registry.npm.taobao.org/react-native-known-styling-properties/download/react-native-known-styling-properties-1.0.5.tgz#dd99690d579c5136541e1df836e75088af6e7356" -react-native@0.55.4: +react-native@^0.55.4: version "0.55.4" - resolved "http://registry.npm.taobao.org/react-native/download/react-native-0.55.4.tgz?cache=0&other_urls=http%3A%2F%2Fregistry.npm.taobao.org%2Freact-native%2Fdownload%2Freact-native-0.55.4.tgz#eecffada3750a928e2ddd07cf11d857ae9751c30" + resolved "https://registry.npmjs.org/react-native/-/react-native-0.55.4.tgz#eecffada3750a928e2ddd07cf11d857ae9751c30" dependencies: absolute-path "^0.0.0" art "^0.10.0" @@ -6538,6 +7212,14 @@ readdirp@^2.0.0: micromatch "^3.1.10" readable-stream "^2.0.2" +readline2@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + mute-stream "0.0.5" + realpath-native@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/realpath-native/-/realpath-native-1.0.2.tgz#cd51ce089b513b45cf9b1516c82989b51ccc6560" @@ -6550,6 +7232,13 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/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 "http://registry.npm.taobao.org/redent/download/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" @@ -6612,6 +7301,13 @@ regexpu-core@^2.0.0: regjsgen "^0.2.0" regjsparser "^0.1.4" +registry-auth-token@^3.0.1: + version "3.4.0" + resolved "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + registry-auth-token@^3.3.2: version "3.3.2" resolved "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" @@ -6619,7 +7315,7 @@ registry-auth-token@^3.3.2: rc "^1.1.6" safe-buffer "^5.0.1" -registry-url@^3.1.0: +registry-url@^3.0.3, registry-url@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" dependencies: @@ -6770,6 +7466,10 @@ require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" +require-package-name@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9" + require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" @@ -6777,12 +7477,23 @@ require-uncached@^1.0.3: caller-path "^0.1.0" resolve-from "^1.0.0" +requireindex@~1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/requireindex/-/requireindex-1.1.0.tgz#e5404b81557ef75db6e49c5a72004893fe03e162" + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" dependencies: resolve-from "^3.0.0" +resolve-dir@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" @@ -6815,7 +7526,7 @@ resolve@^1.1.6, resolve@^1.6.0: dependencies: path-parse "^1.0.5" -resolve@^1.10.0: +resolve@^1.10.0, resolve@^1.9.0: version "1.10.0" resolved "http://registry.npm.taobao.org/resolve/download/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" dependencies: @@ -6833,6 +7544,13 @@ responselike@1.0.2: dependencies: lowercase-keys "^1.0.0" +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -6864,6 +7582,12 @@ rsvp@^3.3.3: version "3.6.2" resolved "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" +run-async@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" + dependencies: + once "^1.3.0" + run-async@^2.2.0: version "2.3.0" resolved "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" @@ -6880,6 +7604,10 @@ rx-lite@*, rx-lite@^4.0.8: version "4.0.8" resolved "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" +rx-lite@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" + rxjs@^5.5.2: version "5.5.12" resolved "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" @@ -6927,6 +7655,12 @@ sax@~1.1.1: version "1.1.6" resolved "https://registry.npmjs.org/sax/-/sax-1.1.6.tgz#5d616be8a5e607d54e114afae55b7eaf2fcc3240" +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + dependencies: + semver "^5.0.3" + "semver@2 || 3 || 4 || 5", semver@5.x, semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.4.1: version "5.6.0" resolved "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" @@ -7191,6 +7925,10 @@ stack-utils@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" +stackframe@^0.3.1: + version "0.3.1" + resolved "https://registry.npmjs.org/stackframe/-/stackframe-0.3.1.tgz#33aa84f1177a5548c8935533cbfeb3420975f5a4" + stacktrace-parser@^0.1.3: version "0.1.4" resolved "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.4.tgz#01397922e5f62ecf30845522c95c4fe1d25e7d4e" @@ -7264,6 +8002,14 @@ string-width@^3.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" +string.prototype.padend@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.4.3" + function-bind "^1.0.2" + string_decoder@^1.1.1: version "1.2.0" resolved "http://registry.npm.taobao.org/string_decoder/download/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" @@ -7324,6 +8070,12 @@ strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/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 "http://registry.npm.taobao.org/strip-indent/download/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" @@ -7336,13 +8088,13 @@ style-search@^0.1.0: version "0.1.0" resolved "http://registry.npm.taobao.org/style-search/download/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902" -stylelint-config-taro-rn@1.2.22: - version "1.2.22" - resolved "http://registry.npm.taobao.org/stylelint-config-taro-rn/download/stylelint-config-taro-rn-1.2.22.tgz#306cbc65f8cc30d2796426537a41dbc39ff13608" +stylelint-config-taro-rn@1.2.27-beta.0: + version "1.2.27-beta.0" + resolved "https://registry.npmjs.org/stylelint-config-taro-rn/-/stylelint-config-taro-rn-1.2.27-beta.0.tgz#0f1fa3957d61f4162f46e69b0880385ed9cd2bbd" -stylelint-taro-rn@1.2.22: - version "1.2.22" - resolved "http://registry.npm.taobao.org/stylelint-taro-rn/download/stylelint-taro-rn-1.2.22.tgz#55ff6b26e692c396abec05c5dbabb40ac1d1030f" +stylelint-taro-rn@1.2.27-beta.0: + version "1.2.27-beta.0" + resolved "https://registry.npmjs.org/stylelint-taro-rn/-/stylelint-taro-rn-1.2.27-beta.0.tgz#03f2d0f63265bbb15e6b8bdd0703ceda5d6d040d" dependencies: react-native-known-styling-properties "^1.0.4" @@ -7477,6 +8229,12 @@ temp@0.8.3: os-tmpdir "^1.0.0" rimraf "~2.2.6" +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + dependencies: + execa "^0.7.0" + test-exclude@^4.2.1: version "4.2.3" resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-4.2.3.tgz#a9a5e64474e4398339245a0a769ad7c2f4a97c20" @@ -7487,10 +8245,14 @@ test-exclude@^4.2.1: read-pkg-up "^1.0.1" require-main-filename "^1.0.1" -text-table@~0.2.0: +text-table@^0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" +throat@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/throat/-/throat-2.0.2.tgz#a9fce808b69e133a632590780f342c30a6249b02" + throat@^4.0.0, throat@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" @@ -7517,7 +8279,7 @@ time-stamp@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" -timed-out@^4.0.1: +timed-out@^4.0.0, timed-out@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" @@ -7574,6 +8336,12 @@ to-through@^2.0.0: dependencies: through2 "^2.0.3" +topo@3.x.x: + version "3.0.3" + resolved "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz#d5a67fb2e69307ebeeb08402ec2a2a6f5f7ad95c" + dependencies: + hoek "6.x.x" + tough-cookie@>=2.3.3: version "3.0.0" resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.0.tgz#d2bceddebde633153ff20a52fa844a0dc71dacef" @@ -7606,6 +8374,10 @@ traverse@0.6.6: version "0.6.6" resolved "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + trim-newlines@^2.0.0: version "2.0.0" resolved "http://registry.npm.taobao.org/trim-newlines/download/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" @@ -7626,6 +8398,62 @@ trough@^1.0.0: version "1.0.3" resolved "http://registry.npm.taobao.org/trough/download/trough-1.0.3.tgz#e29bd1614c6458d44869fc28b255ab7857ef7c24" +tslib@1.9.0: + version "1.9.0" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" + +tslib@^1.8.0, tslib@^1.8.1: + version "1.9.3" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + +tslint-config-prettier@^1.17.0: + version "1.18.0" + resolved "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37" + +tslint-config-standard@^8.0.1: + version "8.0.1" + resolved "https://registry.npmjs.org/tslint-config-standard/-/tslint-config-standard-8.0.1.tgz#e4dd3128e84b0e34b51990b68715a641f2b417e4" + dependencies: + tslint-eslint-rules "^5.3.1" + +tslint-eslint-rules@^5.3.1: + version "5.4.0" + resolved "https://registry.npmjs.org/tslint-eslint-rules/-/tslint-eslint-rules-5.4.0.tgz#e488cc9181bf193fe5cd7bfca213a7695f1737b5" + dependencies: + doctrine "0.7.2" + tslib "1.9.0" + tsutils "^3.0.0" + +tslint@^5.12.0: + version "5.16.0" + resolved "https://registry.npmjs.org/tslint/-/tslint-5.16.0.tgz#ae61f9c5a98d295b9a4f4553b1b1e831c1984d67" + dependencies: + "@babel/code-frame" "^7.0.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^3.2.0" + glob "^7.1.1" + js-yaml "^3.13.0" + minimatch "^3.0.4" + mkdirp "^0.5.1" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.8.0" + tsutils "^2.29.0" + +tsutils@^2.29.0: + version "2.29.0" + resolved "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" + dependencies: + tslib "^1.8.1" + +tsutils@^3.0.0: + version "3.10.0" + resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.10.0.tgz#6f1c95c94606e098592b0dff06590cf9659227d6" + dependencies: + tslib "^1.8.1" + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -7724,6 +8552,12 @@ unique-stream@^2.0.2: json-stable-stringify "^1.0.0" through2-filter "^2.0.0" +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + dependencies: + crypto-random-string "^1.0.0" + unist-util-find-all-after@^1.0.2: version "1.0.2" resolved "http://registry.npm.taobao.org/unist-util-find-all-after/download/unist-util-find-all-after-1.0.2.tgz#9be49cfbae5ca1566b27536670a92836bf2f8d6d" @@ -7771,10 +8605,29 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + upath@^1.0.5: version "1.1.0" resolved "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" +update-notifier@^2.1.0: + version "2.5.0" + resolved "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + dependencies: + boxen "^1.2.1" + chalk "^2.0.1" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-ci "^1.0.10" + is-installed-globally "^0.1.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + uri-js@^4.2.2: version "4.2.2" resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" @@ -7785,6 +8638,12 @@ urix@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + dependencies: + prepend-http "^1.0.1" + url-parse-lax@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" @@ -7934,6 +8793,10 @@ w3c-hr-time@^1.0.1: dependencies: browser-process-hrtime "^0.1.2" +walkdir@0.0.11: + version "0.0.11" + resolved "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz#a16d025eb931bd03b52f308caed0f40fcebe9532" + walker@~1.0.5: version "1.0.7" resolved "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" @@ -7995,7 +8858,14 @@ which-module@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" -which@^1.2.12, which@^1.2.14, which@^1.2.9, which@^1.3.0, which@^1.3.1: +which-pm@^1.0.1: + version "1.1.0" + resolved "https://registry.npmjs.org/which-pm/-/which-pm-1.1.0.tgz#5c0fc3f722f003707dea7b20cd17effd3ad2fc33" + dependencies: + load-yaml-file "^0.1.0" + path-exists "^3.0.0" + +which@^1.2.12, which@^1.2.14, which@^1.2.8, which@^1.2.9, which@^1.3.0, which@^1.3.1: version "1.3.1" resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" dependencies: @@ -8007,6 +8877,12 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" +widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + dependencies: + string-width "^2.1.1" + win-release@^1.0.0: version "1.1.1" resolved "https://registry.npmjs.org/win-release/-/win-release-1.1.1.tgz#5fa55e02be7ca934edfc12665632e849b72e5209" @@ -8040,6 +8916,14 @@ write-file-atomic@^1.2.0: imurmurhash "^0.1.4" slide "^1.1.5" +write-file-atomic@^2.0.0: + version "2.4.2" + resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz#a7181706dfba17855d221140a9c06e15fcdd87b9" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + write-file-atomic@^2.1.0: version "2.3.0" resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" @@ -8092,6 +8976,10 @@ xcode@^0.9.1: simple-plist "^0.2.1" uuid "3.0.1" +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" @@ -8177,6 +9065,24 @@ yargs@^11.0.0: y18n "^3.2.1" yargs-parser "^9.0.2" +yargs@^8.0.2: + version "8.0.2" + resolved "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" + dependencies: + camelcase "^4.1.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^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 "^7.0.0" + yargs@^9.0.0: version "9.0.1" resolved "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c" diff --git a/packages/taro/types/index.d.ts b/packages/taro/types/index.d.ts index 34fc32766a06..183341cfb6a8 100644 --- a/packages/taro/types/index.d.ts +++ b/packages/taro/types/index.d.ts @@ -312,7 +312,8 @@ declare namespace Taro { * ] * @since 1.7.3 */ - subPackages?: SubPackage[] + subPackages?: SubPackage[], + subpackages?: SubPackage[] /** * Worker 代码放置的目录 * 使用 Worker 处理多线程任务时,设置 Worker 代码放置的目录 @@ -467,7 +468,7 @@ declare namespace Taro { function getEnv(): ENV_TYPE.WEAPP | ENV_TYPE.WEB | ENV_TYPE.RN | ENV_TYPE.ALIPAY | ENV_TYPE.TT | ENV_TYPE.SWAN; - function render(component: Component | JSX.Element, element: Element | null): any; + function render(component: Component | any, element: Element | null): any; function internal_safe_set(...arg: any[]): any; function internal_safe_get(...arg: any[]): any; From 7d6b8c708880933d5c8cf87b8b4c8d744bf7272d Mon Sep 17 00:00:00 2001 From: luckyadam Date: Wed, 2 Jan 2019 14:23:11 +0800 Subject: [PATCH 012/126] =?UTF-8?q?fix(cli):=20=E4=BF=AE=E5=A4=8D=E5=BC=95?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/bin/taro-convert | 2 +- packages/taro-cli/bin/taro-doctor | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/taro-cli/bin/taro-convert b/packages/taro-cli/bin/taro-convert index aac8fd0c6410..42cee5e7cd85 100755 --- a/packages/taro-cli/bin/taro-convert +++ b/packages/taro-cli/bin/taro-convert @@ -2,7 +2,7 @@ const program = require('commander') -const Convertor = require('../dist/convertor') +const Convertor = require('../dist/convertor').default program .parse(process.argv) diff --git a/packages/taro-cli/bin/taro-doctor b/packages/taro-cli/bin/taro-doctor index a0b60c550d83..b57e4febddb1 100755 --- a/packages/taro-cli/bin/taro-doctor +++ b/packages/taro-cli/bin/taro-doctor @@ -14,7 +14,7 @@ if (!fs.existsSync(PROJECT_CONF_PATH)) { process.exit(1) } -const { validators } = require('../dist/doctor') +const { validators } = require('../dist/doctor').default const NOTE_ALL_RIGHT = chalk.green('[✓] ') const NOTE_VALID = chalk.yellow('[!] ') From e8e42168c96793af24cce99e32643eace007bea0 Mon Sep 17 00:00:00 2001 From: liliangquan Date: Thu, 3 Jan 2019 19:32:57 +0800 Subject: [PATCH 013/126] =?UTF-8?q?feat(taro-components-qa):=20=E5=BF=AB?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E7=9B=B8=E5=85=B3=E7=BB=84=E4=BB=B6=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/audio/img.js | 4 + .../src/components/audio/index.ux | 195 ++++++++++++++++++ .../src/components/button.js/img.js | 1 + .../src/components/button.js/index.ux | 155 ++++++++++++++ .../src/components/camera/index.ux | 80 +++++++ .../src/components/icon/index.ux | 132 ++++++++++++ .../src/components/image/index.ux | 84 ++++++++ .../src/components/input/index.ux | 113 ++++++++++ .../src/components/label/index.ux | 55 +++++ .../src/components/navigator/index.ux | 81 ++++++++ .../src/components/picker/index.ux | 160 ++++++++++++++ .../src/components/progress/index.ux | 106 ++++++++++ .../src/components/radio/index.ux | 70 +++++++ .../src/components/rich_text/index.ux | 53 +++++ .../src/components/slider/index.ux | 115 +++++++++++ .../src/components/swiper/index.ux | 90 ++++++++ .../src/components/switch/index.ux | 82 ++++++++ .../src/components/text/index.ux | 50 +++++ .../src/components/textarea/index.ux | 74 +++++++ .../src/components/video/index.ux | 126 +++++++++++ .../src/components/view/index.ux | 55 +++++ 21 files changed, 1881 insertions(+) create mode 100644 packages/taro-components-qa/src/components/audio/img.js create mode 100644 packages/taro-components-qa/src/components/audio/index.ux create mode 100644 packages/taro-components-qa/src/components/button.js/img.js create mode 100644 packages/taro-components-qa/src/components/button.js/index.ux create mode 100644 packages/taro-components-qa/src/components/camera/index.ux create mode 100644 packages/taro-components-qa/src/components/icon/index.ux create mode 100644 packages/taro-components-qa/src/components/image/index.ux create mode 100644 packages/taro-components-qa/src/components/input/index.ux create mode 100644 packages/taro-components-qa/src/components/label/index.ux create mode 100644 packages/taro-components-qa/src/components/navigator/index.ux create mode 100644 packages/taro-components-qa/src/components/picker/index.ux create mode 100644 packages/taro-components-qa/src/components/progress/index.ux create mode 100644 packages/taro-components-qa/src/components/radio/index.ux create mode 100644 packages/taro-components-qa/src/components/rich_text/index.ux create mode 100644 packages/taro-components-qa/src/components/slider/index.ux create mode 100644 packages/taro-components-qa/src/components/swiper/index.ux create mode 100644 packages/taro-components-qa/src/components/switch/index.ux create mode 100644 packages/taro-components-qa/src/components/text/index.ux create mode 100644 packages/taro-components-qa/src/components/textarea/index.ux create mode 100644 packages/taro-components-qa/src/components/video/index.ux create mode 100644 packages/taro-components-qa/src/components/view/index.ux diff --git a/packages/taro-components-qa/src/components/audio/img.js b/packages/taro-components-qa/src/components/audio/img.js new file mode 100644 index 000000000000..3347b3ac540a --- /dev/null +++ b/packages/taro-components-qa/src/components/audio/img.js @@ -0,0 +1,4 @@ +export const PAUSE_IMG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAABMklEQVRoQ+2Z0Y3CQAxE7QqOEqAjbwd0QAmEDijhOliXBBVAB0YrATqdkGxl10SRZn/XmXiek/kx08oPr7x/goGlJ4gJrGICIrIhoiMR7YnoTkS/qnoa1XyPfugTEpEzMx/+NmxmJ1WdRpjo0Y8auDFzm8L7mNlFVXeDDMzWDxkopdinRmutoec9kz36oQZ6XuA13+579GEgQtirwQQyCXna+AeyCWXrI4UihL0apFAmIU8bKZRNKFsfKRQh7NUghTIJedpIoWxC2fpIoQhhrwYplEnI00YKZRPK1kcKRQh7NUihTEKe9rdSqC01fv41c621biMNejWllNn6oZ9YRCZmbhua9xm84JitHzLQun6aaCsmMrO2YhqynXkRmasfNuB9Bkvdw8BS5F/vxQQwgU4CD9RcRkCIkNZgAAAAAElFTkSuQmCC' +export const START_IMG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAB2klEQVRoQ9WZfVEEMQzFEwXgACSAk+IAHIAC7hRwKAAJwQE4AAWAA1DwmDdTZjo3cNtuu023f3d282s+XtKqrHzpyu2XIoAQwqmZfYwEnQUQQggi8qCqxwC+RGRjZvcjgEwC8NRV9X3fWADPInJhZgRyWzkA16p695eF0RuEIIzLygHYqOrtIesA7MzsxoOgCQANB/AaQ6prkjcDiBDMhxsze+zljaYAv0YDMBG56pHgiwBEbzCUmOAMrcXWYgCJN6gZ26UIFgeI3lhMM7oAJAnOvGB+NFvdAJKQaqoZ3QESzaA3qhPcBaClZrgBtNIMd4BazRgCoEYzhgKYoxnDASQJnjVnDAmQQJxPzeDDAkSIrZltDsn26ACcLXZrBfgGcLbWEPoEEHJajRFD6AnAZe40NxIAQ4bDz8GY38+HUQDe4qkXd6fuAAB4RcmTn3XD5wnAkGGsV01oXgAv0fjqS7DuAAAm1bVkYO4JwNrOkGl6EdwLoKi2j+SBWbV9FIDZtd0doLa2ewI0qe1eAKzt7CBnKWqJ0eneJlWodW0vgckB+PeRT0Sy+/YSo0r25gDwmZVd4tHehxer7U0B+DE+dKsq+/QTEemeqFUzcclpeOydDCEPo0r+uXqAHzf0dkAxk0BxAAAAAElFTkSuQmCC' + +export default PAUSE_IMG \ No newline at end of file diff --git a/packages/taro-components-qa/src/components/audio/index.ux b/packages/taro-components-qa/src/components/audio/index.ux new file mode 100644 index 000000000000..8bd09fe4b175 --- /dev/null +++ b/packages/taro-components-qa/src/components/audio/index.ux @@ -0,0 +1,195 @@ + + + + \ No newline at end of file diff --git a/packages/taro-components-qa/src/components/button.js/img.js b/packages/taro-components-qa/src/components/button.js/img.js new file mode 100644 index 000000000000..619081d152a4 --- /dev/null +++ b/packages/taro-components-qa/src/components/button.js/img.js @@ -0,0 +1 @@ +export default 'data:image/gif;base64,R0lGODlhgACAAKIAAP///93d3bu7u5mZmQAA/wAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFBQAEACwCAAIAfAB8AAAD/0i63P4wygYqmDjrzbtflvWNZGliYXiubKuloivPLlzReD7al+7/Eh5wSFQIi8hHYBkwHUmD6CD5YTJLz49USuVYraRsZ7vtar7XnQ1Kjpoz6LRHvGlz35O4nEPP2O94EnpNc2sef1OBGIOFMId/inB6jSmPdpGScR19EoiYmZobnBCIiZ95k6KGGp6ni4wvqxilrqBfqo6skLW2YBmjDa28r6Eosp27w8Rov8ekycqoqUHODrTRvXsQwArC2NLF29UM19/LtxO5yJd4Au4CK7DUNxPebG4e7+8n8iv2WmQ66BtoYpo/dvfacBjIkITBE9DGlMvAsOIIZjIUAixliv9ixYZVtLUos5GjwI8gzc3iCGghypQqrbFsme8lwZgLZtIcYfNmTJ34WPTUZw5oRxdD9w0z6iOpO15MgTh1BTTJUKos39jE+o/KS64IFVmsFfYT0aU7capdy7at27dw48qdS7eu3bt480I02vUbX2F/JxYNDImw4GiGE/P9qbhxVpWOI/eFKtlNZbWXuzlmG1mv58+gQ4seTbq06dOoU6vGQZJy0FNlMcV+czhQ7SQmYd8eMhPs5BxVdfcGEtV3buDBXQ+fURxx8oM6MT9P+Fh6dOrH2zavc13u9JXVJb520Vp8dvC76wXMuN5Sepm/1WtkEZHDefnzR9Qvsd9+/wi8+en3X0ntYVcSdAE+UN4zs7ln24CaLagghIxBaGF8kFGoIYV+Ybghh841GIyI5ICIFoklJsigihmimJOLEbLYIYwxSgigiZ+8l2KB+Ml4oo/w8dijjcrouCORKwIpnJIjMnkkksalNeR4fuBIm5UEYImhIlsGCeWNNJphpJdSTlkml1jWeOY6TnaRpppUctcmFW9mGSaZceYopH9zkjnjUe59iR5pdapWaGqHopboaYua1qije67GJ6CuJAAAIfkEBQUABAAsCgACAFcAMAAAA/9Iutz+ML5Ag7w46z0r5WAoSp43nihXVmnrdusrv+s332dt4Tyo9yOBUJD6oQBIQGs4RBlHySSKyczVTtHoidocPUNZaZAr9F5FYbGI3PWdQWn1mi36buLKFJvojsHjLnshdhl4L4IqbxqGh4gahBJ4eY1kiX6LgDN7fBmQEJI4jhieD4yhdJ2KkZk8oiSqEaatqBekDLKztBG2CqBACq4wJRi4PZu1sA2+v8C6EJexrBAD1AOBzsLE0g/V1UvYR9sN3eR6lTLi4+TlY1wz6Qzr8u1t6FkY8vNzZTxaGfn6mAkEGFDgL4LrDDJDyE4hEIbdHB6ESE1iD4oVLfLAqPETIsOODwmCDJlv5MSGJklaS6khAQAh+QQFBQAEACwfAAIAVwAwAAAD/0i63P5LSAGrvTjrNuf+YKh1nWieIumhbFupkivPBEzR+GnnfLj3ooFwwPqdAshAazhEGUXJJIrJ1MGOUamJ2jQ9QVltkCv0XqFh5IncBX01afGYnDqD40u2z76JK/N0bnxweC5sRB9vF34zh4gjg4uMjXobihWTlJUZlw9+fzSHlpGYhTminKSepqebF50NmTyor6qxrLO0L7YLn0ALuhCwCrJAjrUqkrjGrsIkGMW/BMEPJcphLgDaABjUKNEh29vdgTLLIOLpF80s5xrp8ORVONgi8PcZ8zlRJvf40tL8/QPYQ+BAgjgMxkPIQ6E6hgkdjoNIQ+JEijMsasNY0RQix4gKP+YIKXKkwJIFF6JMudFEAgAh+QQFBQAEACw8AAIAQgBCAAAD/kg0PPowykmrna3dzXvNmSeOFqiRaGoyaTuujitv8Gx/661HtSv8gt2jlwIChYtc0XjcEUnMpu4pikpv1I71astytkGh9wJGJk3QrXlcKa+VWjeSPZHP4Rtw+I2OW81DeBZ2fCB+UYCBfWRqiQp0CnqOj4J1jZOQkpOUIYx/m4oxg5cuAaYBO4Qop6c6pKusrDevIrG2rkwptrupXB67vKAbwMHCFcTFxhLIt8oUzLHOE9Cy0hHUrdbX2KjaENzey9Dh08jkz8Tnx83q66bt8PHy8/T19vf4+fr6AP3+/wADAjQmsKDBf6AOKjS4aaHDgZMeSgTQcKLDhBYPEswoA1BBAgAh+QQFBQAEACxOAAoAMABXAAAD7Ei6vPOjyUkrhdDqfXHm4OZ9YSmNpKmiqVqykbuysgvX5o2HcLxzup8oKLQQix0UcqhcVo5ORi+aHFEn02sDeuWqBGCBkbYLh5/NmnldxajX7LbPBK+PH7K6narfO/t+SIBwfINmUYaHf4lghYyOhlqJWgqDlAuAlwyBmpVnnaChoqOkpaanqKmqKgGtrq+wsbA1srW2ry63urasu764Jr/CAb3Du7nGt7TJsqvOz9DR0tPU1TIA2ACl2dyi3N/aneDf4uPklObj6OngWuzt7u/d8fLY9PXr9eFX+vv8+PnYlUsXiqC3c6PmUUgAACH5BAUFAAQALE4AHwAwAFcAAAPpSLrc/m7IAau9bU7MO9GgJ0ZgOI5leoqpumKt+1axPJO1dtO5vuM9yi8TlAyBvSMxqES2mo8cFFKb8kzWqzDL7Xq/4LB4TC6bz1yBes1uu9uzt3zOXtHv8xN+Dx/x/wJ6gHt2g3Rxhm9oi4yNjo+QkZKTCgGWAWaXmmOanZhgnp2goaJdpKGmp55cqqusrZuvsJays6mzn1m4uRAAvgAvuBW/v8GwvcTFxqfIycA3zA/OytCl0tPPO7HD2GLYvt7dYd/ZX99j5+Pi6tPh6+bvXuTuzujxXens9fr7YPn+7egRI9PPHrgpCQAAIfkEBQUABAAsPAA8AEIAQgAAA/lIutz+UI1Jq7026h2x/xUncmD5jehjrlnqSmz8vrE8u7V5z/m5/8CgcEgsGo/IpHLJbDqf0Kh0ShBYBdTXdZsdbb/Yrgb8FUfIYLMDTVYz2G13FV6Wz+lX+x0fdvPzdn9WeoJGAYcBN39EiIiKeEONjTt0kZKHQGyWl4mZdREAoQAcnJhBXBqioqSlT6qqG6WmTK+rsa1NtaGsuEu6o7yXubojsrTEIsa+yMm9SL8osp3PzM2cStDRykfZ2tfUtS/bRd3ewtzV5pLo4eLjQuUp70Hx8t9E9eqO5Oku5/ztdkxi90qPg3x2EMpR6IahGocPCxp8AGtigwQAIfkEBQUABAAsHwBOAFcAMAAAA/9Iutz+MMo36pg4682J/V0ojs1nXmSqSqe5vrDXunEdzq2ta3i+/5DeCUh0CGnF5BGULC4tTeUTFQVONYAs4CfoCkZPjFar83rBx8l4XDObSUL1Ott2d1U4yZwcs5/xSBB7dBMBhgEYfncrTBGDW4WHhomKUY+QEZKSE4qLRY8YmoeUfkmXoaKInJ2fgxmpqqulQKCvqRqsP7WooriVO7u8mhu5NacasMTFMMHCm8qzzM2RvdDRK9PUwxzLKdnaz9y/Kt8SyR3dIuXmtyHpHMcd5+jvWK4i8/TXHff47SLjQvQLkU+fG29rUhQ06IkEG4X/Rryp4mwUxSgLL/7IqFETB8eONT6ChCFy5ItqJomES6kgAQAh+QQFBQAEACwKAE4AVwAwAAAD/0i63A4QuEmrvTi3yLX/4MeNUmieITmibEuppCu3sDrfYG3jPKbHveDktxIaF8TOcZmMLI9NyBPanFKJp4A2IBx4B5lkdqvtfb8+HYpMxp3Pl1qLvXW/vWkli16/3dFxTi58ZRcChwIYf3hWBIRchoiHiotWj5AVkpIXi4xLjxiaiJR/T5ehoomcnZ+EGamqq6VGoK+pGqxCtaiiuJVBu7yaHrk4pxqwxMUzwcKbyrPMzZG90NGDrh/JH8t72dq3IN1jfCHb3L/e5ebh4ukmxyDn6O8g08jt7tf26ybz+m/W9GNXzUQ9fm1Q/APoSWAhhfkMAmpEbRhFKwsvCsmosRIHx444PoKcIXKkjIImjTzjkQAAIfkEBQUABAAsAgA8AEIAQgAAA/VIBNz+8KlJq72Yxs1d/uDVjVxogmQqnaylvkArT7A63/V47/m2/8CgcEgsGo/IpHLJbDqf0Kh0Sj0FroGqDMvVmrjgrDcTBo8v5fCZki6vCW33Oq4+0832O/at3+f7fICBdzsChgJGeoWHhkV0P4yMRG1BkYeOeECWl5hXQ5uNIAOjA1KgiKKko1CnqBmqqk+nIbCkTq20taVNs7m1vKAnurtLvb6wTMbHsUq4wrrFwSzDzcrLtknW16tI2tvERt6pv0fi48jh5h/U6Zs77EXSN/BE8jP09ZFA+PmhP/xvJgAMSGBgQINvEK5ReIZhQ3QEMTBLAAAh+QQFBQAEACwCAB8AMABXAAAD50i6DA4syklre87qTbHn4OaNYSmNqKmiqVqyrcvBsazRpH3jmC7yD98OCBF2iEXjBKmsAJsWHDQKmw571l8my+16v+CweEwum8+hgHrNbrvbtrd8znbR73MVfg838f8BeoB7doN0cYZvaIuMjY6PkJGSk2gClgJml5pjmp2YYJ6dX6GeXaShWaeoVqqlU62ir7CXqbOWrLafsrNctjIDwAMWvC7BwRWtNsbGFKc+y8fNsTrQ0dK3QtXAYtrCYd3eYN3c49/a5NVj5eLn5u3s6e7x8NDo9fbL+Mzy9/T5+tvUzdN3Zp+GBAAh+QQJBQAEACwCAAIAfAB8AAAD/0i63P4wykmrvTjrzbv/YCiOZGmeaKqubOu+cCzPdArcQK2TOL7/nl4PSMwIfcUk5YhUOh3M5nNKiOaoWCuWqt1Ou16l9RpOgsvEMdocXbOZ7nQ7DjzTaeq7zq6P5fszfIASAYUBIYKDDoaGIImKC4ySH3OQEJKYHZWWi5iZG0ecEZ6eHEOio6SfqCaqpaytrpOwJLKztCO2jLi1uoW8Ir6/wCHCxMG2x7muysukzb230M6H09bX2Nna29zd3t/g4cAC5OXm5+jn3Ons7eba7vHt2fL16tj2+QL0+vXw/e7WAUwnrqDBgwgTKlzIsKHDh2gGSBwAccHEixAvaqTYcFCjRoYeNyoM6REhyZIHT4o0qPIjy5YTTcKUmHImx5cwE85cmJPnSYckK66sSAAj0aNIkypdyrSp06dQo0qdSrWq1atYs2rdyrWr169gwxZJAAA7' diff --git a/packages/taro-components-qa/src/components/button.js/index.ux b/packages/taro-components-qa/src/components/button.js/index.ux new file mode 100644 index 000000000000..0cf11a7b4ad8 --- /dev/null +++ b/packages/taro-components-qa/src/components/button.js/index.ux @@ -0,0 +1,155 @@ + + + + + diff --git a/packages/taro-components-qa/src/components/camera/index.ux b/packages/taro-components-qa/src/components/camera/index.ux new file mode 100644 index 000000000000..f7522ec4d642 --- /dev/null +++ b/packages/taro-components-qa/src/components/camera/index.ux @@ -0,0 +1,80 @@ + + + + + \ No newline at end of file diff --git a/packages/taro-components-qa/src/components/icon/index.ux b/packages/taro-components-qa/src/components/icon/index.ux new file mode 100644 index 000000000000..fdb57b710ce3 --- /dev/null +++ b/packages/taro-components-qa/src/components/icon/index.ux @@ -0,0 +1,132 @@ + + + + + diff --git a/packages/taro-components-qa/src/components/image/index.ux b/packages/taro-components-qa/src/components/image/index.ux new file mode 100644 index 000000000000..1e0ee91576cd --- /dev/null +++ b/packages/taro-components-qa/src/components/image/index.ux @@ -0,0 +1,84 @@ + + + + + diff --git a/packages/taro-components-qa/src/components/input/index.ux b/packages/taro-components-qa/src/components/input/index.ux new file mode 100644 index 000000000000..81441c65c583 --- /dev/null +++ b/packages/taro-components-qa/src/components/input/index.ux @@ -0,0 +1,113 @@ + + + + + diff --git a/packages/taro-components-qa/src/components/label/index.ux b/packages/taro-components-qa/src/components/label/index.ux new file mode 100644 index 000000000000..82cb4ef1f5c8 --- /dev/null +++ b/packages/taro-components-qa/src/components/label/index.ux @@ -0,0 +1,55 @@ + + + + + diff --git a/packages/taro-components-qa/src/components/navigator/index.ux b/packages/taro-components-qa/src/components/navigator/index.ux new file mode 100644 index 000000000000..a765bac33201 --- /dev/null +++ b/packages/taro-components-qa/src/components/navigator/index.ux @@ -0,0 +1,81 @@ + + + + + diff --git a/packages/taro-components-qa/src/components/picker/index.ux b/packages/taro-components-qa/src/components/picker/index.ux new file mode 100644 index 000000000000..b77104912e20 --- /dev/null +++ b/packages/taro-components-qa/src/components/picker/index.ux @@ -0,0 +1,160 @@ + + + + + diff --git a/packages/taro-components-qa/src/components/progress/index.ux b/packages/taro-components-qa/src/components/progress/index.ux new file mode 100644 index 000000000000..b06652626017 --- /dev/null +++ b/packages/taro-components-qa/src/components/progress/index.ux @@ -0,0 +1,106 @@ + + + + + \ No newline at end of file diff --git a/packages/taro-components-qa/src/components/radio/index.ux b/packages/taro-components-qa/src/components/radio/index.ux new file mode 100644 index 000000000000..4e3ce745afa2 --- /dev/null +++ b/packages/taro-components-qa/src/components/radio/index.ux @@ -0,0 +1,70 @@ + + + + + diff --git a/packages/taro-components-qa/src/components/rich_text/index.ux b/packages/taro-components-qa/src/components/rich_text/index.ux new file mode 100644 index 000000000000..bfda22088006 --- /dev/null +++ b/packages/taro-components-qa/src/components/rich_text/index.ux @@ -0,0 +1,53 @@ + + + + + \ No newline at end of file diff --git a/packages/taro-components-qa/src/components/slider/index.ux b/packages/taro-components-qa/src/components/slider/index.ux new file mode 100644 index 000000000000..26dd508dfece --- /dev/null +++ b/packages/taro-components-qa/src/components/slider/index.ux @@ -0,0 +1,115 @@ + + + + + + \ No newline at end of file diff --git a/packages/taro-components-qa/src/components/swiper/index.ux b/packages/taro-components-qa/src/components/swiper/index.ux new file mode 100644 index 000000000000..de95ed870b8e --- /dev/null +++ b/packages/taro-components-qa/src/components/swiper/index.ux @@ -0,0 +1,90 @@ + + + + + diff --git a/packages/taro-components-qa/src/components/switch/index.ux b/packages/taro-components-qa/src/components/switch/index.ux new file mode 100644 index 000000000000..5f62a068e768 --- /dev/null +++ b/packages/taro-components-qa/src/components/switch/index.ux @@ -0,0 +1,82 @@ + + + + + diff --git a/packages/taro-components-qa/src/components/text/index.ux b/packages/taro-components-qa/src/components/text/index.ux new file mode 100644 index 000000000000..d0eba4ddf688 --- /dev/null +++ b/packages/taro-components-qa/src/components/text/index.ux @@ -0,0 +1,50 @@ + + + + + diff --git a/packages/taro-components-qa/src/components/textarea/index.ux b/packages/taro-components-qa/src/components/textarea/index.ux new file mode 100644 index 000000000000..52e18dbd7b87 --- /dev/null +++ b/packages/taro-components-qa/src/components/textarea/index.ux @@ -0,0 +1,74 @@ + + + + + diff --git a/packages/taro-components-qa/src/components/video/index.ux b/packages/taro-components-qa/src/components/video/index.ux new file mode 100644 index 000000000000..79932b266f45 --- /dev/null +++ b/packages/taro-components-qa/src/components/video/index.ux @@ -0,0 +1,126 @@ + + + + + diff --git a/packages/taro-components-qa/src/components/view/index.ux b/packages/taro-components-qa/src/components/view/index.ux new file mode 100644 index 000000000000..e1744c01b0f8 --- /dev/null +++ b/packages/taro-components-qa/src/components/view/index.ux @@ -0,0 +1,55 @@ + + + + + From 950b49d419a644b598c0a86662e8fb25dcf24fd7 Mon Sep 17 00:00:00 2001 From: Alan Zhang Date: Thu, 3 Jan 2019 15:41:34 +0800 Subject: [PATCH 014/126] =?UTF-8?q?fix(doctor):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=20typescript=20=E5=90=8E=E5=87=BA=E7=8E=B0?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/bin/taro-doctor | 4 ++-- packages/taro-cli/src/doctor/configSchema.ts | 14 +++++--------- packages/taro-cli/src/doctor/configValidator.ts | 6 +++--- packages/taro-cli/src/doctor/eslintValidator.ts | 4 ++-- packages/taro-cli/src/doctor/index.ts | 13 +++++++++---- packages/taro-cli/src/doctor/joi2desc.ts | 2 +- packages/taro-cli/src/doctor/packageValidator.ts | 4 ++-- packages/taro-cli/src/doctor/recommandValidator.ts | 6 +++--- packages/taro-cli/src/doctor/validatorEslintrc.ts | 2 +- 9 files changed, 28 insertions(+), 27 deletions(-) diff --git a/packages/taro-cli/bin/taro-doctor b/packages/taro-cli/bin/taro-doctor index b57e4febddb1..9c64060453a0 100755 --- a/packages/taro-cli/bin/taro-doctor +++ b/packages/taro-cli/bin/taro-doctor @@ -6,7 +6,7 @@ const _ = require('lodash/fp') const ora = require('ora') const chalk = require('chalk') const fs = require('fs-extra') -const { PROJECT_CONFIG } = require('../dist/util') +const { PROJECT_CONFIG } = require('../dist/util/constants') const PROJECT_CONF_PATH = path.join(process.cwd(), PROJECT_CONFIG) if (!fs.existsSync(PROJECT_CONF_PATH)) { @@ -57,7 +57,7 @@ program async function diagnose () { const spinner = ora('正在诊断项目...').start() - const reportsP = _.invokeMap(_.call, validators) + const reportsP = _.map(validator => validator(), validators) const reports = await Promise.all(reportsP) spinner.succeed('诊断完成') printReport(reports) diff --git a/packages/taro-cli/src/doctor/configSchema.ts b/packages/taro-cli/src/doctor/configSchema.ts index 25f7798e7335..c8fe11d391d6 100644 --- a/packages/taro-cli/src/doctor/configSchema.ts +++ b/packages/taro-cli/src/doctor/configSchema.ts @@ -1,4 +1,4 @@ -import Joi from 'joi' +import * as Joi from 'joi' const schema = Joi.object().keys({ 'projectName': Joi.string().required(), @@ -85,17 +85,13 @@ const schema = Joi.object().keys({ 'miniCssExtractPluginOption': Joi.object(), // 第三方配置 'module': Joi.object().keys({ - 'postcss': Joi.object().keys({ - 'autoprefixer': Joi.object().keys({ + 'postcss': Joi.object().pattern( + Joi.string(), + Joi.object().keys({ 'enable': Joi.bool(), 'config': Joi.object() // 第三方配置 }), - 'pxtransform': Joi.object().keys({ - 'enable': Joi.bool(), - 'config': Joi.object() - }), - 'plugins': Joi.array() // 第三方配置 - }) + ) }) }) }) diff --git a/packages/taro-cli/src/doctor/configValidator.ts b/packages/taro-cli/src/doctor/configValidator.ts index 53e257be11b2..afd68df332ef 100644 --- a/packages/taro-cli/src/doctor/configValidator.ts +++ b/packages/taro-cli/src/doctor/configValidator.ts @@ -1,6 +1,6 @@ -import Joi from 'joi' -import _ from 'lodash/fp' -import path from 'path' +import * as Joi from 'joi' +import * as _ from 'lodash/fp' +import * as path from 'path' import joi2desc from './joi2desc' import configSchema from './configSchema' diff --git a/packages/taro-cli/src/doctor/eslintValidator.ts b/packages/taro-cli/src/doctor/eslintValidator.ts index 498a9d6c6464..cb06bdfc3fa5 100644 --- a/packages/taro-cli/src/doctor/eslintValidator.ts +++ b/packages/taro-cli/src/doctor/eslintValidator.ts @@ -1,5 +1,5 @@ -import path from 'path' -import _ from 'lodash' +import * as path from 'path' +import * as _ from 'lodash' import { CLIEngine } from 'eslint' import { PROJECT_CONFIG } from '../util/constants' diff --git a/packages/taro-cli/src/doctor/index.ts b/packages/taro-cli/src/doctor/index.ts index 3dec316e1010..59247fdfa2a3 100644 --- a/packages/taro-cli/src/doctor/index.ts +++ b/packages/taro-cli/src/doctor/index.ts @@ -1,8 +1,13 @@ +import configValidator from './configValidator'; +import packageValidator from './packageValidator'; +import recommandValidator from './recommandValidator'; +import eslintValidator from './eslintValidator'; + export default { validators: [ - require('./configValidator'), - require('./packageValidator'), - require('./recommandValidator'), - require('./eslintValidator') + configValidator, + packageValidator, + recommandValidator, + eslintValidator ] } diff --git a/packages/taro-cli/src/doctor/joi2desc.ts b/packages/taro-cli/src/doctor/joi2desc.ts index 4fe795fdb705..4ba60dd5b7d9 100644 --- a/packages/taro-cli/src/doctor/joi2desc.ts +++ b/packages/taro-cli/src/doctor/joi2desc.ts @@ -57,7 +57,7 @@ const joi2desc = { 'number.precision': '', 'number.ref': '', 'number.unsafe': '', - 'object.allowUnknown': '', + 'object.allowUnknown': '不合法的字段', 'object.and': '', 'object.assert': '', 'object.base': '应该为一个对象', diff --git a/packages/taro-cli/src/doctor/packageValidator.ts b/packages/taro-cli/src/doctor/packageValidator.ts index 8f4d605a3e86..3551175fc5da 100644 --- a/packages/taro-cli/src/doctor/packageValidator.ts +++ b/packages/taro-cli/src/doctor/packageValidator.ts @@ -1,5 +1,5 @@ -import _ from 'lodash/fp' -import npmCheck from 'npm-check' +import * as _ from 'lodash/fp' +import * as npmCheck from 'npm-check' import { getPkgVersion } from '../util' diff --git a/packages/taro-cli/src/doctor/recommandValidator.ts b/packages/taro-cli/src/doctor/recommandValidator.ts index 0c5001409816..312a575fbe2b 100644 --- a/packages/taro-cli/src/doctor/recommandValidator.ts +++ b/packages/taro-cli/src/doctor/recommandValidator.ts @@ -1,6 +1,6 @@ -import _ from 'lodash/fp' -import fs from 'fs-extra' -import path from 'path' +import * as _ from 'lodash/fp' +import * as fs from 'fs-extra' +import * as path from 'path' import chalk from 'chalk' import { IErrorLine } from './interface' diff --git a/packages/taro-cli/src/doctor/validatorEslintrc.ts b/packages/taro-cli/src/doctor/validatorEslintrc.ts index 4e168dbb2596..521a005d3929 100644 --- a/packages/taro-cli/src/doctor/validatorEslintrc.ts +++ b/packages/taro-cli/src/doctor/validatorEslintrc.ts @@ -1,4 +1,4 @@ -export default { +module.exports = { 'extends': ['taro'], 'rules': { 'no-unused-vars': ['error', { 'varsIgnorePattern': 'Taro' }], From f07149420c384ee75e47fe18befe1c578bc3421c Mon Sep 17 00:00:00 2001 From: luckyadam Date: Tue, 8 Jan 2019 15:12:13 +0800 Subject: [PATCH 015/126] =?UTF-8?q?feat(cli):=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=BF=AB=E5=BA=94=E7=94=A8=E7=BC=96=E8=AF=91=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/bin/taro-build | 2 +- packages/taro-cli/src/build.ts | 9 ++++++++- packages/taro-cli/src/quick/index.ts | 5 +++++ packages/taro-cli/src/util/constants.ts | 3 ++- 4 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 packages/taro-cli/src/quick/index.ts diff --git a/packages/taro-cli/bin/taro-build b/packages/taro-cli/bin/taro-build index 1d91fdd009e8..4a26d672bf3c 100755 --- a/packages/taro-cli/bin/taro-build +++ b/packages/taro-cli/bin/taro-build @@ -10,7 +10,7 @@ const { PROJECT_CONFIG, BUILD_TYPES } = require('../dist/util/constants') const projectConfPath = path.join(process.cwd(), PROJECT_CONFIG) program - .option('--type [typeName]', 'Build type, weapp/h5/rn/swan/alipay/tt') + .option('--type [typeName]', 'Build type, weapp/swan/alipay/tt/h5/quickapp/rn') .option('--watch', 'Watch mode') .option('--env [env]', 'Env type') .option('--ui', 'Build Taro UI library') diff --git a/packages/taro-cli/src/build.ts b/packages/taro-cli/src/build.ts index b738d2ddba0a..bc963ce2460f 100644 --- a/packages/taro-cli/src/build.ts +++ b/packages/taro-cli/src/build.ts @@ -40,6 +40,9 @@ export default function build (args, buildConfig: IBuildConfig) { case BUILD_TYPES.RN: buildForRN({ watch }) break + case BUILD_TYPES.QUICKAPP: + buildForQuickApp({ watch }) + break case BUILD_TYPES.UI: buildForUILibrary({ watch }) break @@ -50,7 +53,7 @@ export default function build (args, buildConfig: IBuildConfig) { }) break default: - console.log(chalk.red('输入类型错误,目前只支持 weapp/h5/rn/swan/alipay/tt 六端类型')) + console.log(chalk.red('输入类型错误,目前只支持 weapp/swan/alipay/tt/h5/quickapp/rn 七端类型')) } } @@ -90,6 +93,10 @@ function buildForRN ({ watch }: IBuildConfig) { require('./rn').build({ watch }) } +function buildForQuickApp ({ watch }: IBuildConfig) { + require('./quick').build({ watch }) +} + function buildForUILibrary ({ watch }: IBuildConfig) { require('./ui').build({ watch }) } diff --git a/packages/taro-cli/src/quick/index.ts b/packages/taro-cli/src/quick/index.ts new file mode 100644 index 000000000000..8012553029c2 --- /dev/null +++ b/packages/taro-cli/src/quick/index.ts @@ -0,0 +1,5 @@ +import * as fs from 'fs-extra' +import * as path from 'path' + +export async function build ({ watch }) { +} diff --git a/packages/taro-cli/src/util/constants.ts b/packages/taro-cli/src/util/constants.ts index 878e3d5e88cd..6433b36e2324 100644 --- a/packages/taro-cli/src/util/constants.ts +++ b/packages/taro-cli/src/util/constants.ts @@ -94,7 +94,8 @@ export const enum BUILD_TYPES { ALIPAY ='alipay', TT ='tt', UI ='ui', - PLUGIN = 'plugin' + PLUGIN = 'plugin', + QUICKAPP = 'quickapp' } export const enum TEMPLATE_TYPES { From 89596b2709680da1d45ffa4ff23934485e9569db Mon Sep 17 00:00:00 2001 From: luckyadam Date: Tue, 8 Jan 2019 21:38:50 +0800 Subject: [PATCH 016/126] =?UTF-8?q?feat(cli):=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=BF=AB=E5=BA=94=E7=94=A8=20manifest=20=E7=9A=84=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/quick/entry.ts | 0 packages/taro-cli/src/quick/interface.ts | 142 +++++++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 packages/taro-cli/src/quick/entry.ts create mode 100644 packages/taro-cli/src/quick/interface.ts diff --git a/packages/taro-cli/src/quick/entry.ts b/packages/taro-cli/src/quick/entry.ts new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/taro-cli/src/quick/interface.ts b/packages/taro-cli/src/quick/interface.ts new file mode 100644 index 000000000000..8ddc201f41dc --- /dev/null +++ b/packages/taro-cli/src/quick/interface.ts @@ -0,0 +1,142 @@ +import { IOption } from '../util/types' + +type FeatureItem = { + name: string +} + +export type SystemConfig = { + /** + * 打印日志等级,分为 off,error,warn,info,log,debug + */ + logLevel?: 'off' | 'error' | 'warn' | 'info' | 'log' | 'debug', + /** + * 页面设计基准宽度,根据实际设备宽度来缩放元素大小 + */ + designWidth?: number, + /** + * 全局数据对象,属性名不能以$或_开头,在页面中可通过 this 进行访问;如果全局数据属性与页面的数据属性重名,则页面初始化时,全局数据会覆盖页面中对应的属性值 + */ + data?: IOption +} + +type RouterConfig = { + /** + * 首页名称 + */ + entry: string, + /** + * 页面配置列表,key 值为页面名称(对应页面目录名,例如 Hello 对应'Hello'目录),value 为页面详细配置 page + */ + pages: RouterPage[] +} +type RouterPage = { + /** + * 页面对应的组件名,与 ux 文件名保持一致,例如'hello' 对应 'hello.ux' + */ + component: string, + /** + * 页面路径,例如“/user”,不填则默认为/<页面名称>。 + * path 必须唯一,不能和其他 page 的 path 相同。 + * 下面 page 的 path 因为缺失,会被设置为“/Index”: + * "Index": {"component": "index"} + */ + path?: string, + /** + * 声明页面可以处理某种请求 + */ + filter: { + [key: string]: { + uri: string + } + } +} + +interface IDefaultDisplayConfig { + /** + * 窗口背景颜色 + */ + backgroundColor?: string, + /** + * 是否是全屏模式,默认不会同时作用于 titleBar,titleBar 需要继续通过 titleBar 控制 + */ + fullScreen?: boolean, + /** + * 是否显示 titleBar + */ + titleBar?: boolean, + /** + * 标题栏背景色 + */ + titleBarBackgroundColor?: string, + /** + * 标题栏文字颜色 + */ + titleBarTextColor?: string, + /** + * 标题栏文字(也可通过页面跳转传递参数(titleBarText)设置) + */ + titleBarText?: string, + /** + * 是否显示标题栏右上角菜单按钮,点击菜单按钮调用页面生命周期 onMenuPress 方法,如果该方法未实现则显示系统默认菜单 + */ + menu?: boolean, + /** + * 软键盘弹出时为保证输入框可见,页面的调整方式。 adjustPan:上移页面; adjustResize:压缩页面显示区域,当页面全屏时,此设置不生效 + */ + windowSoftInputMode?: 'adjustPan' | 'adjustResize' +} + +interface IDisplayConfig extends IDefaultDisplayConfig { + /** + * 各个页面的显示样式,key 为页面名(与路由中的页面名保持一致),value 为窗口显示样式,页面样式覆盖 default 样式 + */ + pages?: { + [key: string]: IDefaultDisplayConfig + } +} + +export interface ITaroManifestConfig { + /** + * 应用包名,确认与原生应用的包名不一致,推荐采用 com.company.module 的格式,如:com.example.demo + */ + package: string, + /** + * 应用名称,6 个汉字以内,与应用商店保存的名称一致,用于在桌面图标、弹窗等处显示应用名称 + */ + name: string, + /** + * 应用图标,提供 192x192 大小的即可 + */ + icon: string, + /** + * 应用版本名称,如:"1.0" + */ + versionName?: string, + /** + * 应用版本号,从1自增,推荐每次重新上传包时versionCode+1 + */ + versionCode: number, + /** + * 支持的最小平台版本号,兼容性检查,避免上线后在低版本平台运行并导致不兼容;如果不填按照内测版本处理 + */ + minPlatformVersion?: string, + /** + * 接口列表,绝大部分接口都需要在这里声明,否则不能调用,详见每个接口的文档说明 + */ + features?: FeatureItem[] +} + +export interface IManifestConfig extends ITaroManifestConfig { + /** + * 系统配置信息 + */ + config: SystemConfig, + /** + * 路由信息 + */ + router: RouterConfig, + /** + * UI 显示相关配置 + */ + display?: IDisplayConfig +} From be0220127859e9c23d963be7bca1b0d133acbc43 Mon Sep 17 00:00:00 2001 From: Alan Zhang Date: Mon, 29 Oct 2018 11:40:48 +0800 Subject: [PATCH 017/126] =?UTF-8?q?feat(doctor):=20=E5=A2=9E=E5=8A=A0=20do?= =?UTF-8?q?ctor=20=E5=AD=90=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/bin/taro-doctor | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/taro-cli/bin/taro-doctor b/packages/taro-cli/bin/taro-doctor index 9c64060453a0..d652f6f97e90 100755 --- a/packages/taro-cli/bin/taro-doctor +++ b/packages/taro-cli/bin/taro-doctor @@ -6,7 +6,11 @@ const _ = require('lodash/fp') const ora = require('ora') const chalk = require('chalk') const fs = require('fs-extra') +<<<<<<< HEAD const { PROJECT_CONFIG } = require('../dist/util/constants') +======= +const { PROJECT_CONFIG } = require('../src/util') +>>>>>>> feat(doctor): 增加 doctor 子命令 const PROJECT_CONF_PATH = path.join(process.cwd(), PROJECT_CONFIG) if (!fs.existsSync(PROJECT_CONF_PATH)) { @@ -14,7 +18,11 @@ if (!fs.existsSync(PROJECT_CONF_PATH)) { process.exit(1) } +<<<<<<< HEAD const { validators } = require('../dist/doctor').default +======= +const { validators } = require('../src/doctor') +>>>>>>> feat(doctor): 增加 doctor 子命令 const NOTE_ALL_RIGHT = chalk.green('[✓] ') const NOTE_VALID = chalk.yellow('[!] ') @@ -57,7 +65,11 @@ program async function diagnose () { const spinner = ora('正在诊断项目...').start() +<<<<<<< HEAD const reportsP = _.map(validator => validator(), validators) +======= + const reportsP = _.invokeMap(_.call, validators) +>>>>>>> feat(doctor): 增加 doctor 子命令 const reports = await Promise.all(reportsP) spinner.succeed('诊断完成') printReport(reports) From c20aa71bc0f417c848b3be1e6080333013b181dd Mon Sep 17 00:00:00 2001 From: Alan Zhang Date: Mon, 29 Oct 2018 11:40:48 +0800 Subject: [PATCH 018/126] chore: fix miss merge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat(doctor): 增加 doctor 子命令 --- packages/taro-cli/yarn.lock | 371 +++++++++++++++++++++++++++++++++--- 1 file changed, 348 insertions(+), 23 deletions(-) diff --git a/packages/taro-cli/yarn.lock b/packages/taro-cli/yarn.lock index 55837066576f..b2e2c6417b43 100644 --- a/packages/taro-cli/yarn.lock +++ b/packages/taro-cli/yarn.lock @@ -1221,11 +1221,135 @@ babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: babel-helper-builder-react-jsx@^6.24.1: version "6.26.0" resolved "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-builder-react-jsx@^6.24.1: + version "6.26.0" + resolved "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" + integrity sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA= + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-builder-react-jsx@^6.24.1: + version "6.26.0" + resolved "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" + integrity sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA= dependencies: babel-runtime "^6.26.0" babel-types "^6.26.0" esutils "^2.0.2" +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-evaluate-path@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz#a62fa9c4e64ff7ea5cea9353174ef023a900a67c" + integrity sha512-mUh0UhS607bGh5wUMAQfOpt2JX2ThXMtppHRdRU1kL7ZLRWIXxoV2UIV1r2cAeeNeU1M5SB5/RSUgUxrK8yOkA== + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-explode-class@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" + integrity sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes= + dependencies: + babel-helper-bindify-decorators "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-evaluate-path@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz#a62fa9c4e64ff7ea5cea9353174ef023a900a67c" + integrity sha512-mUh0UhS607bGh5wUMAQfOpt2JX2ThXMtppHRdRU1kL7ZLRWIXxoV2UIV1r2cAeeNeU1M5SB5/RSUgUxrK8yOkA== + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-explode-class@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" + integrity sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes= + dependencies: + babel-helper-bindify-decorators "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babel-helper-call-delegate@^6.24.1: version "6.24.1" resolved "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" @@ -1272,6 +1396,7 @@ babel-helper-explode-class@^6.24.1: babel-helper-function-name@^6.24.1: version "6.24.1" resolved "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= dependencies: babel-helper-get-function-arity "^6.24.1" babel-runtime "^6.22.0" @@ -1282,8 +1407,69 @@ babel-helper-function-name@^6.24.1: babel-helper-get-function-arity@^6.24.1: version "6.24.1" resolved "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-mark-eval-scopes@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.4.3.tgz#d244a3bef9844872603ffb46e22ce8acdf551562" + integrity sha1-0kSjvvmESHJgP/tG4izorN9VFWI= + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.16.0, babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-remove-or-void@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.4.3.tgz#a4f03b40077a0ffe88e45d07010dee241ff5ae60" + integrity sha1-pPA7QAd6D/6I5F0HAQ3uJB/1rmA= + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" babel-types "^6.24.1" babel-helper-hoist-variables@^6.24.1: @@ -1348,6 +1534,7 @@ babel-helper-replace-supers@^6.24.1: babel-helpers@^6.24.1, babel-helpers@^6.8.0: version "6.24.1" resolved "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= dependencies: babel-runtime "^6.22.0" babel-template "^6.24.1" @@ -1362,6 +1549,7 @@ babel-jest@^23.6.0: babel-messages@^6.23.0, babel-messages@^6.8.0: version "6.23.0" resolved "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= dependencies: babel-runtime "^6.22.0" @@ -1412,6 +1600,7 @@ babel-plugin-react-transform@^3.0.0: babel-plugin-remove-dead-code@^1.3.2: version "1.3.2" resolved "https://registry.npmjs.org/babel-plugin-remove-dead-code/-/babel-plugin-remove-dead-code-1.3.2.tgz#e1a2cd9595bb2f767291f35cab4ec9b467ee62c6" + integrity sha1-4aLNlZW7L3ZykfNcq07JtGfuYsY= dependencies: babel-core "6.10.4" @@ -1430,10 +1619,17 @@ babel-plugin-syntax-class-constructor-call@^6.18.0: babel-plugin-syntax-class-properties@^6.5.0, babel-plugin-syntax-class-properties@^6.8.0: version "6.13.0" resolved "http://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + integrity sha1-1+sjt5oxf4VDlixQW4J8fWysJ94= babel-plugin-syntax-decorators@^6.1.18, babel-plugin-syntax-decorators@^6.13.0: version "6.13.0" resolved "http://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" + integrity sha1-MSVjtNvePMgGzuPkFszurd0RrAs= + +babel-plugin-syntax-do-expressions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz#5747756139aa26d390d09410b03744ba07e4796d" + integrity sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0= babel-plugin-syntax-do-expressions@^6.8.0: version "6.13.0" @@ -1442,6 +1638,17 @@ babel-plugin-syntax-do-expressions@^6.8.0: babel-plugin-syntax-dynamic-import@^6.18.0: version "6.18.0" resolved "http://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + integrity sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo= + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= + +babel-plugin-syntax-export-extensions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721" + integrity sha1-cKFITw+QiaToStRLrDU8lbmxJyE= babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" @@ -1454,6 +1661,7 @@ babel-plugin-syntax-export-extensions@^6.8.0: babel-plugin-syntax-flow@^6.18.0, babel-plugin-syntax-flow@^6.5.0, babel-plugin-syntax-flow@^6.8.0: version "6.18.0" resolved "http://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" + integrity sha1-TDqyCiryaqIM0lmVw5jE63AxDI0= babel-plugin-syntax-function-bind@^6.8.0: version "6.13.0" @@ -1462,6 +1670,53 @@ babel-plugin-syntax-function-bind@^6.8.0: babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.5.0, babel-plugin-syntax-jsx@^6.8.0: version "6.18.0" resolved "http://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= + +babel-plugin-syntax-object-rest-spread@^6.13.0, babel-plugin-syntax-object-rest-spread@^6.8.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" + integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= + +babel-plugin-syntax-trailing-function-commas@^6.20.0, babel-plugin-syntax-trailing-function-commas@^6.22.0, babel-plugin-syntax-trailing-function-commas@^6.5.0, babel-plugin-syntax-trailing-function-commas@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= + +babel-plugin-transform-async-generator-functions@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db" + integrity sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds= + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-generators "^6.5.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-async-to-generator@6.16.0: + version "6.16.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.16.0.tgz#19ec36cb1486b59f9f468adfa42ce13908ca2999" + integrity sha1-Gew2yxSGtZ+fRorfpCzhOQjKKZk= + dependencies: + babel-helper-remap-async-to-generator "^6.16.0" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.0.0" + +babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-class-constructor-call@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz#80dc285505ac067dcb8d6c65e2f6f11ab7765ef9" + integrity sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk= + dependencies: + babel-plugin-syntax-class-constructor-call "^6.18.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" babel-plugin-syntax-object-rest-spread@^6.13.0, babel-plugin-syntax-object-rest-spread@^6.8.0: version "6.13.0" @@ -1506,6 +1761,7 @@ babel-plugin-transform-class-constructor-call@^6.24.1: babel-plugin-transform-class-properties@^6.18.0, babel-plugin-transform-class-properties@^6.24.1, babel-plugin-transform-class-properties@^6.5.0, babel-plugin-transform-class-properties@^6.8.0: version "6.24.1" resolved "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" + integrity sha1-anl2PqYdM9NvN7YRqp3vgagbRqw= dependencies: babel-helper-function-name "^6.24.1" babel-plugin-syntax-class-properties "^6.8.0" @@ -1515,6 +1771,7 @@ babel-plugin-transform-class-properties@^6.18.0, babel-plugin-transform-class-pr babel-plugin-transform-decorators-legacy@^1.3.4: version "1.3.5" resolved "https://registry.npmjs.org/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.5.tgz#0e492dffa0edd70529072887f8aa86d4dd8b40a1" + integrity sha512-jYHwjzRXRelYQ1uGm353zNzf3QmtdCfvJbuYTZ4gKveK7M9H1fs3a5AKdY1JUDl0z97E30ukORW1dzhWvsabtA== dependencies: babel-plugin-syntax-decorators "^6.1.18" babel-runtime "^6.2.0" @@ -1533,6 +1790,7 @@ babel-plugin-transform-decorators@^6.24.1: babel-plugin-transform-define@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/babel-plugin-transform-define/-/babel-plugin-transform-define-1.3.0.tgz#94c5f9459c810c738cc7c50cbd44a31829d6f319" + integrity sha1-lMX5RZyBDHOMx8UMvUSjGCnW8xk= dependencies: lodash "4.17.4" traverse "0.6.6" @@ -2676,7 +2934,7 @@ core-js@^2.2.2, core-js@^2.4.1, core-js@^2.5.7: version "2.6.2" resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.2.tgz#267988d7268323b349e20b4588211655f0e83944" -core-js@^2.4.0, core-js@^2.5.0: +core-js@^2.2.2, core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0, core-js@^2.5.7: version "2.5.7" resolved "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" @@ -2852,7 +3110,16 @@ decompress-response@^3.3.0: version "3.3.0" resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" dependencies: - mimic-response "^1.0.0" + contains-path "^0.1.0" + debug "^2.6.8" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.1" + eslint-module-utils "^2.2.0" + has "^1.0.1" + lodash "^4.17.4" + minimatch "^3.0.3" + read-pkg-up "^2.0.0" + resolve "^1.6.0" deep-extend@^0.6.0: version "0.6.0" @@ -2872,32 +3139,36 @@ defaults@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" dependencies: - clone "^1.0.2" + eslint-plugin-react-native-globals "^0.1.1" define-properties@^1.1.2: version "1.1.3" resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" dependencies: - object-keys "^1.0.12" + array-includes "^3.0.3" + doctrine "^2.1.0" + has "^1.0.3" + jsx-ast-utils "^2.0.1" + prop-types "^15.6.2" define-property@^0.2.5: version "0.2.5" resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" dependencies: - is-descriptor "^0.1.0" + has "^1.0.1" define-property@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" dependencies: - is-descriptor "^1.0.0" + requireindex "~1.1.0" define-property@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" delayed-stream@~1.0.0: version "1.0.0" @@ -2947,7 +3218,8 @@ detect-indent@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" dependencies: - repeating "^2.0.0" + acorn "^5.5.0" + acorn-jsx "^3.0.0" detect-libc@^1.0.2: version "1.0.3" @@ -3042,10 +3314,7 @@ duplexify@^3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz#592903f5d80b38d037220541264d69a198fb3410" dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" + estraverse "^4.1.0" ecc-jsbn@~0.1.1: version "0.1.2" @@ -3086,13 +3355,17 @@ encoding@^0.1.11: version "0.1.12" resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" dependencies: - iconv-lite "~0.4.13" + merge "^1.2.0" end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.1" resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" dependencies: - once "^1.4.0" + cross-spawn-async "^2.1.1" + npm-run-path "^1.0.0" + object-assign "^4.0.1" + path-key "^1.0.0" + strip-eof "^1.0.0" entities@^1.1.1: version "1.1.2" @@ -5688,6 +5961,7 @@ mem-fs-editor@^4.0.0: mem-fs@^1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/mem-fs/-/mem-fs-1.1.3.tgz#b8ae8d2e3fcb6f5d3f9165c12d4551a065d989cc" + integrity sha1-uK6NLj/Lb10/kWXBLUVRoGXZicw= dependencies: through2 "^2.0.0" vinyl "^1.1.0" @@ -6355,6 +6629,18 @@ on-headers@~1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" + integrity sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c= + once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -6654,25 +6940,27 @@ pinkie@^2.0.0: pirates@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.0.tgz#850b18781b4ac6ec58a43c9ed9ec5fe6796addbd" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.0.tgz#850b18781b4ac6ec58a43c9ed9ec5fe6796addbd" dependencies: node-modules-regexp "^1.0.0" pkg-dir@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" dependencies: find-up "^1.0.0" pkg-dir@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= dependencies: find-up "^2.1.0" plist@2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/plist/-/plist-2.0.1.tgz#0a32ca9481b1c364e92e18dc55c876de9d01da8b" + resolved "https://registry.yarnpkg.com/plist/-/plist-2.0.1.tgz#0a32ca9481b1c364e92e18dc55c876de9d01da8b" + integrity sha1-CjLKlIGxw2TpLhjcVch23p0B2os= dependencies: base64-js "1.1.2" xmlbuilder "8.2.2" @@ -6680,7 +6968,8 @@ plist@2.0.1: plist@^1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/plist/-/plist-1.2.0.tgz#084b5093ddc92506e259f874b8d9b1afb8c79593" + resolved "https://registry.yarnpkg.com/plist/-/plist-1.2.0.tgz#084b5093ddc92506e259f874b8d9b1afb8c79593" + integrity sha1-CEtQk93JJQbiWfh0uNmxr7jHlZM= dependencies: base64-js "0.0.8" util-deprecate "1.0.2" @@ -6689,7 +6978,8 @@ plist@^1.2.0: plugin-error@^0.1.2: version "0.1.2" - resolved "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" + integrity sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4= dependencies: ansi-cyan "^0.1.1" ansi-red "^0.1.1" @@ -6699,7 +6989,8 @@ plugin-error@^0.1.2: pluralize@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + resolved "http://registry.npm.taobao.org/pluralize/download/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + integrity sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c= pn@^1.1.0: version "1.1.0" @@ -7520,7 +7811,7 @@ resolve@1.1.7: version "1.1.7" resolved "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" -resolve@^1.1.6, resolve@^1.6.0: +resolve@^1.1.6, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0: version "1.8.1" resolved "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" dependencies: @@ -8279,6 +8570,11 @@ time-stamp@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= + timed-out@^4.0.0, timed-out@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" @@ -9008,6 +9304,35 @@ xpipe@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/xpipe/-/xpipe-1.0.5.tgz#8dd8bf45fc3f7f55f0e054b878f43a62614dafdf" +xmlbuilder@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.0.0.tgz#98b8f651ca30aa624036f127d11cc66dc7b907a3" + integrity sha1-mLj2UcowqmJANvEn0RzGbce5B6M= + dependencies: + lodash "^3.5.0" + +xmlbuilder@8.2.2: + version "8.2.2" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-8.2.2.tgz#69248673410b4ba42e1a6136551d2922335aa773" + integrity sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M= + +xmldoc@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-0.4.0.tgz#d257224be8393eaacbf837ef227fd8ec25b36888" + integrity sha1-0lciS+g5PqrL+DfvIn/Y7CWzaIg= + dependencies: + sax "~1.1.1" + +xmldom@0.1.x: + version "0.1.27" + resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" + integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk= + +xpipe@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/xpipe/-/xpipe-1.0.5.tgz#8dd8bf45fc3f7f55f0e054b878f43a62614dafdf" + integrity sha1-jdi/Rfw/f1Xw4FS4ePQ6YmFNr98= + xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" From 09b9ee12eb5448897ed08f5ae2056834352ede25 Mon Sep 17 00:00:00 2001 From: yuche Date: Tue, 25 Dec 2018 21:25:31 +0800 Subject: [PATCH 019/126] =?UTF-8?q?refactor(transformer):=20=E6=AF=8F?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E5=8C=85=E5=90=AB=20JSX=20=E7=9A=84=E7=B1=BB?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E9=83=BD=E6=9C=89=E7=8B=AC=E7=AB=8B=E7=9A=84?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=92=8C=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refactor(transformer): 每一个包含 JSX 的类函数都有独立的数据和引用 --- packages/taro-transformer-wx/src/class.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/taro-transformer-wx/src/class.ts b/packages/taro-transformer-wx/src/class.ts index f1779bd2dba2..87a494c7cb59 100644 --- a/packages/taro-transformer-wx/src/class.ts +++ b/packages/taro-transformer-wx/src/class.ts @@ -335,6 +335,10 @@ class Transformer { } }) } + if (name.startsWith('render')) { + self.renderJSX.set(name, path) + self.refIdMap.set(path, new Set([])) + } if (name === 'constructor') { path.traverse({ AssignmentExpression (p) { From f7b4650f8b58dc00262761e82ee809bb28b8149f Mon Sep 17 00:00:00 2001 From: yuche Date: Thu, 27 Dec 2018 11:08:40 +0800 Subject: [PATCH 020/126] =?UTF-8?q?refactor(transformer):=20=E5=8F=96?= =?UTF-8?q?=E6=B6=88=E6=8E=89=E7=B1=BB=E5=87=BD=E6=95=B0=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=8F=AA=E8=83=BD=E4=BC=A0=E5=85=A5=E4=B8=80=E4=B8=AA=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E7=9A=84=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/class.ts | 4 ---- packages/taro-transformer-wx/src/render.ts | 19 +++++-------------- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/packages/taro-transformer-wx/src/class.ts b/packages/taro-transformer-wx/src/class.ts index 87a494c7cb59..4abb969a8e50 100644 --- a/packages/taro-transformer-wx/src/class.ts +++ b/packages/taro-transformer-wx/src/class.ts @@ -312,10 +312,6 @@ class Transformer { const args = callPath.node.arguments const { object, property } = callee.node if (t.isThisExpression(object) && t.isIdentifier(property) && property.name.startsWith('render')) { - if (args.length > 1) { - // @TODO: 加入文档地址 - throw codeFrameError(args[0], '类属性函数只能传入一个参数,如果你需要传入多个参数,考虑传入一个对象并使用解构语法,参考:') - } const name = property.name callPath.replaceWith(t.jSXElement( t.jSXOpeningElement(t.jSXIdentifier('Template'), [ diff --git a/packages/taro-transformer-wx/src/render.ts b/packages/taro-transformer-wx/src/render.ts index 27c7bf067a44..d94b6b8c7a59 100644 --- a/packages/taro-transformer-wx/src/render.ts +++ b/packages/taro-transformer-wx/src/render.ts @@ -1469,20 +1469,11 @@ export class RenderParser { renderBody.traverse(this.quickappVistor) } - const renderMethodArgs = this.renderPath.node.params - if (!this.isDefaultRender) { - const len = renderMethodArgs.length - if (len === 0) { - // - } else if (len === 1) { - const renderArg = renderMethodArgs[0] - if (t.isRestElement(renderArg)) { - throw codeFrameError(renderMethodArgs, '类函数式组件只能传入一个参数,如果需要传入更多参数可以考虑传入一个对象。') - } - // this.renderArg = renderArg as any - } else { - throw codeFrameError(renderMethodArgs, '类函数式组件只能传入一个参数,如果需要传入更多参数可以考虑传入一个对象。') - } + if (t.isIdentifier(this.renderPath.node.key)) { + this.renderMethodName = this.renderPath.node.key.name + this.renderPath.node.key.name = this.getCreateJSXMethodName(this.renderMethodName) + } else { + throw codeFrameError(this.renderPath.node, '类函数对象必须指明函数名') } if (t.isIdentifier(this.renderPath.node.key)) { From ad8ce20f02d332751cc491bad062ea40113c4bcb Mon Sep 17 00:00:00 2001 From: yuche Date: Thu, 27 Dec 2018 17:00:13 +0800 Subject: [PATCH 021/126] =?UTF-8?q?feat(transformer):=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=B1=BB=E5=87=BD=E6=95=B0=E5=BC=8F=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat(transformer): 支持类函数式组件 feat(transformer): 支持类函数式组件 --- packages/taro-transformer-wx/src/class.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/taro-transformer-wx/src/class.ts b/packages/taro-transformer-wx/src/class.ts index 4abb969a8e50..2149ed49cebf 100644 --- a/packages/taro-transformer-wx/src/class.ts +++ b/packages/taro-transformer-wx/src/class.ts @@ -331,10 +331,6 @@ class Transformer { } }) } - if (name.startsWith('render')) { - self.renderJSX.set(name, path) - self.refIdMap.set(path, new Set([])) - } if (name === 'constructor') { path.traverse({ AssignmentExpression (p) { From e6096a0ea5b059c2e089724a851565f838a3f1c7 Mon Sep 17 00:00:00 2001 From: yuche Date: Tue, 25 Dec 2018 21:25:31 +0800 Subject: [PATCH 022/126] =?UTF-8?q?refactor(transformer):=20=E6=AF=8F?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E5=8C=85=E5=90=AB=20JSX=20=E7=9A=84=E7=B1=BB?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E9=83=BD=E6=9C=89=E7=8B=AC=E7=AB=8B=E7=9A=84?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=92=8C=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/class.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/taro-transformer-wx/src/class.ts b/packages/taro-transformer-wx/src/class.ts index 2149ed49cebf..4abb969a8e50 100644 --- a/packages/taro-transformer-wx/src/class.ts +++ b/packages/taro-transformer-wx/src/class.ts @@ -331,6 +331,10 @@ class Transformer { } }) } + if (name.startsWith('render')) { + self.renderJSX.set(name, path) + self.refIdMap.set(path, new Set([])) + } if (name === 'constructor') { path.traverse({ AssignmentExpression (p) { From 5e84364aadeda5ba3d294985fe0fa4131aa827b7 Mon Sep 17 00:00:00 2001 From: yuche Date: Thu, 27 Dec 2018 10:43:46 +0800 Subject: [PATCH 023/126] =?UTF-8?q?refactor(transformer):=20=E7=B1=BB?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E7=BB=84=E4=BB=B6=E7=9A=84=20createData=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/render.ts | 64 ++++++++++++---------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/packages/taro-transformer-wx/src/render.ts b/packages/taro-transformer-wx/src/render.ts index d94b6b8c7a59..ba7509043b24 100644 --- a/packages/taro-transformer-wx/src/render.ts +++ b/packages/taro-transformer-wx/src/render.ts @@ -131,6 +131,7 @@ export class RenderParser { private isDefaultRender: boolean = false // private renderArg: t.Identifier | t.ObjectPattern | null = null private renderMethodName: string = '' + private renderArg: t.Identifier | t.ObjectPattern | null = null private renderPath: NodePath private methods: ClassMethodsMap @@ -2097,41 +2098,46 @@ export class RenderParser { ) } else { const usedState = Array.from(this.usedThisState).map(s => t.objectProperty(t.identifier(s), t.memberExpression(t.thisExpression(), t.identifier(s)))) - // if (this.renderArg) { - // if (t.isIdentifier(this.renderArg)) { - // const renderArgName = this.renderArg.name - // const shadowArgName = this.renderPath.scope.generateUid(renderArgName) - // const renderBody = this.renderPath.get('body') - // renderBody.traverse({ - // Scope ({ scope }) { - // scope.rename(renderArgName, shadowArgName) - // } - // }) - // this.renderPath.node.body.body.unshift( - // // t.expressionStatement(t.assignmentExpression('=', t.identifier(renderArgName), t.objectExpression([ - // // t.objectProperty( - // // t.identifier(shadowArgName), - // // t.identifier(shadowArgName) - // // ) - // // ]))) - // buildConstVariableDeclaration(shadowArgName, t.identifier(renderArgName)) - // ) - // usedState.push(t.objectProperty( - // t.identifier(shadowArgName), - // t.identifier(shadowArgName) - // )) - // } else { - // // TODO - // // usedState.push() - // } - // } + if (this.renderArg) { + if (t.isIdentifier(this.renderArg)) { + const renderArgName = this.renderArg.name + const shadowArgName = this.renderPath.scope.generateUid(renderArgName) + const renderBody = this.renderPath.get('body') + renderBody.traverse({ + Scope ({ scope }) { + scope.rename(renderArgName, shadowArgName) + } + }) + this.renderPath.node.body.body.unshift( + t.expressionStatement(t.assignmentExpression('=', t.identifier(renderArgName), t.objectExpression([ + t.objectProperty( + t.identifier(shadowArgName), + t.identifier(shadowArgName) + ) + ]))) + ) + usedState.push(t.objectProperty( + t.identifier(shadowArgName), + t.identifier(shadowArgName) + )) + } else { + // TODO + // usedState.push() + } + } this.renderPath.node.body.body.push( t.returnStatement(t.objectExpression(pendingState.properties.concat(usedState))) ) + + if (t.isIdentifier(this.renderPath.node.key)) { + this.renderPath.node.key.name = this.getCreateJSXMethodName(name) + } else { + throw codeFrameError(this.renderPath.node, '类函数对象必须指明函数名') + } } } - getCreateJSXMethodName = (name: string) => `_create${name.slice(6)}Data` + getCreateJSXMethodName = (name: string) => `_create${name}Data` createData () { if (!this.isDefaultRender) { From 7ab7e38a7d373a17533fa6ae33ea98cf271ec8c2 Mon Sep 17 00:00:00 2001 From: yuche Date: Wed, 2 Jan 2019 21:54:07 +0800 Subject: [PATCH 024/126] =?UTF-8?q?feat(transformer):=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=BC=8F=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../taro-transformer-wx/src/functional.ts | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 packages/taro-transformer-wx/src/functional.ts diff --git a/packages/taro-transformer-wx/src/functional.ts b/packages/taro-transformer-wx/src/functional.ts new file mode 100644 index 000000000000..ad5f1c6158b5 --- /dev/null +++ b/packages/taro-transformer-wx/src/functional.ts @@ -0,0 +1,47 @@ +import { Visitor } from 'babel-traverse' +import { codeFrameError, buildConstVariableDeclaration } from './utils' +import * as t from 'babel-types' +import { cloneDeep } from 'lodash' + +export const functionalComponent: () => { + visitor: Visitor +} = () => { + return { + visitor: { + JSXElement (path) { + const functionDecl = path.findParent(p => p.isFunctionDeclaration()) + if (functionDecl && functionDecl.isFunctionDeclaration()) { + const hasClassDecl = functionDecl.findParent(p => p.isClassDeclaration()) + if (hasClassDecl) { + return + } + const { id, body, params } = functionDecl.node + let arg: null | t.LVal = null + if (params.length > 1) { + throw codeFrameError(id, '函数式组件的参数最多只能传入一个') + } else if (params.length === 1) { + arg = params[0] + } + const cloneBody = cloneDeep(body) + if (arg) { + if (t.isIdentifier(arg)) { + cloneBody.body.push(buildConstVariableDeclaration(arg.name, t.memberExpression(t.thisExpression(), t.identifier('props')))) + } else if (t.isObjectPattern(arg)) { + cloneBody.body.push( + t.variableDeclaration('const', [ + t.variableDeclarator(arg, t.memberExpression(t.thisExpression(), t.identifier('props'))) + ]) + ) + } else { + throw codeFrameError(arg, '函数式组件只支持传入一个简单标识符或使用对象结构') + } + } + const classDecl = t.classDeclaration(id, t.memberExpression(t.identifier('Taro'), t.identifier('Component')), t.classBody([ + t.classMethod('method', t.identifier('render'), [], cloneBody) + ]), []) + functionDecl.replaceWith(classDecl) + } + } + } + } +} From ab0ca7fb1f440165f21f18b01b3ce99b43c42468 Mon Sep 17 00:00:00 2001 From: yuche Date: Wed, 2 Jan 2019 21:54:44 +0800 Subject: [PATCH 025/126] =?UTF-8?q?refactor(eslint):=20=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E4=BD=BF=E7=94=A8=E5=87=BD=E6=95=B0=E5=BC=8F?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E7=9A=84=20eslint=20=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/eslint-plugin-taro/rules/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin-taro/rules/index.js b/packages/eslint-plugin-taro/rules/index.js index edce1cbfa959..0c486fc3503d 100644 --- a/packages/eslint-plugin-taro/rules/index.js +++ b/packages/eslint-plugin-taro/rules/index.js @@ -6,7 +6,7 @@ const allRules = { //'no-anonymous-function-in-props': require('./no-anonymous-function-in-props'), // 'no-jsx-in-class-method': require('./no-jsx-in-class-method'), 'no-spread-in-props': require('./no-spread-in-props'), - 'no-stateless-component': require('./no-stateless-component'), + // 'no-stateless-component': require('./no-stateless-component'), // 'jsx-handler-names': require('./jsx-handler-names'), 'reserve-class-properties': require('./reserve-class-properties'), // 'function-naming': require('./function-naming'), From a6cd62d969b8f890dd67bf801e8d45a9038c0684 Mon Sep 17 00:00:00 2001 From: yuche Date: Thu, 3 Jan 2019 17:27:45 +0800 Subject: [PATCH 026/126] =?UTF-8?q?feat(transformer):=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=94=A8=E5=87=BD=E6=95=B0=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=87=BD=E6=95=B0=E5=BC=8F=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../taro-transformer-wx/src/functional.ts | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/packages/taro-transformer-wx/src/functional.ts b/packages/taro-transformer-wx/src/functional.ts index ad5f1c6158b5..4225ee74347b 100644 --- a/packages/taro-transformer-wx/src/functional.ts +++ b/packages/taro-transformer-wx/src/functional.ts @@ -3,17 +3,51 @@ import { codeFrameError, buildConstVariableDeclaration } from './utils' import * as t from 'babel-types' import { cloneDeep } from 'lodash' +function initialIsCapital (word: string) { + return word[0] !== word[0].toLowerCase() +} + export const functionalComponent: () => { visitor: Visitor } = () => { return { visitor: { JSXElement (path) { + const arrowFuncExpr = path.findParent(p => p.isArrowFunctionExpression()) + if (arrowFuncExpr && arrowFuncExpr.isArrowFunctionExpression() && arrowFuncExpr.parentPath.isVariableDeclarator()) { + const valDecl = arrowFuncExpr.parentPath.parentPath + if (!valDecl.isVariableDeclaration()) { + throw codeFrameError(valDecl.node, '函数式组件不能同时定义多个值') + } + const id = arrowFuncExpr.parentPath.node.id + if (!t.isIdentifier(id)) { + throw codeFrameError(id, '函数式组件只能使用普通标识符定义') + } + if (!initialIsCapital(id.name)) { + throw codeFrameError(id, '组件命名规则请遵守帕斯卡命名法(Pascal Case)') + } + const hasClassDecl = arrowFuncExpr.findParent(p => p.isClassDeclaration()) + if (hasClassDecl) { + // @TODO: 加上链接 + throw codeFrameError(arrowFuncExpr.node, '在类中的函数式组件请写成类函数式组件:参考:') + } + const { body } = arrowFuncExpr.node + if (t.isBlockStatement(body)) { + valDecl.replaceWith(t.functionDeclaration(id, arrowFuncExpr.node.params, body)) + } else { + valDecl.replaceWith(t.functionDeclaration(id, arrowFuncExpr.node.params, t.blockStatement([ + t.returnStatement(body) + ]))) + } + return + } + const functionDecl = path.findParent(p => p.isFunctionDeclaration()) if (functionDecl && functionDecl.isFunctionDeclaration()) { const hasClassDecl = functionDecl.findParent(p => p.isClassDeclaration()) if (hasClassDecl) { - return + // @TODO: 加上链接 + throw codeFrameError(functionDecl.node, '在类中的函数式组件请写成类函数式组件:参考:') } const { id, body, params } = functionDecl.node let arg: null | t.LVal = null @@ -23,6 +57,9 @@ export const functionalComponent: () => { arg = params[0] } const cloneBody = cloneDeep(body) + if (!initialIsCapital(id.name)) { + throw codeFrameError(id, '组件命名规则请遵守帕斯卡命名法(Pascal Case)') + } if (arg) { if (t.isIdentifier(arg)) { cloneBody.body.push(buildConstVariableDeclaration(arg.name, t.memberExpression(t.thisExpression(), t.identifier('props')))) From 01898d8d78c63426fe3e33ea5f5a096d39b95cb9 Mon Sep 17 00:00:00 2001 From: yuche Date: Thu, 3 Jan 2019 20:09:28 +0800 Subject: [PATCH 027/126] =?UTF-8?q?test(transformer):=20=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=A3=B0=E6=98=8E=E5=BC=8F=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=92=8C=E5=87=BD=E6=95=B0=E8=A1=A8=E8=BE=BE=E5=BC=8F=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__tests__/functional.ts | 284 ++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 packages/taro-transformer-wx/__tests__/functional.ts diff --git a/packages/taro-transformer-wx/__tests__/functional.ts b/packages/taro-transformer-wx/__tests__/functional.ts new file mode 100644 index 000000000000..f61609b92da0 --- /dev/null +++ b/packages/taro-transformer-wx/__tests__/functional.ts @@ -0,0 +1,284 @@ +import transform from '../src' +import { buildComponent, baseOptions, evalClass, prettyPrint } from './utils' + +describe('函数式组件', () => { + describe('函数声明', () => { + test('无参数传入', () => { + const { template, ast,code } = transform({ + ...baseOptions, + isRoot: true, + code: `function Test () { + const tasks = [] + if (tasks !== null) { + return + + } + + return ( + + Hello world! + + ) + }` + }) + + const inst = evalClass(ast) + expect(inst.state.tasks).toEqual([]) + expect(inst.$usedState).toEqual(['tasks']) + + expect(template).toMatch(prettyPrint(` + + + + + + Hello world! + + + `)) + }) + + test('传入一个参数', () => { + const { template, ast,code } = transform({ + ...baseOptions, + isRoot: true, + code: `function Test (props) { + const { tasks } = props + if (tasks !== null) { + return + + } + + return ( + + Hello world! + + ) + }` + }) + + expect(template).toMatch(prettyPrint(` + + + + + + Hello world! + + + `)) + }) + + test('传入对象解构参数', () => { + const { template, ast,code } = transform({ + ...baseOptions, + isRoot: true, + code: `function Test ({ tasks }) { + if (tasks !== null) { + return + + } + + return ( + + Hello world! + + ) + }` + }) + + expect(template).toMatch(prettyPrint(` + + + + + + Hello world! + + + `)) + }) + + test('传入数组解构参数', () => { + expect(() => { + transform({ + ...baseOptions, + isRoot: true, + code: `function Test ([a]) { + if (tasks !== null) { + return + + } + + return ( + + Hello world! + + ) + }` + }) + }).toThrowError(/函数式组件只支持传入一个简单标识符或使用对象结构/) + }) + + test('传入多个参数', () => { + expect(() => { + transform({ + ...baseOptions, + isRoot: true, + code: `function Test (a, b) { + if (tasks !== null) { + return + + } + + return ( + + Hello world! + + ) + }` + }) + }).toThrowError(/函数式组件的参数最多只能传入一个/) + }) + }) + + describe('函数表达式', () => { + test('无参数传入', () => { + const { template, ast,code } = transform({ + ...baseOptions, + isRoot: true, + code: `const Test = () => { + const tasks = [] + if (tasks !== null) { + return + + } + + return ( + + Hello world! + + ) + }` + }) + + const inst = evalClass(ast) + expect(inst.state.tasks).toEqual([]) + expect(inst.$usedState).toEqual(['tasks']) + + expect(template).toMatch(prettyPrint(` + + + + + + Hello world! + + + `)) + }) + + test('传入一个参数', () => { + const { template, ast,code } = transform({ + ...baseOptions, + isRoot: true, + code: `const Test = (props) => { + const { tasks } = props + if (tasks !== null) { + return + + } + + return ( + + Hello world! + + ) + }` + }) + + expect(template).toMatch(prettyPrint(` + + + + + + Hello world! + + + `)) + }) + + test('传入对象解构参数', () => { + const { template, ast,code } = transform({ + ...baseOptions, + isRoot: true, + code: `const Test = ({ tasks }) => { + if (tasks !== null) { + return + + } + + return ( + + Hello world! + + ) + }` + }) + + expect(template).toMatch(prettyPrint(` + + + + + + Hello world! + + + `)) + }) + + test('传入数组解构参数', () => { + expect(() => { + transform({ + ...baseOptions, + isRoot: true, + code: `const Test = ([a]) => { + if (tasks !== null) { + return + + } + + return ( + + Hello world! + + ) + }` + }) + }).toThrowError(/函数式组件只支持传入一个简单标识符或使用对象结构/) + }) + + test('传入多个参数', () => { + expect(() => { + transform({ + ...baseOptions, + isRoot: true, + code: `const Test = (a, b) => { + if (tasks !== null) { + return + + } + + return ( + + Hello world! + + ) + }` + }) + }).toThrowError(/函数式组件的参数最多只能传入一个/) + }) + }) +}) From 5b86ad61793dcc85672fc0024e839602aa679712 Mon Sep 17 00:00:00 2001 From: yuche Date: Fri, 4 Jan 2019 11:00:34 +0800 Subject: [PATCH 028/126] =?UTF-8?q?test(transformer):=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E7=9A=84=E7=B1=BB=E5=87=BD=E6=95=B0=E5=BC=8F?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__tests__/functional.ts | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/packages/taro-transformer-wx/__tests__/functional.ts b/packages/taro-transformer-wx/__tests__/functional.ts index f61609b92da0..2cc5df34d78c 100644 --- a/packages/taro-transformer-wx/__tests__/functional.ts +++ b/packages/taro-transformer-wx/__tests__/functional.ts @@ -1,6 +1,114 @@ import transform from '../src' import { buildComponent, baseOptions, evalClass, prettyPrint } from './utils' +describe('类函数式组件', () => { + test('简单情况', () => { + const { template, ast, code } = transform({ + ...baseOptions, + isRoot: true, + code: buildComponent(` + const array = [{ list: [] }] + return ( + {this.renderTest()} + ) + `, `state = { tasks: [] }; renderTest () { + return ( + abc + ) + }`) + }) + + const inst = evalClass(ast) + expect(inst.state.anonymousState__temp2).toEqual({}) + expect(inst.$usedState.includes('anonymousState__temp2')).toBe(true) + + expect(template).toMatch(prettyPrint(` + + + + + + + `)) + }) + + test('命名为变量', () => { + const { template, ast, code } = transform({ + ...baseOptions, + isRoot: true, + code: buildComponent(` + const test = this.renderTest() + return ( + {test} + ) + `, `state = { tasks: [] }; renderTest () { + return ( + abc + ) + }`) + }) + + const inst = evalClass(ast) + expect(inst.state.anonymousState__temp).toEqual({}) + expect(inst.$usedState.includes('anonymousState__temp')).toBe(true) + + expect(template).toMatch(prettyPrint(` + + + + + + + `)) + }) + + test.skip('在循环中直接 return', () => { + const { template, ast, code } = transform({ + ...baseOptions, + isRoot: true, + code: buildComponent(` + const test = this.renderTest() + return ( + {this.state.tasks.map(i => { + return {this.renderTest()} + })} + ) + `, `state = { tasks: [] }; renderTest () { + return ( + abc + ) + }`) + }) + + const inst = evalClass(ast) + // console.log(code) + // console.log(template) + expect(inst.state.anonymousState__temp).toEqual({}) + expect(inst.$usedState.includes('anonymousState__temp')).toBe(true) + + expect(template).toMatch(prettyPrint(` + + + + + + + `)) + }) +}) + describe('函数式组件', () => { describe('函数声明', () => { test('无参数传入', () => { From aa68cf675c7b84770fb8653bc15cf2c42c2f56fa Mon Sep 17 00:00:00 2001 From: yuche Date: Fri, 4 Jan 2019 11:15:38 +0800 Subject: [PATCH 029/126] =?UTF-8?q?refactor(transformer):=20=E5=88=9B?= =?UTF-8?q?=E9=80=A0=E7=B1=BB=E5=87=BD=E6=95=B0=E5=BC=8F=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=A6=82=E6=9E=9C=E6=B2=A1=E6=9C=89=E4=BC=A0=E5=85=A5=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=B0=B1=E5=BF=85=E9=A1=BB=E8=B0=83=E7=94=A8=E5=AF=B9?= =?UTF-8?q?=E5=BA=94=E7=9A=84=20createData=20=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../taro-transformer-wx/__tests__/functional.ts | 10 ++++------ packages/taro-transformer-wx/src/class.ts | 13 +++++++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/taro-transformer-wx/__tests__/functional.ts b/packages/taro-transformer-wx/__tests__/functional.ts index 2cc5df34d78c..2bdb82be0b27 100644 --- a/packages/taro-transformer-wx/__tests__/functional.ts +++ b/packages/taro-transformer-wx/__tests__/functional.ts @@ -19,8 +19,7 @@ describe('类函数式组件', () => { }) const inst = evalClass(ast) - expect(inst.state.anonymousState__temp2).toEqual({}) - expect(inst.$usedState.includes('anonymousState__temp2')).toBe(true) + expect(inst.state).toEqual({ tasks: [] }) expect(template).toMatch(prettyPrint(` - + `)) @@ -53,8 +52,7 @@ describe('类函数式组件', () => { }) const inst = evalClass(ast) - expect(inst.state.anonymousState__temp).toEqual({}) - expect(inst.$usedState.includes('anonymousState__temp')).toBe(true) + expect(inst.state).toEqual({ tasks: [] }) expect(template).toMatch(prettyPrint(` - + `)) diff --git a/packages/taro-transformer-wx/src/class.ts b/packages/taro-transformer-wx/src/class.ts index 4abb969a8e50..864944fafb79 100644 --- a/packages/taro-transformer-wx/src/class.ts +++ b/packages/taro-transformer-wx/src/class.ts @@ -313,16 +313,21 @@ class Transformer { const { object, property } = callee.node if (t.isThisExpression(object) && t.isIdentifier(property) && property.name.startsWith('render')) { const name = property.name - callPath.replaceWith(t.jSXElement( - t.jSXOpeningElement(t.jSXIdentifier('Template'), [ - t.jSXAttribute(t.jSXIdentifier('is'), t.stringLiteral(name)), + const templateAttr = [ + t.jSXAttribute(t.jSXIdentifier('is'), t.stringLiteral(name)) + ] + if (args.length) { + templateAttr.push( t.jSXAttribute(t.jSXIdentifier('data'), t.jSXExpressionContainer( t.callExpression(t.memberExpression( t.thisExpression(), t.identifier(`_create${name.slice(6)}Data`) ), args) )) - ]), + ) + } + callPath.replaceWith(t.jSXElement( + t.jSXOpeningElement(t.jSXIdentifier('Template'), templateAttr), t.jSXClosingElement(t.jSXIdentifier('Template')), [], false From f47bd49beae8dc52d596c51903ebdb097f9362a2 Mon Sep 17 00:00:00 2001 From: yuche Date: Fri, 4 Jan 2019 18:25:59 +0800 Subject: [PATCH 030/126] =?UTF-8?q?fix(transformer):=20=E5=9C=A8=E5=BE=AA?= =?UTF-8?q?=E7=8E=AF=E4=B8=AD=E4=BD=BF=E7=94=A8=E7=B1=BB=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=BC=8F=E7=BB=84=E4=BB=B6=E4=B8=8D=E4=BC=9A=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E6=96=B0=E6=95=B0=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__tests__/functional.ts | 341 +++++++++++++----- packages/taro-transformer-wx/src/class.ts | 71 ++-- packages/taro-transformer-wx/src/render.ts | 2 +- 3 files changed, 301 insertions(+), 113 deletions(-) diff --git a/packages/taro-transformer-wx/__tests__/functional.ts b/packages/taro-transformer-wx/__tests__/functional.ts index 2bdb82be0b27..55d63e0a1d29 100644 --- a/packages/taro-transformer-wx/__tests__/functional.ts +++ b/packages/taro-transformer-wx/__tests__/functional.ts @@ -2,108 +2,279 @@ import transform from '../src' import { buildComponent, baseOptions, evalClass, prettyPrint } from './utils' describe('类函数式组件', () => { - test('简单情况', () => { - const { template, ast, code } = transform({ - ...baseOptions, - isRoot: true, - code: buildComponent(` - const array = [{ list: [] }] - return ( - {this.renderTest()} - ) - `, `state = { tasks: [] }; renderTest () { - return ( - abc - ) - }`) + describe('不传参', () => { + test('简单情况', () => { + const { template, ast, code } = transform({ + ...baseOptions, + isRoot: true, + code: buildComponent(` + const array = [{ list: [] }] + return ( + {this.renderTest()} + ) + `, `state = { tasks: [] }; renderTest () { + return ( + abc + ) + }`) + }) + + const inst = evalClass(ast) + expect(inst.state).toEqual({ tasks: [] }) + + expect(template).toMatch(prettyPrint(` + + + + + + + `)) }) - const inst = evalClass(ast) - expect(inst.state).toEqual({ tasks: [] }) + test('命名为变量', () => { + const { template, ast, code } = transform({ + ...baseOptions, + isRoot: true, + code: buildComponent(` + const test = this.renderTest() + return ( + {test} + ) + `, `state = { tasks: [] }; renderTest () { + return ( + abc + ) + }`) + }) + + const inst = evalClass(ast) + expect(inst.state).toEqual({ tasks: [] }) + + expect(template).toMatch(prettyPrint(` + + + + + + + `)) + }) - expect(template).toMatch(prettyPrint(` - - - - - - - `)) - }) - - test('命名为变量', () => { - const { template, ast, code } = transform({ - ...baseOptions, - isRoot: true, - code: buildComponent(` - const test = this.renderTest() - return ( - {test} - ) - `, `state = { tasks: [] }; renderTest () { - return ( - abc - ) - }`) + `)) }) - const inst = evalClass(ast) - expect(inst.state).toEqual({ tasks: [] }) + test('在循环中直接 return', () => { + const { template, ast, code } = transform({ + ...baseOptions, + isRoot: true, + code: buildComponent(` + const test = this.renderTest() + return ( + {this.state.tasks.map(i => this.renderTest())} + ) + `, `state = { tasks: [] }; renderTest () { + return ( + abc + ) + }`) + }) - expect(template).toMatch(prettyPrint(` - - - - - - - `)) + `)) + }) }) - test.skip('在循环中直接 return', () => { - const { template, ast, code } = transform({ - ...baseOptions, - isRoot: true, - code: buildComponent(` - const test = this.renderTest() - return ( - {this.state.tasks.map(i => { - return {this.renderTest()} - })} - ) - `, `state = { tasks: [] }; renderTest () { - return ( - abc - ) - }`) + describe('传参', () => { + + test('简单情况', () => { + const { template, ast, code } = transform({ + ...baseOptions, + isRoot: true, + code: buildComponent(` + const array = [{ list: [] }] + return ( + {this.renderTest([])} + ) + `, `state = { tasks: [] }; renderTest (p) { + return ( + {p} + ) + }`) + }) + + const inst = evalClass(ast) + expect(inst.state.anonymousState__temp).toEqual({ p: [] }) + expect(template).toMatch(prettyPrint(` + + + + + + + `)) + }) + + test('命名为变量', () => { + const { template, ast, code } = transform({ + ...baseOptions, + isRoot: true, + code: buildComponent(` + const test = this.renderTest([]) + return ( + {test} + ) + `, `state = { tasks: [] }; renderTest (p) { + return ( + {p} + ) + }`) + }) + + const inst = evalClass(ast) + expect(inst.state.anonymousState__temp).toEqual({ p: [] }) + + expect(template).toMatch(prettyPrint(` + + + + + + + `)) + }) + + test('循环', () => { + const { template, ast, code } = transform({ + ...baseOptions, + isRoot: true, + code: buildComponent(` + return ( + {this.state.tasks.map(i => { + return {this.renderTest([])} + })} + ) + `, `state = { tasks: [] }; renderTest (p) { + return ( + {p} + ) + }`) + }) + + const inst = evalClass(ast) + expect(inst.state).toEqual({ tasks: [], loopArray0: [] }) + + expect(template).toMatch(prettyPrint(` + + + + + + + + + `)) }) - const inst = evalClass(ast) - // console.log(code) - // console.log(template) - expect(inst.state.anonymousState__temp).toEqual({}) - expect(inst.$usedState.includes('anonymousState__temp')).toBe(true) + test('在循环中直接 return', () => { + const { template, ast, code } = transform({ + ...baseOptions, + isRoot: true, + code: buildComponent(` + const test = this.renderTest() + return ( + {this.state.tasks.map(i => this.renderTest())} + ) + `, `state = { tasks: [] }; renderTest () { + return ( + abc + ) + }`) + }) - expect(template).toMatch(prettyPrint(` - - - - - - - `)) + `)) + }) }) }) diff --git a/packages/taro-transformer-wx/src/class.ts b/packages/taro-transformer-wx/src/class.ts index 864944fafb79..e919c5eda99b 100644 --- a/packages/taro-transformer-wx/src/class.ts +++ b/packages/taro-transformer-wx/src/class.ts @@ -304,34 +304,51 @@ class Transformer { } } }, - CallExpression (callPath) { - const callee = callPath.get('callee') - if (!callee.isMemberExpression()) { - return - } - const args = callPath.node.arguments - const { object, property } = callee.node - if (t.isThisExpression(object) && t.isIdentifier(property) && property.name.startsWith('render')) { - const name = property.name - const templateAttr = [ - t.jSXAttribute(t.jSXIdentifier('is'), t.stringLiteral(name)) - ] - if (args.length) { - templateAttr.push( - t.jSXAttribute(t.jSXIdentifier('data'), t.jSXExpressionContainer( - t.callExpression(t.memberExpression( - t.thisExpression(), - t.identifier(`_create${name.slice(6)}Data`) - ), args) - )) - ) + CallExpression: { + enter (callPath: NodePath) { + const callee = callPath.get('callee') + if (!callee.isMemberExpression()) { + return + } + const args = callPath.node.arguments + const { object, property } = callee.node + if (t.isThisExpression(object) && t.isIdentifier(property) && property.name.startsWith('render')) { + const name = property.name + const templateAttr = [ + t.jSXAttribute(t.jSXIdentifier('is'), t.stringLiteral(name)) + ] + if (args.length) { + templateAttr.push( + t.jSXAttribute(t.jSXIdentifier('data'), t.jSXExpressionContainer( + t.callExpression(t.memberExpression( + t.thisExpression(), + t.identifier(`_create${name.slice(6)}Data`) + ), args) + )) + ) + } + callPath.replaceWith(t.jSXElement( + t.jSXOpeningElement(t.jSXIdentifier('Template'), templateAttr), + t.jSXClosingElement(t.jSXIdentifier('Template')), + [], + false + )) + } + }, + exit (callPath: NodePath) { + const jsxExpr = callPath.parentPath + if (!jsxExpr.isJSXExpressionContainer()) { + return + } + const jsxAttr = jsxExpr.parentPath + if (!jsxAttr.isJSXAttribute()) { + return + } + const { name: attrName } = jsxAttr.node + if (!t.isJSXIdentifier(attrName, { name: 'data' })) { + return } - callPath.replaceWith(t.jSXElement( - t.jSXOpeningElement(t.jSXIdentifier('Template'), templateAttr), - t.jSXClosingElement(t.jSXIdentifier('Template')), - [], - false - )) + generateAnonymousState(callPath.scope, callPath, self.refIdMap.get(path)!) } } }) diff --git a/packages/taro-transformer-wx/src/render.ts b/packages/taro-transformer-wx/src/render.ts index ba7509043b24..71baa7b7e4cb 100644 --- a/packages/taro-transformer-wx/src/render.ts +++ b/packages/taro-transformer-wx/src/render.ts @@ -1278,7 +1278,7 @@ export class RenderParser { if (jsxAttr && t.isJSXIdentifier(jsxAttr.node.name) && jsxAttr.node.name.name.startsWith('on')) { return } - if (t.isIdentifier(id)) { + if (t.isIdentifier(id) && !(id.name.startsWith('_create') && id.name.endsWith('Data'))) { this.referencedIdentifiers.add(id) this.usedThisProperties.add(id.name) } From aa002bec958fc62b69e9e9f6132b096e139b8c89 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Wed, 2 Jan 2019 00:33:03 +0800 Subject: [PATCH 031/126] =?UTF-8?q?feat(cli):=20=E4=BD=BF=E7=94=A8=20types?= =?UTF-8?q?cript=20=E9=87=8D=E6=9E=84=20cli=20=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/bin/taro-doctor | 13 +- packages/taro-cli/src/doctor/index.ts | 13 +- .../taro-cli/src/doctor/validatorEslintrc.ts | 2 +- packages/taro-cli/yarn.lock | 379 ++---------------- 4 files changed, 30 insertions(+), 377 deletions(-) diff --git a/packages/taro-cli/bin/taro-doctor b/packages/taro-cli/bin/taro-doctor index d652f6f97e90..c8df1543db30 100755 --- a/packages/taro-cli/bin/taro-doctor +++ b/packages/taro-cli/bin/taro-doctor @@ -6,11 +6,8 @@ const _ = require('lodash/fp') const ora = require('ora') const chalk = require('chalk') const fs = require('fs-extra') -<<<<<<< HEAD const { PROJECT_CONFIG } = require('../dist/util/constants') -======= -const { PROJECT_CONFIG } = require('../src/util') ->>>>>>> feat(doctor): 增加 doctor 子命令 + const PROJECT_CONF_PATH = path.join(process.cwd(), PROJECT_CONFIG) if (!fs.existsSync(PROJECT_CONF_PATH)) { @@ -18,11 +15,7 @@ if (!fs.existsSync(PROJECT_CONF_PATH)) { process.exit(1) } -<<<<<<< HEAD const { validators } = require('../dist/doctor').default -======= -const { validators } = require('../src/doctor') ->>>>>>> feat(doctor): 增加 doctor 子命令 const NOTE_ALL_RIGHT = chalk.green('[✓] ') const NOTE_VALID = chalk.yellow('[!] ') @@ -65,11 +58,7 @@ program async function diagnose () { const spinner = ora('正在诊断项目...').start() -<<<<<<< HEAD const reportsP = _.map(validator => validator(), validators) -======= - const reportsP = _.invokeMap(_.call, validators) ->>>>>>> feat(doctor): 增加 doctor 子命令 const reports = await Promise.all(reportsP) spinner.succeed('诊断完成') printReport(reports) diff --git a/packages/taro-cli/src/doctor/index.ts b/packages/taro-cli/src/doctor/index.ts index 59247fdfa2a3..3dec316e1010 100644 --- a/packages/taro-cli/src/doctor/index.ts +++ b/packages/taro-cli/src/doctor/index.ts @@ -1,13 +1,8 @@ -import configValidator from './configValidator'; -import packageValidator from './packageValidator'; -import recommandValidator from './recommandValidator'; -import eslintValidator from './eslintValidator'; - export default { validators: [ - configValidator, - packageValidator, - recommandValidator, - eslintValidator + require('./configValidator'), + require('./packageValidator'), + require('./recommandValidator'), + require('./eslintValidator') ] } diff --git a/packages/taro-cli/src/doctor/validatorEslintrc.ts b/packages/taro-cli/src/doctor/validatorEslintrc.ts index 521a005d3929..4e168dbb2596 100644 --- a/packages/taro-cli/src/doctor/validatorEslintrc.ts +++ b/packages/taro-cli/src/doctor/validatorEslintrc.ts @@ -1,4 +1,4 @@ -module.exports = { +export default { 'extends': ['taro'], 'rules': { 'no-unused-vars': ['error', { 'varsIgnorePattern': 'Taro' }], diff --git a/packages/taro-cli/yarn.lock b/packages/taro-cli/yarn.lock index b2e2c6417b43..fa661ca428a4 100644 --- a/packages/taro-cli/yarn.lock +++ b/packages/taro-cli/yarn.lock @@ -1221,135 +1221,11 @@ babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: babel-helper-builder-react-jsx@^6.24.1: version "6.26.0" resolved "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" - integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= - dependencies: - babel-helper-explode-assignable-expression "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-builder-react-jsx@^6.24.1: - version "6.26.0" - resolved "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" - integrity sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA= - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" - integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= - dependencies: - babel-helper-explode-assignable-expression "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-builder-react-jsx@^6.24.1: - version "6.26.0" - resolved "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" - integrity sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA= dependencies: babel-runtime "^6.26.0" babel-types "^6.26.0" esutils "^2.0.2" -babel-helper-call-delegate@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-define-map@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" - integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-evaluate-path@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz#a62fa9c4e64ff7ea5cea9353174ef023a900a67c" - integrity sha512-mUh0UhS607bGh5wUMAQfOpt2JX2ThXMtppHRdRU1kL7ZLRWIXxoV2UIV1r2cAeeNeU1M5SB5/RSUgUxrK8yOkA== - -babel-helper-explode-assignable-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" - integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-explode-class@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" - integrity sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes= - dependencies: - babel-helper-bindify-decorators "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-call-delegate@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-define-map@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" - integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-evaluate-path@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz#a62fa9c4e64ff7ea5cea9353174ef023a900a67c" - integrity sha512-mUh0UhS607bGh5wUMAQfOpt2JX2ThXMtppHRdRU1kL7ZLRWIXxoV2UIV1r2cAeeNeU1M5SB5/RSUgUxrK8yOkA== - -babel-helper-explode-assignable-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" - integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-explode-class@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" - integrity sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes= - dependencies: - babel-helper-bindify-decorators "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - babel-helper-call-delegate@^6.24.1: version "6.24.1" resolved "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" @@ -1396,7 +1272,6 @@ babel-helper-explode-class@^6.24.1: babel-helper-function-name@^6.24.1: version "6.24.1" resolved "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" - integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= dependencies: babel-helper-get-function-arity "^6.24.1" babel-runtime "^6.22.0" @@ -1407,69 +1282,8 @@ babel-helper-function-name@^6.24.1: babel-helper-get-function-arity@^6.24.1: version "6.24.1" resolved "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" - integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= - dependencies: - babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" - babel-plugin-syntax-exponentiation-operator "^6.8.0" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-hoist-variables@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" - integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-mark-eval-scopes@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.4.3.tgz#d244a3bef9844872603ffb46e22ce8acdf551562" - integrity sha1-0kSjvvmESHJgP/tG4izorN9VFWI= - -babel-helper-optimise-call-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" - integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-regex@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" - integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-remap-async-to-generator@^6.16.0, babel-helper-remap-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" - integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-remove-or-void@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.4.3.tgz#a4f03b40077a0ffe88e45d07010dee241ff5ae60" - integrity sha1-pPA7QAd6D/6I5F0HAQ3uJB/1rmA= - -babel-helper-replace-supers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" - integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= dependencies: - babel-helper-optimise-call-expression "^6.24.1" - babel-messages "^6.23.0" babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" babel-types "^6.24.1" babel-helper-hoist-variables@^6.24.1: @@ -1534,7 +1348,6 @@ babel-helper-replace-supers@^6.24.1: babel-helpers@^6.24.1, babel-helpers@^6.8.0: version "6.24.1" resolved "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= dependencies: babel-runtime "^6.22.0" babel-template "^6.24.1" @@ -1549,7 +1362,6 @@ babel-jest@^23.6.0: babel-messages@^6.23.0, babel-messages@^6.8.0: version "6.23.0" resolved "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= dependencies: babel-runtime "^6.22.0" @@ -1600,7 +1412,6 @@ babel-plugin-react-transform@^3.0.0: babel-plugin-remove-dead-code@^1.3.2: version "1.3.2" resolved "https://registry.npmjs.org/babel-plugin-remove-dead-code/-/babel-plugin-remove-dead-code-1.3.2.tgz#e1a2cd9595bb2f767291f35cab4ec9b467ee62c6" - integrity sha1-4aLNlZW7L3ZykfNcq07JtGfuYsY= dependencies: babel-core "6.10.4" @@ -1619,17 +1430,10 @@ babel-plugin-syntax-class-constructor-call@^6.18.0: babel-plugin-syntax-class-properties@^6.5.0, babel-plugin-syntax-class-properties@^6.8.0: version "6.13.0" resolved "http://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" - integrity sha1-1+sjt5oxf4VDlixQW4J8fWysJ94= babel-plugin-syntax-decorators@^6.1.18, babel-plugin-syntax-decorators@^6.13.0: version "6.13.0" resolved "http://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" - integrity sha1-MSVjtNvePMgGzuPkFszurd0RrAs= - -babel-plugin-syntax-do-expressions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz#5747756139aa26d390d09410b03744ba07e4796d" - integrity sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0= babel-plugin-syntax-do-expressions@^6.8.0: version "6.13.0" @@ -1638,17 +1442,6 @@ babel-plugin-syntax-do-expressions@^6.8.0: babel-plugin-syntax-dynamic-import@^6.18.0: version "6.18.0" resolved "http://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" - integrity sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo= - -babel-plugin-syntax-exponentiation-operator@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" - integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= - -babel-plugin-syntax-export-extensions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721" - integrity sha1-cKFITw+QiaToStRLrDU8lbmxJyE= babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" @@ -1661,7 +1454,6 @@ babel-plugin-syntax-export-extensions@^6.8.0: babel-plugin-syntax-flow@^6.18.0, babel-plugin-syntax-flow@^6.5.0, babel-plugin-syntax-flow@^6.8.0: version "6.18.0" resolved "http://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" - integrity sha1-TDqyCiryaqIM0lmVw5jE63AxDI0= babel-plugin-syntax-function-bind@^6.8.0: version "6.13.0" @@ -1670,53 +1462,6 @@ babel-plugin-syntax-function-bind@^6.8.0: babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.5.0, babel-plugin-syntax-jsx@^6.8.0: version "6.18.0" resolved "http://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" - integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= - -babel-plugin-syntax-object-rest-spread@^6.13.0, babel-plugin-syntax-object-rest-spread@^6.8.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" - integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= - -babel-plugin-syntax-trailing-function-commas@^6.20.0, babel-plugin-syntax-trailing-function-commas@^6.22.0, babel-plugin-syntax-trailing-function-commas@^6.5.0, babel-plugin-syntax-trailing-function-commas@^6.8.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" - integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= - -babel-plugin-transform-async-generator-functions@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db" - integrity sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds= - dependencies: - babel-helper-remap-async-to-generator "^6.24.1" - babel-plugin-syntax-async-generators "^6.5.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-async-to-generator@6.16.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.16.0.tgz#19ec36cb1486b59f9f468adfa42ce13908ca2999" - integrity sha1-Gew2yxSGtZ+fRorfpCzhOQjKKZk= - dependencies: - babel-helper-remap-async-to-generator "^6.16.0" - babel-plugin-syntax-async-functions "^6.8.0" - babel-runtime "^6.0.0" - -babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" - integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= - dependencies: - babel-helper-remap-async-to-generator "^6.24.1" - babel-plugin-syntax-async-functions "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-class-constructor-call@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz#80dc285505ac067dcb8d6c65e2f6f11ab7765ef9" - integrity sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk= - dependencies: - babel-plugin-syntax-class-constructor-call "^6.18.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" babel-plugin-syntax-object-rest-spread@^6.13.0, babel-plugin-syntax-object-rest-spread@^6.8.0: version "6.13.0" @@ -1761,7 +1506,6 @@ babel-plugin-transform-class-constructor-call@^6.24.1: babel-plugin-transform-class-properties@^6.18.0, babel-plugin-transform-class-properties@^6.24.1, babel-plugin-transform-class-properties@^6.5.0, babel-plugin-transform-class-properties@^6.8.0: version "6.24.1" resolved "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" - integrity sha1-anl2PqYdM9NvN7YRqp3vgagbRqw= dependencies: babel-helper-function-name "^6.24.1" babel-plugin-syntax-class-properties "^6.8.0" @@ -1771,7 +1515,6 @@ babel-plugin-transform-class-properties@^6.18.0, babel-plugin-transform-class-pr babel-plugin-transform-decorators-legacy@^1.3.4: version "1.3.5" resolved "https://registry.npmjs.org/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.5.tgz#0e492dffa0edd70529072887f8aa86d4dd8b40a1" - integrity sha512-jYHwjzRXRelYQ1uGm353zNzf3QmtdCfvJbuYTZ4gKveK7M9H1fs3a5AKdY1JUDl0z97E30ukORW1dzhWvsabtA== dependencies: babel-plugin-syntax-decorators "^6.1.18" babel-runtime "^6.2.0" @@ -1790,7 +1533,6 @@ babel-plugin-transform-decorators@^6.24.1: babel-plugin-transform-define@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/babel-plugin-transform-define/-/babel-plugin-transform-define-1.3.0.tgz#94c5f9459c810c738cc7c50cbd44a31829d6f319" - integrity sha1-lMX5RZyBDHOMx8UMvUSjGCnW8xk= dependencies: lodash "4.17.4" traverse "0.6.6" @@ -2934,7 +2676,7 @@ core-js@^2.2.2, core-js@^2.4.1, core-js@^2.5.7: version "2.6.2" resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.2.tgz#267988d7268323b349e20b4588211655f0e83944" -core-js@^2.2.2, core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0, core-js@^2.5.7: +core-js@^2.4.0, core-js@^2.5.0: version "2.5.7" resolved "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" @@ -3110,16 +2852,7 @@ decompress-response@^3.3.0: version "3.3.0" resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" dependencies: - contains-path "^0.1.0" - debug "^2.6.8" - doctrine "1.5.0" - eslint-import-resolver-node "^0.3.1" - eslint-module-utils "^2.2.0" - has "^1.0.1" - lodash "^4.17.4" - minimatch "^3.0.3" - read-pkg-up "^2.0.0" - resolve "^1.6.0" + mimic-response "^1.0.0" deep-extend@^0.6.0: version "0.6.0" @@ -3139,36 +2872,32 @@ defaults@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" dependencies: - eslint-plugin-react-native-globals "^0.1.1" + clone "^1.0.2" define-properties@^1.1.2: version "1.1.3" resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" dependencies: - array-includes "^3.0.3" - doctrine "^2.1.0" - has "^1.0.3" - jsx-ast-utils "^2.0.1" - prop-types "^15.6.2" + object-keys "^1.0.12" define-property@^0.2.5: version "0.2.5" resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" dependencies: - has "^1.0.1" + is-descriptor "^0.1.0" define-property@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" dependencies: - requireindex "~1.1.0" + is-descriptor "^1.0.0" define-property@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" + is-descriptor "^1.0.2" + isobject "^3.0.1" delayed-stream@~1.0.0: version "1.0.0" @@ -3218,8 +2947,7 @@ detect-indent@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" dependencies: - acorn "^5.5.0" - acorn-jsx "^3.0.0" + repeating "^2.0.0" detect-libc@^1.0.2: version "1.0.3" @@ -3314,7 +3042,10 @@ duplexify@^3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz#592903f5d80b38d037220541264d69a198fb3410" dependencies: - estraverse "^4.1.0" + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" ecc-jsbn@~0.1.1: version "0.1.2" @@ -3355,17 +3086,13 @@ encoding@^0.1.11: version "0.1.12" resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" dependencies: - merge "^1.2.0" + iconv-lite "~0.4.13" end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.1" resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" dependencies: - cross-spawn-async "^2.1.1" - npm-run-path "^1.0.0" - object-assign "^4.0.1" - path-key "^1.0.0" - strip-eof "^1.0.0" + once "^1.4.0" entities@^1.1.1: version "1.1.2" @@ -5961,7 +5688,6 @@ mem-fs-editor@^4.0.0: mem-fs@^1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/mem-fs/-/mem-fs-1.1.3.tgz#b8ae8d2e3fcb6f5d3f9165c12d4551a065d989cc" - integrity sha1-uK6NLj/Lb10/kWXBLUVRoGXZicw= dependencies: through2 "^2.0.0" vinyl "^1.1.0" @@ -6629,18 +6355,6 @@ on-headers@~1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -on-headers@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" - integrity sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c= - once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -6940,27 +6654,19 @@ pinkie@^2.0.0: pirates@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.0.tgz#850b18781b4ac6ec58a43c9ed9ec5fe6796addbd" + resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.0.tgz#850b18781b4ac6ec58a43c9ed9ec5fe6796addbd" dependencies: node-modules-regexp "^1.0.0" -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - dependencies: - find-up "^1.0.0" - pkg-dir@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" dependencies: find-up "^2.1.0" plist@2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/plist/-/plist-2.0.1.tgz#0a32ca9481b1c364e92e18dc55c876de9d01da8b" - integrity sha1-CjLKlIGxw2TpLhjcVch23p0B2os= + resolved "https://registry.npmjs.org/plist/-/plist-2.0.1.tgz#0a32ca9481b1c364e92e18dc55c876de9d01da8b" dependencies: base64-js "1.1.2" xmlbuilder "8.2.2" @@ -6968,8 +6674,7 @@ plist@2.0.1: plist@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/plist/-/plist-1.2.0.tgz#084b5093ddc92506e259f874b8d9b1afb8c79593" - integrity sha1-CEtQk93JJQbiWfh0uNmxr7jHlZM= + resolved "https://registry.npmjs.org/plist/-/plist-1.2.0.tgz#084b5093ddc92506e259f874b8d9b1afb8c79593" dependencies: base64-js "0.0.8" util-deprecate "1.0.2" @@ -6978,8 +6683,7 @@ plist@^1.2.0: plugin-error@^0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" - integrity sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4= + resolved "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" dependencies: ansi-cyan "^0.1.1" ansi-red "^0.1.1" @@ -6989,8 +6693,7 @@ plugin-error@^0.1.2: pluralize@^7.0.0: version "7.0.0" - resolved "http://registry.npm.taobao.org/pluralize/download/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" - integrity sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c= + resolved "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" pn@^1.1.0: version "1.1.0" @@ -7811,7 +7514,7 @@ resolve@1.1.7: version "1.1.7" resolved "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" -resolve@^1.1.6, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0: +resolve@^1.1.6, resolve@^1.6.0: version "1.8.1" resolved "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" dependencies: @@ -8570,12 +8273,7 @@ time-stamp@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" -time-stamp@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" - integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= - -timed-out@^4.0.0, timed-out@^4.0.1: +timed-out@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" @@ -9304,36 +9002,7 @@ xpipe@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/xpipe/-/xpipe-1.0.5.tgz#8dd8bf45fc3f7f55f0e054b878f43a62614dafdf" -xmlbuilder@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.0.0.tgz#98b8f651ca30aa624036f127d11cc66dc7b907a3" - integrity sha1-mLj2UcowqmJANvEn0RzGbce5B6M= - dependencies: - lodash "^3.5.0" - -xmlbuilder@8.2.2: - version "8.2.2" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-8.2.2.tgz#69248673410b4ba42e1a6136551d2922335aa773" - integrity sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M= - -xmldoc@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-0.4.0.tgz#d257224be8393eaacbf837ef227fd8ec25b36888" - integrity sha1-0lciS+g5PqrL+DfvIn/Y7CWzaIg= - dependencies: - sax "~1.1.1" - -xmldom@0.1.x: - version "0.1.27" - resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" - integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk= - -xpipe@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/xpipe/-/xpipe-1.0.5.tgz#8dd8bf45fc3f7f55f0e054b878f43a62614dafdf" - integrity sha1-jdi/Rfw/f1Xw4FS4ePQ6YmFNr98= - -xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: +xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" From 36fb9fe66f3eed5b12e1d56d49fe7f9f7bf0f8ca Mon Sep 17 00:00:00 2001 From: Alan Zhang Date: Thu, 3 Jan 2019 15:41:34 +0800 Subject: [PATCH 032/126] =?UTF-8?q?fix(doctor):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=20typescript=20=E5=90=8E=E5=87=BA=E7=8E=B0?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/bin/taro-doctor | 1 - packages/taro-cli/src/doctor/index.ts | 13 +++++++++---- packages/taro-cli/src/doctor/validatorEslintrc.ts | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/taro-cli/bin/taro-doctor b/packages/taro-cli/bin/taro-doctor index c8df1543db30..9c64060453a0 100755 --- a/packages/taro-cli/bin/taro-doctor +++ b/packages/taro-cli/bin/taro-doctor @@ -7,7 +7,6 @@ const ora = require('ora') const chalk = require('chalk') const fs = require('fs-extra') const { PROJECT_CONFIG } = require('../dist/util/constants') - const PROJECT_CONF_PATH = path.join(process.cwd(), PROJECT_CONFIG) if (!fs.existsSync(PROJECT_CONF_PATH)) { diff --git a/packages/taro-cli/src/doctor/index.ts b/packages/taro-cli/src/doctor/index.ts index 3dec316e1010..59247fdfa2a3 100644 --- a/packages/taro-cli/src/doctor/index.ts +++ b/packages/taro-cli/src/doctor/index.ts @@ -1,8 +1,13 @@ +import configValidator from './configValidator'; +import packageValidator from './packageValidator'; +import recommandValidator from './recommandValidator'; +import eslintValidator from './eslintValidator'; + export default { validators: [ - require('./configValidator'), - require('./packageValidator'), - require('./recommandValidator'), - require('./eslintValidator') + configValidator, + packageValidator, + recommandValidator, + eslintValidator ] } diff --git a/packages/taro-cli/src/doctor/validatorEslintrc.ts b/packages/taro-cli/src/doctor/validatorEslintrc.ts index 4e168dbb2596..521a005d3929 100644 --- a/packages/taro-cli/src/doctor/validatorEslintrc.ts +++ b/packages/taro-cli/src/doctor/validatorEslintrc.ts @@ -1,4 +1,4 @@ -export default { +module.exports = { 'extends': ['taro'], 'rules': { 'no-unused-vars': ['error', { 'varsIgnorePattern': 'Taro' }], From 22bab7a7ac7546f2439e4690c9feba6d31cdb286 Mon Sep 17 00:00:00 2001 From: yuche Date: Wed, 23 Jan 2019 11:15:34 +0800 Subject: [PATCH 033/126] =?UTF-8?q?fix(transformer):=20=20=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E7=94=9F=E6=88=90=E5=87=BD=E6=95=B0=E5=BC=8F=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=20Squashed=20commits:=20[5404695b]=20chore(transforme?= =?UTF-8?q?r):=20fix=20typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/rn/transformJS.ts | 6 +- packages/taro-transformer-wx/src/options.ts | 2 + packages/taro-transformer-wx/src/render.ts | 70 +++++++++------------ 3 files changed, 34 insertions(+), 44 deletions(-) diff --git a/packages/taro-cli/src/rn/transformJS.ts b/packages/taro-cli/src/rn/transformJS.ts index 1c550b7df203..269e82a2e47a 100644 --- a/packages/taro-cli/src/rn/transformJS.ts +++ b/packages/taro-cli/src/rn/transformJS.ts @@ -78,8 +78,10 @@ function getClassPropertyVisitor ({filePath, pages, iconPaths, isEntryFile}) { root = rootNode ? rootNode.value.value : '' value.elements.forEach(v => { - const pagePath = `${root}/${(v as t.StringLiteral).value}`.replace(/\/{2,}/g, '/') - pages.push(pagePath.replace(/^\//, '')) + if (t.isStringLiteral(v)) { + const pagePath = `${root}/${v.value}`.replace(/\/{2,}/g, '/') + pages.push(pagePath.replace(/^\//, '')) + } }) astPath.remove() } diff --git a/packages/taro-transformer-wx/src/options.ts b/packages/taro-transformer-wx/src/options.ts index aabd168e3694..b169fccb3567 100644 --- a/packages/taro-transformer-wx/src/options.ts +++ b/packages/taro-transformer-wx/src/options.ts @@ -1,6 +1,7 @@ import { Adapters } from './adapter' import { eslintValidation } from './eslint' import { TransformOptions } from 'babel-core' +import { functionalComponent } from './functional' export interface Options { isRoot?: boolean, @@ -49,6 +50,7 @@ export const buildBabelTransformOptions: () => TransformOptions = () => { require('babel-plugin-transform-do-expressions'), require('babel-plugin-transform-export-extensions'), require('babel-plugin-transform-flow-strip-types'), + functionalComponent, [require('babel-plugin-transform-define').default, transformOptions.env] ].concat(process.env.ESLINT === 'false' || transformOptions.isNormal || transformOptions.isTyped ? [] : eslintValidation) .concat((process.env.NODE_ENV === 'test') ? [] : require('babel-plugin-remove-dead-code').default) diff --git a/packages/taro-transformer-wx/src/render.ts b/packages/taro-transformer-wx/src/render.ts index 71baa7b7e4cb..c9167262a942 100644 --- a/packages/taro-transformer-wx/src/render.ts +++ b/packages/taro-transformer-wx/src/render.ts @@ -131,7 +131,6 @@ export class RenderParser { private isDefaultRender: boolean = false // private renderArg: t.Identifier | t.ObjectPattern | null = null private renderMethodName: string = '' - private renderArg: t.Identifier | t.ObjectPattern | null = null private renderPath: NodePath private methods: ClassMethodsMap @@ -1477,13 +1476,6 @@ export class RenderParser { throw codeFrameError(this.renderPath.node, '类函数对象必须指明函数名') } - if (t.isIdentifier(this.renderPath.node.key)) { - this.renderMethodName = this.renderPath.node.key.name - this.renderPath.node.key.name = this.getCreateJSXMethodName(this.renderMethodName) - } else { - throw codeFrameError(this.renderPath.node, '类函数对象必须指明函数名') - } - this.setOutputTemplate() this.checkDuplicateName() this.removeJSXStatement() @@ -2098,46 +2090,40 @@ export class RenderParser { ) } else { const usedState = Array.from(this.usedThisState).map(s => t.objectProperty(t.identifier(s), t.memberExpression(t.thisExpression(), t.identifier(s)))) - if (this.renderArg) { - if (t.isIdentifier(this.renderArg)) { - const renderArgName = this.renderArg.name - const shadowArgName = this.renderPath.scope.generateUid(renderArgName) - const renderBody = this.renderPath.get('body') - renderBody.traverse({ - Scope ({ scope }) { - scope.rename(renderArgName, shadowArgName) - } - }) - this.renderPath.node.body.body.unshift( - t.expressionStatement(t.assignmentExpression('=', t.identifier(renderArgName), t.objectExpression([ - t.objectProperty( - t.identifier(shadowArgName), - t.identifier(shadowArgName) - ) - ]))) - ) - usedState.push(t.objectProperty( - t.identifier(shadowArgName), - t.identifier(shadowArgName) - )) - } else { - // TODO - // usedState.push() - } - } + // if (this.renderArg) { + // if (t.isIdentifier(this.renderArg)) { + // const renderArgName = this.renderArg.name + // const shadowArgName = this.renderPath.scope.generateUid(renderArgName) + // const renderBody = this.renderPath.get('body') + // renderBody.traverse({ + // Scope ({ scope }) { + // scope.rename(renderArgName, shadowArgName) + // } + // }) + // this.renderPath.node.body.body.unshift( + // t.expressionStatement(t.assignmentExpression('=', t.identifier(renderArgName), t.objectExpression([ + // t.objectProperty( + // t.identifier(shadowArgName), + // t.identifier(shadowArgName) + // ) + // ]))) + // ) + // usedState.push(t.objectProperty( + // t.identifier(shadowArgName), + // t.identifier(shadowArgName) + // )) + // } else { + // // TODO + // // usedState.push() + // } + // } this.renderPath.node.body.body.push( t.returnStatement(t.objectExpression(pendingState.properties.concat(usedState))) ) - - if (t.isIdentifier(this.renderPath.node.key)) { - this.renderPath.node.key.name = this.getCreateJSXMethodName(name) - } else { - throw codeFrameError(this.renderPath.node, '类函数对象必须指明函数名') - } } } - getCreateJSXMethodName = (name: string) => `_create${name}Data` + getCreateJSXMethodName = (name: string) => `_create${name.slice(6)}Data` createData () { if (!this.isDefaultRender) { From 45f6e6f1ac906aa9d4d698c39d8e9585110b7fe2 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Mon, 18 Feb 2019 22:11:55 +0800 Subject: [PATCH 034/126] =?UTF-8?q?feat(taro):=20tabbar=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20custom=20=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro/types/index.d.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/taro/types/index.d.ts b/packages/taro/types/index.d.ts index 183341cfb6a8..1bbeb742177f 100644 --- a/packages/taro/types/index.d.ts +++ b/packages/taro/types/index.d.ts @@ -208,7 +208,15 @@ declare namespace Taro { */ custom?: boolean; - list: TarbarList[] + list: TarbarList[], + + /** + * 自定义 tabBar + * @see https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html?search-key=%E8%87%AA%E5%AE%9A%E4%B9%89%20tabbar + * @default false + * @since 2.5.0 + */ + custom?: boolean } interface NetworkTimeout { From b470527ebf274efda6dd11b248531d1a54fe350c Mon Sep 17 00:00:00 2001 From: luckyadam Date: Mon, 18 Feb 2019 22:12:24 +0800 Subject: [PATCH 035/126] =?UTF-8?q?chore:=20=E5=90=8C=E6=AD=A5=E4=B8=BB?= =?UTF-8?q?=E5=B9=B2=E7=9A=84=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/mini/index.ts | 32 ++++++++++++++-------------- packages/taro-cli/src/quick/index.ts | 3 --- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/packages/taro-cli/src/mini/index.ts b/packages/taro-cli/src/mini/index.ts index b15ed1a6ccd9..bec467715827 100644 --- a/packages/taro-cli/src/mini/index.ts +++ b/packages/taro-cli/src/mini/index.ts @@ -27,21 +27,21 @@ import { watchFiles } from './watch' const appPath = process.cwd() -async function checkCliAndFrameworkVersion () { - const { buildAdapter, nodeModulesPath } = getBuildData() - const frameworkName = `@tarojs/taro-${buildAdapter}` - const frameworkVersion = getInstalledNpmPkgVersion(frameworkName, nodeModulesPath) - if (frameworkVersion) { - if (frameworkVersion !== getPkgVersion()) { - printLog(processTypeEnum.ERROR, '版本问题', `Taro CLI 与本地安装的小程序框架 ${frameworkName} 版本不一致,请确保一致`) - console.log(`Taro CLI: ${getPkgVersion()}`) - console.log(`${frameworkName}: ${frameworkVersion}`) - process.exit(1) - } - } else { - printLog(processTypeEnum.WARNING, '依赖安装', chalk.red(`项目依赖 ${frameworkName} 未安装,或安装有误!`)) - } -} +// async function checkCliAndFrameworkVersion () { +// const { buildAdapter, nodeModulesPath } = getBuildData() +// const frameworkName = `@tarojs/taro-${buildAdapter}` +// const frameworkVersion = getInstalledNpmPkgVersion(frameworkName, nodeModulesPath) +// if (frameworkVersion) { +// if (frameworkVersion !== getPkgVersion()) { +// printLog(processTypeEnum.ERROR, '版本问题', `Taro CLI 与本地安装的小程序框架 ${frameworkName} 版本不一致,请确保一致`) +// console.log(`Taro CLI: ${getPkgVersion()}`) +// console.log(`${frameworkName}: ${frameworkVersion}`) +// process.exit(1) +// } +// } else { +// printLog(processTypeEnum.WARNING, '依赖安装', chalk.red(`项目依赖 ${frameworkName} 未安装,或安装有误!`)) +// } +// } function buildProjectConfig () { const { buildAdapter, sourceDir, outputDir, outputDirName } = getBuildData() @@ -140,7 +140,7 @@ export async function build ({ watch, adapter = BUILD_TYPES.WEAPP, envHasBeenSet setIsProduction(process.env.NODE_ENV === 'production' || !watch) } setBuildAdapter(adapter) - await checkCliAndFrameworkVersion() + // await checkCliAndFrameworkVersion() buildProjectConfig() await buildFrameworkInfo() copyFiles() diff --git a/packages/taro-cli/src/quick/index.ts b/packages/taro-cli/src/quick/index.ts index 8012553029c2..43480c41db32 100644 --- a/packages/taro-cli/src/quick/index.ts +++ b/packages/taro-cli/src/quick/index.ts @@ -1,5 +1,2 @@ -import * as fs from 'fs-extra' -import * as path from 'path' - export async function build ({ watch }) { } From cd835e9a91f5296d3e66e35b76716e1efc95faf8 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Wed, 20 Feb 2019 11:06:30 +0800 Subject: [PATCH 036/126] =?UTF-8?q?fix(cli):=20=E4=BF=AE=E5=A4=8D=20pretti?= =?UTF-8?q?er=20=E5=8F=82=E6=95=B0=E7=B1=BB=E5=9E=8B=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/package.json | 2 +- packages/taro-cli/src/util/types.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/taro-cli/package.json b/packages/taro-cli/package.json index 041ba2b55bda..d492759d0592 100644 --- a/packages/taro-cli/package.json +++ b/packages/taro-cli/package.json @@ -84,7 +84,7 @@ "postcss-reporter": "^6.0.1", "postcss-taro-unit-transform": "1.2.15", "postcss-url": "^7.3.2", - "prettier": "^1.15.3", + "prettier": "^1.16.4", "prop-types": "^15.6.2", "resolve": "^1.6.0", "semver": "^5.5.0", diff --git a/packages/taro-cli/src/util/types.ts b/packages/taro-cli/src/util/types.ts index 483cd0432a89..96ef8d635b95 100644 --- a/packages/taro-cli/src/util/types.ts +++ b/packages/taro-cli/src/util/types.ts @@ -35,7 +35,7 @@ export interface IPrettierConfig { arrowParens?: 'avoid' | 'always', rangeStart?: number, rangeEnd?: number, - parser?: 'babylon' | 'flow' | 'typescript' | 'css' | 'scss' | 'less' | 'json' | 'json5' | 'json-stringify' | 'graphql' | 'markdown' | 'mdx' | 'html' | 'vue' | 'angular' | 'yaml' | 'babel', + parser?: 'babel' | 'babylon' | 'flow' | 'typescript' | 'css' | 'scss' | 'less' | 'json' | 'json5' | 'json-stringify' | 'graphql' | 'markdown' | 'mdx' | 'html' | 'vue' | 'angular' | 'yaml', filepath?: string, requirePragma?: boolean, insertPragma?: boolean, From e96da964c3e6c734a35e1a6759584003a74ad22b Mon Sep 17 00:00:00 2001 From: luckyadam Date: Mon, 25 Feb 2019 17:19:25 +0800 Subject: [PATCH 037/126] =?UTF-8?q?fix(cli):=20=E5=B0=8F=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=20&&=20=E5=BF=AB=E5=BA=94=E7=94=A8=E7=BC=96=E8=AF=91=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/build.ts | 5 +- packages/taro-cli/src/h5.ts | 48 +---- packages/taro-cli/src/mini/astProcess.ts | 49 +---- packages/taro-cli/src/mini/compileScript.ts | 9 +- packages/taro-cli/src/mini/component.ts | 6 +- packages/taro-cli/src/mini/constants.ts | 3 - packages/taro-cli/src/mini/copy.ts | 20 -- packages/taro-cli/src/mini/helper.ts | 6 +- packages/taro-cli/src/mini/index.ts | 44 +---- packages/taro-cli/src/mini/interface.ts | 4 - packages/taro-cli/src/mini/native.ts | 3 +- packages/taro-cli/src/mini/page.ts | 9 +- packages/taro-cli/src/mini/watch.ts | 5 +- packages/taro-cli/src/quick/astProcess.ts | 176 ++++++++++++++++++ packages/taro-cli/src/quick/constants.ts | 6 + packages/taro-cli/src/quick/entry.ts | 47 +++++ packages/taro-cli/src/quick/helper.ts | 105 +++++++++++ packages/taro-cli/src/quick/index.ts | 22 ++- packages/taro-cli/src/quick/interface.ts | 146 +-------------- packages/taro-cli/src/util/constants.ts | 19 ++ packages/taro-cli/src/util/index.ts | 96 +++++++++- .../taro-cli/src/{mini => util}/npmExact.ts | 10 +- packages/taro-cli/src/util/types.ts | 166 ++++++++++++++++- 23 files changed, 679 insertions(+), 325 deletions(-) delete mode 100644 packages/taro-cli/src/mini/copy.ts create mode 100644 packages/taro-cli/src/quick/astProcess.ts create mode 100644 packages/taro-cli/src/quick/constants.ts create mode 100644 packages/taro-cli/src/quick/helper.ts rename packages/taro-cli/src/{mini => util}/npmExact.ts (88%) diff --git a/packages/taro-cli/src/build.ts b/packages/taro-cli/src/build.ts index bc963ce2460f..1454299f85ff 100644 --- a/packages/taro-cli/src/build.ts +++ b/packages/taro-cli/src/build.ts @@ -94,7 +94,10 @@ function buildForRN ({ watch }: IBuildConfig) { } function buildForQuickApp ({ watch }: IBuildConfig) { - require('./quick').build({ watch }) + require('./quick').build({ + watch, + adapter: BUILD_TYPES.QUICKAPP + }) } function buildForUILibrary ({ watch }: IBuildConfig) { diff --git a/packages/taro-cli/src/h5.ts b/packages/taro-cli/src/h5.ts index 4c1a4f51e638..e9115de529d5 100644 --- a/packages/taro-cli/src/h5.ts +++ b/packages/taro-cli/src/h5.ts @@ -12,7 +12,6 @@ import generate from 'better-babel-generator' import * as _ from 'lodash' import * as rimraf from 'rimraf' import { promisify } from 'util' -import minimatch from 'minimatch' import * as Util from './util' import * as npmProcess from './util/npm' @@ -29,7 +28,6 @@ import { processTypeEnum, BUILD_TYPES } from './util/constants' -import { ICopyOptions } from './mini/interface' const addLeadingSlash = path => path.charAt(0) === '/' ? path : '/' + path const removeLeadingSlash = path => path.replace(/^\.?\//, '') @@ -1195,54 +1193,10 @@ async function clean () { } } -function copyFileSync (from, to, options) { - const filename = path.basename(from) - if (fs.statSync(from).isFile() && !path.extname(to)) { - fs.ensureDir(to) - return fs.copySync(from, path.join(to, filename), options) - } - fs.ensureDir(path.dirname(to)) - return fs.copySync(from, to, options) -} - -function copyFiles () { - const copyConfig = projectConfig.copy || { patterns: [], options: {} } - if (copyConfig.patterns && copyConfig.patterns.length) { - copyConfig.options = copyConfig.options || {} - const globalIgnore = copyConfig.options.ignore - const projectDir = appPath - copyConfig.patterns.forEach(pattern => { - if (typeof pattern === 'object' && pattern.from && pattern.to) { - const from = path.join(projectDir, pattern.from) - const to = path.join(projectDir, pattern.to) - let ignore = pattern.ignore || globalIgnore - if (fs.existsSync(from)) { - const copyOptions: ICopyOptions = {} - if (ignore) { - ignore = Array.isArray(ignore) ? ignore : [ignore] - copyOptions.filter = src => { - let isMatch = false - ignore.forEach(iPa => { - if (minimatch(path.basename(src), iPa)) { - isMatch = true - } - }) - return !isMatch - } - } - copyFileSync(from, to, copyOptions) - } else { - Util.printLog(processTypeEnum.ERROR, '拷贝失败', `${pattern.from} 文件不存在!`) - } - } - }) - } -} - export async function build (buildConfig) { process.env.TARO_ENV = BUILD_TYPES.H5 await clean() - copyFiles() + Util.copyFiles(appPath, projectConfig.copy) await buildTemp() await buildDist(buildConfig) if (buildConfig.watch) { diff --git a/packages/taro-cli/src/mini/astProcess.ts b/packages/taro-cli/src/mini/astProcess.ts index 8c0ed1815224..09322ae69827 100644 --- a/packages/taro-cli/src/mini/astProcess.ts +++ b/packages/taro-cli/src/mini/astProcess.ts @@ -11,7 +11,6 @@ import { Config as IConfig } from '@tarojs/taro' const template = require('babel-template') import { - CONFIG_MAP, REG_SCRIPT, REG_TYPESCRIPT, REG_JSON, @@ -21,7 +20,8 @@ import { REG_STYLE, CSS_EXT, processTypeEnum, - BUILD_TYPES + BUILD_TYPES, + NODE_MODULES_REG } from '../util/constants' import { resolveScriptPath, @@ -29,13 +29,14 @@ import { promoteRelativePath, isNpmPkg, isAliasPath, - replaceAliasPath + replaceAliasPath, + traverseObjectNode } from '../util' import { convertObjectToAstExpression, convertArrayToAstExpression } from '../util/astConvert' import babylonConfig from '../config/babylon' +import { getExactedNpmFilePath, getNotExistNpmList } from '../util/npmExact' import { - NODE_MODULES_REG, PARSE_AST_TYPE, taroJsComponents, taroJsRedux, @@ -43,48 +44,12 @@ import { DEVICE_RATIO_NAME } from './constants' import { IComponentObj } from './interface' -import { getExactedNpmFilePath, getNotExistNpmList } from './npmExact' import { getBuildData, isFileToBePage } from './helper' import { processStyleUseCssModule } from './compileStyle' -function traverseObjectNode (node) { - const { buildAdapter } = getBuildData() - if (node.type === 'ClassProperty' || node.type === 'ObjectProperty') { - const properties = node.value.properties - const obj = {} - properties.forEach(p => { - let key = t.isIdentifier(p.key) ? p.key.name : p.key.value - if (CONFIG_MAP[buildAdapter][key]) { - key = CONFIG_MAP[buildAdapter][key] - } - obj[key] = traverseObjectNode(p.value) - }) - return obj - } - if (node.type === 'ObjectExpression') { - const properties = node.properties - const obj= {} - properties.forEach(p => { - let key = t.isIdentifier(p.key) ? p.key.name : p.key.value - if (CONFIG_MAP[buildAdapter][key]) { - key = CONFIG_MAP[buildAdapter][key] - } - obj[key] = traverseObjectNode(p.value) - }) - return obj - } - if (node.type === 'ArrayExpression') { - return node.elements.map(item => traverseObjectNode(item)) - } - if (node.type === 'NullLiteral') { - return null - } - return node.value -} - function createCssModuleMap (styleFilePath, tokens) { const { sourceDir, @@ -315,7 +280,7 @@ export function parseAst ( left.object.type === 'ThisExpression' && left.property.type === 'Identifier' && left.property.name === 'config') { - configObj = traverseObjectNode(node.expression.right) + configObj = traverseObjectNode(node.expression.right, buildAdapter) } } } @@ -398,7 +363,7 @@ export function parseAst ( ClassProperty (astPath) { const node = astPath.node if (node.key.name === 'config') { - configObj = traverseObjectNode(node) + configObj = traverseObjectNode(node, buildAdapter) } }, diff --git a/packages/taro-cli/src/mini/compileScript.ts b/packages/taro-cli/src/mini/compileScript.ts index 88885c486b23..66804b65bd84 100644 --- a/packages/taro-cli/src/mini/compileScript.ts +++ b/packages/taro-cli/src/mini/compileScript.ts @@ -5,12 +5,14 @@ import * as wxTransformer from '@tarojs/transformer-wx' import { printLog, - isDifferentArray + isDifferentArray, + copyFileSync } from '../util' import { BUILD_TYPES, processTypeEnum, - REG_TYPESCRIPT + REG_TYPESCRIPT, + NODE_MODULES_REG } from '../util/constants' import { callPlugin } from '../util/npm' import { IWxTransformResult } from '../util/types' @@ -24,8 +26,7 @@ import { uglifyJS } from './helper' import { parseAst } from './astProcess' -import { PARSE_AST_TYPE, NODE_MODULES_REG } from './constants' -import { copyFileSync } from './copy' +import { PARSE_AST_TYPE } from './constants' import { IDependency } from './interface' const isBuildingScripts: Map = new Map() diff --git a/packages/taro-cli/src/mini/component.ts b/packages/taro-cli/src/mini/component.ts index 4e8bf7466802..21ee131d48c7 100644 --- a/packages/taro-cli/src/mini/component.ts +++ b/packages/taro-cli/src/mini/component.ts @@ -9,7 +9,9 @@ import traverse from 'babel-traverse' import { IWxTransformResult } from '../util/types' import { REG_TYPESCRIPT, - processTypeEnum + processTypeEnum, + NODE_MODULES_REG, + NODE_MODULES } from '../util/constants' import { printLog, @@ -37,7 +39,7 @@ import { import { compileScriptFile, compileDepScripts } from './compileScript' import { compileDepStyles } from './compileStyle' import { transfromNativeComponents, processNativeWxml } from './native' -import { PARSE_AST_TYPE, NODE_MODULES_REG, NODE_MODULES } from './constants' +import { PARSE_AST_TYPE } from './constants' const notTaroComponents = new Set() const componentsNamedMap = new Map() diff --git a/packages/taro-cli/src/mini/constants.ts b/packages/taro-cli/src/mini/constants.ts index 13c44e0d256d..d0f91d80ad25 100644 --- a/packages/taro-cli/src/mini/constants.ts +++ b/packages/taro-cli/src/mini/constants.ts @@ -4,9 +4,6 @@ export const taroJsFramework = '@tarojs/taro' export const taroJsComponents = '@tarojs/components' export const taroJsRedux = '@tarojs/redux' -export const NODE_MODULES = 'node_modules' -export const NODE_MODULES_REG = /(.*)node_modules/ - export enum PARSE_AST_TYPE { ENTRY = 'ENTRY', PAGE = 'PAGE', diff --git a/packages/taro-cli/src/mini/copy.ts b/packages/taro-cli/src/mini/copy.ts deleted file mode 100644 index 4458c810f76e..000000000000 --- a/packages/taro-cli/src/mini/copy.ts +++ /dev/null @@ -1,20 +0,0 @@ -import * as fs from 'fs-extra' -import * as path from 'path' - -import { ICopyOptions } from './interface' - -export function copyFileSync (from: string, to: string, options?: ICopyOptions) { - const filename = path.basename(from) - if (fs.statSync(from).isFile() && !path.extname(to)) { - fs.ensureDir(to) - if (from === path.join(to, filename)) { - return - } - return fs.copySync(from, path.join(to, filename), options) - } - if (from === to) { - return - } - fs.ensureDir(path.dirname(to)) - return fs.copySync(from, to, options) -} diff --git a/packages/taro-cli/src/mini/helper.ts b/packages/taro-cli/src/mini/helper.ts index e3bd3b98ad74..c17f687f235d 100644 --- a/packages/taro-cli/src/mini/helper.ts +++ b/packages/taro-cli/src/mini/helper.ts @@ -10,7 +10,8 @@ import { IMINI_APP_FILE_TYPE, PROJECT_CONFIG, processTypeEnum, - REG_SCRIPTS + REG_SCRIPTS, + NODE_MODULES_REG } from '../util/constants' import { resolveScriptPath, @@ -39,8 +40,7 @@ import { IBuildResult, IDependency } from './interface' -import { NODE_MODULES_REG } from './constants' -import { getNodeModulesPath, getNpmOutputDir } from './npmExact' +import { getNodeModulesPath, getNpmOutputDir } from '../util/npmExact' const appPath = process.cwd() const configDir = path.join(appPath, PROJECT_CONFIG) diff --git a/packages/taro-cli/src/mini/index.ts b/packages/taro-cli/src/mini/index.ts index bec467715827..663e28357c06 100644 --- a/packages/taro-cli/src/mini/index.ts +++ b/packages/taro-cli/src/mini/index.ts @@ -2,13 +2,13 @@ import * as fs from 'fs-extra' import * as path from 'path' import chalk from 'chalk' -import * as minimatch from 'minimatch' import * as _ from 'lodash' import { printLog, getInstalledNpmPkgVersion, - getPkgVersion + getPkgVersion, + copyFiles } from '../util' import { processTypeEnum, BUILD_TYPES } from '../util/constants' import { IMiniAppBuildConfig } from '../util/types' @@ -19,8 +19,6 @@ import { setBuildAdapter, setAppConfig } from './helper' -import { ICopyOptions } from './interface' -import { copyFileSync } from './copy' import { buildEntry } from './entry' import { buildPages } from './page' import { watchFiles } from './watch' @@ -99,42 +97,8 @@ async function buildFrameworkInfo () { } } -function copyFiles () { - const { projectConfig } = getBuildData() - const copyConfig = projectConfig.copy || { patterns: [], options: {} } - if (copyConfig.patterns && copyConfig.patterns.length) { - copyConfig.options = copyConfig.options || {} - const globalIgnore = copyConfig.options.ignore - const projectDir = appPath - copyConfig.patterns.forEach(pattern => { - if (typeof pattern === 'object' && pattern.from && pattern.to) { - const from = path.join(projectDir, pattern.from) - const to = path.join(projectDir, pattern.to) - let ignore = pattern.ignore || globalIgnore - if (fs.existsSync(from)) { - const copyOptions: ICopyOptions = {} - if (ignore) { - ignore = Array.isArray(ignore) ? ignore : [ignore] - copyOptions.filter = src => { - let isMatch = false - ignore && ignore.forEach(iPa => { - if (minimatch(path.basename(src), iPa)) { - isMatch = true - } - }) - return !isMatch - } - } - copyFileSync(from, to, copyOptions) - } else { - printLog(processTypeEnum.ERROR, '拷贝失败', `${pattern.from} 文件不存在!`) - } - } - }) - } -} - export async function build ({ watch, adapter = BUILD_TYPES.WEAPP, envHasBeenSet = false }: IMiniAppBuildConfig) { + const { projectConfig } = getBuildData() process.env.TARO_ENV = adapter if (!envHasBeenSet) { setIsProduction(process.env.NODE_ENV === 'production' || !watch) @@ -143,7 +107,7 @@ export async function build ({ watch, adapter = BUILD_TYPES.WEAPP, envHasBeenSet // await checkCliAndFrameworkVersion() buildProjectConfig() await buildFrameworkInfo() - copyFiles() + copyFiles(appPath, projectConfig.copy) const appConfig = await buildEntry() setAppConfig(appConfig) await buildPages() diff --git a/packages/taro-cli/src/mini/interface.ts b/packages/taro-cli/src/mini/interface.ts index 92fac4df8d16..54d9505bd70d 100644 --- a/packages/taro-cli/src/mini/interface.ts +++ b/packages/taro-cli/src/mini/interface.ts @@ -23,7 +23,3 @@ export interface IDependency { json: string[], media: string[] } - -export interface ICopyOptions { - filter?: (src: string) => boolean -} diff --git a/packages/taro-cli/src/mini/native.ts b/packages/taro-cli/src/mini/native.ts index 1cdf243d5a14..42305af74ced 100644 --- a/packages/taro-cli/src/mini/native.ts +++ b/packages/taro-cli/src/mini/native.ts @@ -5,9 +5,8 @@ import { Config as IConfig } from '@tarojs/taro' import chalk from 'chalk' import { REG_WXML_IMPORT, processTypeEnum } from '../util/constants' -import { isEmptyObject, printLog, resolveScriptPath } from '../util' +import { isEmptyObject, printLog, resolveScriptPath, copyFileSync } from '../util' -import { copyFileSync } from './copy' import { buildDepComponents } from './component' import { taroJsFramework } from './constants' import { compileDepScripts } from './compileScript' diff --git a/packages/taro-cli/src/mini/page.ts b/packages/taro-cli/src/mini/page.ts index dd0329254302..7cacc4048992 100644 --- a/packages/taro-cli/src/mini/page.ts +++ b/packages/taro-cli/src/mini/page.ts @@ -7,20 +7,21 @@ import * as _ from 'lodash' import { REG_TYPESCRIPT, - processTypeEnum + processTypeEnum, + NODE_MODULES_REG } from '../util/constants' import { resolveScriptPath, printLog, isEmptyObject, promoteRelativePath, - isDifferentArray + isDifferentArray, + copyFileSync } from '../util' import { IWxTransformResult } from '../util/types' import { IComponentObj } from './interface' -import { PARSE_AST_TYPE, NODE_MODULES_REG, taroJsFramework } from './constants' -import { copyFileSync } from './copy' +import { PARSE_AST_TYPE, taroJsFramework } from './constants' import { getBuildData, getRealComponentsPathList, diff --git a/packages/taro-cli/src/mini/watch.ts b/packages/taro-cli/src/mini/watch.ts index e32ae8274901..31127e2e1dad 100644 --- a/packages/taro-cli/src/mini/watch.ts +++ b/packages/taro-cli/src/mini/watch.ts @@ -7,7 +7,8 @@ import { REG_TYPESCRIPT, REG_SCRIPT, REG_STYLE, - processTypeEnum + processTypeEnum, + NODE_MODULES_REG } from '../util/constants' import { printLog, @@ -29,7 +30,7 @@ import { import { buildEntry } from './entry' import { buildPages, buildSinglePage } from './page' import { buildSingleComponent, getComponentsNamedMap } from './component' -import { isWindows, NODE_MODULES_REG } from './constants' +import { isWindows } from './constants' export function watchFiles () { const appPath = process.cwd() diff --git a/packages/taro-cli/src/quick/astProcess.ts b/packages/taro-cli/src/quick/astProcess.ts new file mode 100644 index 000000000000..6221fadddea2 --- /dev/null +++ b/packages/taro-cli/src/quick/astProcess.ts @@ -0,0 +1,176 @@ +import * as fs from 'fs-extra' +import * as path from 'path' + +import * as babel from 'babel-core' +import * as t from 'babel-types' +import generate from 'babel-generator' +import traverse from 'babel-traverse' +import _ from 'lodash' +import { Config as IConfig } from '@tarojs/taro' + +import { PARSE_AST_TYPE } from './constants' +import { getBuildData } from './helper' +import { getNotExistNpmList } from '../util/npmExact' +import { traverseObjectNode } from '../util' + +export function parseAst ( + type: PARSE_AST_TYPE, + ast: t.File, + sourceFilePath: string, + filePath: string, + npmSkip: boolean = false +) { + const styleFiles: string[] = [] + const scriptFiles: string[] = [] + const jsonFiles: string[] = [] + const mediaFiles: string[] = [] + + const { + nodeModulesPath, + npmOutputDir, + sourceDir, + outputDir, + buildAdapter, + constantsReplaceList, + isProduction, + npmConfig, + alias: pathAlias, + projectConfig + } = getBuildData() + const notExistNpmList = getNotExistNpmList() + const taroMiniAppFramework = `@tarojs/taro-${buildAdapter}` + let needExportDefault = false + let configObj: IConfig = {} + let componentClassName: string = '' + ast = babel.transformFromAst(ast, '', { + plugins: [ + [require('babel-plugin-danger-remove-unused-import'), { ignore: ['@tarojs/taro', 'react', 'nervjs'] }], + [require('babel-plugin-transform-define').default, constantsReplaceList] + ] + }).ast as t.File + traverse(ast, { + ClassDeclaration (astPath) { + const node = astPath.node + let hasCreateData = false + if (astPath.isProperty({ superClass: true })) { + astPath.traverse({ + ClassMethod (astPath) { + if (astPath.get('key').isIdentifier({ name: '_createData' })) { + hasCreateData = true + } + } + }) + if (hasCreateData) { + needExportDefault = true + astPath.traverse({ + ClassMethod (astPath) { + const node = astPath.node + if (node.kind === 'constructor') { + astPath.traverse({ + ExpressionStatement (astPath) { + const node = astPath.node + if (node.expression && + node.expression.type === 'AssignmentExpression' && + node.expression.operator === '=') { + const left = node.expression.left + if (left.type === 'MemberExpression' && + left.object.type === 'ThisExpression' && + left.property.type === 'Identifier' && + left.property.name === 'config') { + configObj = traverseObjectNode(node.expression.right, buildAdapter) + } + } + } + }) + } + } + }) + if (node.id === null) { + componentClassName = '_TaroComponentClass' + astPath.replaceWith( + t.classDeclaration( + t.identifier(componentClassName), + node.superClass as t.Expression, + node.body as t.ClassBody, + node.decorators as t.Decorator[] || [] + ) + ) + } else if (node.id.name === 'App') { + componentClassName = '_App' + astPath.replaceWith( + t.classDeclaration( + t.identifier(componentClassName), + node.superClass as t.Expression, + node.body as t.ClassBody, + node.decorators as t.Decorator[] || [] + ) + ) + } else { + componentClassName = node.id.name + } + } + } + }, + + ClassExpression (astPath) { + const node = astPath.node + if (node.superClass) { + let hasCreateData = false + astPath.traverse({ + ClassMethod (astPath) { + if (astPath.get('key').isIdentifier({ name: '_createData' })) { + hasCreateData = true + } + } + }) + if (hasCreateData) { + needExportDefault = true + if (node.id === null) { + const parentNode = astPath.parentPath.node as any + if (t.isVariableDeclarator(astPath.parentPath)) { + componentClassName = parentNode.id.name + } else { + componentClassName = '_TaroComponentClass' + } + astPath.replaceWith( + t.classExpression( + t.identifier(componentClassName), + node.superClass as t.Expression, + node.body as t.ClassBody, + node.decorators as t.Decorator[] || [] + ) + ) + } else if (node.id.name === 'App') { + componentClassName = '_App' + astPath.replaceWith( + t.classExpression( + t.identifier(componentClassName), + node.superClass as t.Expression, + node.body as t.ClassBody, + node.decorators as t.Decorator[] || [] + ) + ) + } else { + componentClassName = node.id.name + } + } + } + }, + + ClassProperty (astPath) { + const node = astPath.node + if (node.key.name === 'config') { + configObj = traverseObjectNode(node, buildAdapter) + } + } + }) + return { + code: generate(ast).code, + styleFiles, + scriptFiles, + jsonFiles, + configObj, + mediaFiles, + componentClassName + } +} diff --git a/packages/taro-cli/src/quick/constants.ts b/packages/taro-cli/src/quick/constants.ts new file mode 100644 index 000000000000..7feed344bca2 --- /dev/null +++ b/packages/taro-cli/src/quick/constants.ts @@ -0,0 +1,6 @@ +export enum PARSE_AST_TYPE { + ENTRY = 'ENTRY', + PAGE = 'PAGE', + COMPONENT = 'COMPONENT', + NORMAL = 'NORMAL' +} diff --git a/packages/taro-cli/src/quick/entry.ts b/packages/taro-cli/src/quick/entry.ts index e69de29bb2d1..3227bf257d54 100644 --- a/packages/taro-cli/src/quick/entry.ts +++ b/packages/taro-cli/src/quick/entry.ts @@ -0,0 +1,47 @@ +import * as fs from 'fs-extra' +import * as path from 'path' + +import * as wxTransformer from '@tarojs/transformer-wx' + +import { IWxTransformResult } from '../util/types' +import { processTypeEnum, REG_TYPESCRIPT } from '../util/constants' +import { printLog } from '../util' + +import { getBuildData, setAppConfig, getDependencyTree } from './helper' +import { parseAst } from './astProcess' +import { PARSE_AST_TYPE } from './constants' + +export async function buildEntry () { + const { + buildAdapter, + constantsReplaceList, + entryFilePath, + outputDir, + entryFileName, + sourceDirName, + projectConfig + } = getBuildData() + + const quickAppConf = projectConfig.quickApp + const entryFileCode = fs.readFileSync(entryFilePath).toString() + const outputEntryFilePath = path.join(outputDir, entryFileName) + + printLog(processTypeEnum.COMPILE, '入口文件', `${sourceDirName}/${entryFileName}`) + try { + const transformResult: IWxTransformResult = wxTransformer({ + code: entryFileCode, + sourcePath: entryFilePath, + outputPath: outputEntryFilePath, + isApp: true, + isTyped: REG_TYPESCRIPT.test(entryFilePath), + adapter: buildAdapter, + env: constantsReplaceList + }) + const { configObj, code } = parseAst(PARSE_AST_TYPE.ENTRY, transformResult.ast, entryFilePath, outputEntryFilePath) + const dependencyTree = getDependencyTree() + setAppConfig(configObj) + console.log(transformResult.template) + } catch (err) { + console.log(err) + } +} diff --git a/packages/taro-cli/src/quick/helper.ts b/packages/taro-cli/src/quick/helper.ts new file mode 100644 index 000000000000..084ca7f68fbd --- /dev/null +++ b/packages/taro-cli/src/quick/helper.ts @@ -0,0 +1,105 @@ +import * as path from 'path' + +import * as _ from 'lodash' +import { AppConfig } from '@tarojs/taro' + +import { + BUILD_TYPES, + PROJECT_CONFIG +} from '../util/constants' +import CONFIG from '../config' +import { + resolveScriptPath, + generateEnvList, + generateConstantsList +} from '../util' +import { IProjectConfig, INpmConfig, IOption } from '../util/types' +import { getNodeModulesPath, getNpmOutputDir } from '../util/npmExact' +import { IDependency } from './interface' + +const appPath = process.cwd() +const configDir = path.join(appPath, PROJECT_CONFIG) +const projectConfig = require(configDir)(_.merge) +const sourceDirName = projectConfig.sourceRoot || CONFIG.SOURCE_DIR +const outputDirName = projectConfig.outputRoot || CONFIG.OUTPUT_DIR +const sourceDir = path.join(appPath, sourceDirName) +const outputDir = path.join(appPath, outputDirName) +const entryFilePath = resolveScriptPath(path.join(sourceDir, CONFIG.ENTRY)) +const entryFileName = path.basename(entryFilePath) + +const pathAlias = projectConfig.alias || {} +const quickAppConf = projectConfig.quickApp || {} +const npmConfig = Object.assign({ + name: CONFIG.NPM_DIR, + dir: null +}, quickAppConf.npm) + +const minifestJSON = {} +const dependencyTree: Map = new Map() + +export interface IBuildData { + appPath: string, + configDir: string, + sourceDirName: string, + outputDirName: string, + sourceDir: string, + outputDir: string, + entryFilePath: string, + entryFileName: string, + projectConfig: IProjectConfig, + npmConfig: INpmConfig, + appConfig: AppConfig, + alias: IOption, + isProduction: boolean, + buildAdapter: BUILD_TYPES, + constantsReplaceList: IOption, + nodeModulesPath: string, + npmOutputDir: string +} + +const BuildData: IBuildData = { + appPath, + configDir, + sourceDirName, + outputDirName, + sourceDir, + outputDir, + entryFilePath, + entryFileName, + projectConfig, + npmConfig, + alias: pathAlias, + isProduction: false, + appConfig: {}, + buildAdapter: BUILD_TYPES.WEAPP, + constantsReplaceList: {}, + nodeModulesPath: getNodeModulesPath(), + npmOutputDir: getNpmOutputDir(outputDir, configDir, npmConfig) +} + +export function setAppConfig (appConfig: AppConfig) { + BuildData.appConfig = appConfig +} + +export function setIsProduction (isProduction: boolean) { + BuildData.isProduction = isProduction +} + +export function setBuildAdapter (adapter: BUILD_TYPES) { + BuildData.buildAdapter = adapter + BuildData.constantsReplaceList = Object.assign({}, generateEnvList(projectConfig.env || {}), generateConstantsList(projectConfig.defineConstants || {}), { + 'process.env.TARO_ENV': adapter + }) +} + +export function getBuildData (): IBuildData { + return BuildData +} + +export function setManifestJSON (key, value) { + minifestJSON[key] = value +} + +export function getDependencyTree (): Map { + return dependencyTree +} diff --git a/packages/taro-cli/src/quick/index.ts b/packages/taro-cli/src/quick/index.ts index 43480c41db32..69a02a8669eb 100644 --- a/packages/taro-cli/src/quick/index.ts +++ b/packages/taro-cli/src/quick/index.ts @@ -1,2 +1,22 @@ -export async function build ({ watch }) { +import { BUILD_TYPES } from '../util/constants' +import { IMiniAppBuildConfig } from '../util/types' + +import { + getBuildData, + setIsProduction, + setBuildAdapter, + setAppConfig +} from './helper' +import { copyFiles } from '../util' + +import { buildEntry } from './entry' + +export async function build ({ watch, adapter = BUILD_TYPES.QUICKAPP }: IMiniAppBuildConfig) { + const { projectConfig, appPath } = getBuildData() + process.env.TARO_ENV = adapter + setIsProduction(process.env.NODE_ENV === 'production' || !watch) + setBuildAdapter(adapter) + copyFiles(appPath, projectConfig.copy) + const appConfig = await buildEntry() + // setAppConfig(appConfig) } diff --git a/packages/taro-cli/src/quick/interface.ts b/packages/taro-cli/src/quick/interface.ts index 8ddc201f41dc..db83f46215ee 100644 --- a/packages/taro-cli/src/quick/interface.ts +++ b/packages/taro-cli/src/quick/interface.ts @@ -1,142 +1,6 @@ -import { IOption } from '../util/types' - -type FeatureItem = { - name: string -} - -export type SystemConfig = { - /** - * 打印日志等级,分为 off,error,warn,info,log,debug - */ - logLevel?: 'off' | 'error' | 'warn' | 'info' | 'log' | 'debug', - /** - * 页面设计基准宽度,根据实际设备宽度来缩放元素大小 - */ - designWidth?: number, - /** - * 全局数据对象,属性名不能以$或_开头,在页面中可通过 this 进行访问;如果全局数据属性与页面的数据属性重名,则页面初始化时,全局数据会覆盖页面中对应的属性值 - */ - data?: IOption -} - -type RouterConfig = { - /** - * 首页名称 - */ - entry: string, - /** - * 页面配置列表,key 值为页面名称(对应页面目录名,例如 Hello 对应'Hello'目录),value 为页面详细配置 page - */ - pages: RouterPage[] -} -type RouterPage = { - /** - * 页面对应的组件名,与 ux 文件名保持一致,例如'hello' 对应 'hello.ux' - */ - component: string, - /** - * 页面路径,例如“/user”,不填则默认为/<页面名称>。 - * path 必须唯一,不能和其他 page 的 path 相同。 - * 下面 page 的 path 因为缺失,会被设置为“/Index”: - * "Index": {"component": "index"} - */ - path?: string, - /** - * 声明页面可以处理某种请求 - */ - filter: { - [key: string]: { - uri: string - } - } -} - -interface IDefaultDisplayConfig { - /** - * 窗口背景颜色 - */ - backgroundColor?: string, - /** - * 是否是全屏模式,默认不会同时作用于 titleBar,titleBar 需要继续通过 titleBar 控制 - */ - fullScreen?: boolean, - /** - * 是否显示 titleBar - */ - titleBar?: boolean, - /** - * 标题栏背景色 - */ - titleBarBackgroundColor?: string, - /** - * 标题栏文字颜色 - */ - titleBarTextColor?: string, - /** - * 标题栏文字(也可通过页面跳转传递参数(titleBarText)设置) - */ - titleBarText?: string, - /** - * 是否显示标题栏右上角菜单按钮,点击菜单按钮调用页面生命周期 onMenuPress 方法,如果该方法未实现则显示系统默认菜单 - */ - menu?: boolean, - /** - * 软键盘弹出时为保证输入框可见,页面的调整方式。 adjustPan:上移页面; adjustResize:压缩页面显示区域,当页面全屏时,此设置不生效 - */ - windowSoftInputMode?: 'adjustPan' | 'adjustResize' -} - -interface IDisplayConfig extends IDefaultDisplayConfig { - /** - * 各个页面的显示样式,key 为页面名(与路由中的页面名保持一致),value 为窗口显示样式,页面样式覆盖 default 样式 - */ - pages?: { - [key: string]: IDefaultDisplayConfig - } -} - -export interface ITaroManifestConfig { - /** - * 应用包名,确认与原生应用的包名不一致,推荐采用 com.company.module 的格式,如:com.example.demo - */ - package: string, - /** - * 应用名称,6 个汉字以内,与应用商店保存的名称一致,用于在桌面图标、弹窗等处显示应用名称 - */ - name: string, - /** - * 应用图标,提供 192x192 大小的即可 - */ - icon: string, - /** - * 应用版本名称,如:"1.0" - */ - versionName?: string, - /** - * 应用版本号,从1自增,推荐每次重新上传包时versionCode+1 - */ - versionCode: number, - /** - * 支持的最小平台版本号,兼容性检查,避免上线后在低版本平台运行并导致不兼容;如果不填按照内测版本处理 - */ - minPlatformVersion?: string, - /** - * 接口列表,绝大部分接口都需要在这里声明,否则不能调用,详见每个接口的文档说明 - */ - features?: FeatureItem[] -} - -export interface IManifestConfig extends ITaroManifestConfig { - /** - * 系统配置信息 - */ - config: SystemConfig, - /** - * 路由信息 - */ - router: RouterConfig, - /** - * UI 显示相关配置 - */ - display?: IDisplayConfig +export interface IDependency { + style: string[], + script: string[], + json: string[], + media: string[] } diff --git a/packages/taro-cli/src/util/constants.ts b/packages/taro-cli/src/util/constants.ts index 6433b36e2324..ec895f0561d4 100644 --- a/packages/taro-cli/src/util/constants.ts +++ b/packages/taro-cli/src/util/constants.ts @@ -86,6 +86,9 @@ export const REG_WXML_IMPORT: RegExp = / { + let key = t.isIdentifier(p.key) ? p.key.name : p.key.value + if (CONFIG_MAP[buildAdapter][key] === false) { + return + } + if (CONFIG_MAP[buildAdapter][key]) { + key = CONFIG_MAP[buildAdapter][key] + } + obj[key] = traverseObjectNode(p.value, buildAdapter) + }) + return obj + } + if (node.type === 'ObjectExpression') { + const properties = node.properties + const obj= {} + properties.forEach(p => { + let key = t.isIdentifier(p.key) ? p.key.name : p.key.value + if (CONFIG_MAP[buildAdapter][key] === false) { + return + } + if (CONFIG_MAP[buildAdapter][key]) { + key = CONFIG_MAP[buildAdapter][key] + } + obj[key] = traverseObjectNode(p.value, buildAdapter) + }) + return obj + } + if (node.type === 'ArrayExpression') { + return node.elements.map(item => traverseObjectNode(item, buildAdapter)) + } + if (node.type === 'NullLiteral') { + return null + } + return node.value +} + +export function copyFileSync (from: string, to: string, options?: ICopyArgOptions) { + const filename = path.basename(from) + if (fs.statSync(from).isFile() && !path.extname(to)) { + fs.ensureDir(to) + if (from === path.join(to, filename)) { + return + } + return fs.copySync(from, path.join(to, filename), options) + } + if (from === to) { + return + } + fs.ensureDir(path.dirname(to)) + return fs.copySync(from, to, options) +} + +export function copyFiles (appPath: string, copyConfig: ICopyOptions | void) { + copyConfig = copyConfig || { patterns: [], options: {} } + if (copyConfig.patterns && copyConfig.patterns.length) { + copyConfig.options = copyConfig.options || {} + const globalIgnore = copyConfig.options.ignore + const projectDir = appPath + copyConfig.patterns.forEach(pattern => { + if (typeof pattern === 'object' && pattern.from && pattern.to) { + const from = path.join(projectDir, pattern.from) + const to = path.join(projectDir, pattern.to) + let ignore = pattern.ignore || globalIgnore + if (fs.existsSync(from)) { + const copyOptions: ICopyArgOptions = {} + if (ignore) { + ignore = Array.isArray(ignore) ? ignore : [ignore] + copyOptions.filter = src => { + let isMatch = false + ignore && ignore.forEach(iPa => { + if (minimatch(path.basename(src), iPa)) { + isMatch = true + } + }) + return !isMatch + } + } + copyFileSync(from, to, copyOptions) + } else { + printLog(processTypeEnum.ERROR, '拷贝失败', `${pattern.from} 文件不存在!`) + } + } + }) + } +} diff --git a/packages/taro-cli/src/mini/npmExact.ts b/packages/taro-cli/src/util/npmExact.ts similarity index 88% rename from packages/taro-cli/src/mini/npmExact.ts rename to packages/taro-cli/src/util/npmExact.ts index 3309c7d7cd5c..29e9f83033bd 100644 --- a/packages/taro-cli/src/mini/npmExact.ts +++ b/packages/taro-cli/src/util/npmExact.ts @@ -1,11 +1,9 @@ import * as path from 'path' -import { resolveNpmFilesPath } from '../util/resolve_npm_files' -import { INpmConfig } from '../util/types' -import { BUILD_TYPES, REG_STYLE } from '../util/constants' -import { promoteRelativePath, recursiveFindNodeModules } from '../util' - -import { NODE_MODULES } from './constants' +import { resolveNpmFilesPath } from './resolve_npm_files' +import { INpmConfig } from './types' +import { BUILD_TYPES, REG_STYLE, NODE_MODULES } from './constants' +import { promoteRelativePath, recursiveFindNodeModules } from './index' interface IArgs { npmName: string, diff --git a/packages/taro-cli/src/util/types.ts b/packages/taro-cli/src/util/types.ts index 96ef8d635b95..6e552b559070 100644 --- a/packages/taro-cli/src/util/types.ts +++ b/packages/taro-cli/src/util/types.ts @@ -71,6 +71,10 @@ export interface ICopyOptions { } } +export interface ICopyArgOptions { + filter?: (src: string) => boolean +} + export interface IWxTransformResult { code: string, ast: t.File, @@ -108,7 +112,8 @@ export interface ICompileOption { } export interface IMiniAppConfig { - appOutput: boolean, + appOutput?: boolean, + npm?: INpmConfig, module?: { postcss?: IPostcssOption }, @@ -158,6 +163,162 @@ export interface IH5Config { } } +type FeatureItem = { + name: string +} + +const enum LogLevel { + OFF = 'off', + ERROR = 'error', + WARN = 'warn', + INFO = 'info', + LOG = 'log', + DEBUG = 'debug' +} + +export type SystemConfig = { + /** + * 打印日志等级,分为 off,error,warn,info,log,debug + */ + logLevel?: LogLevel, + /** + * 页面设计基准宽度,根据实际设备宽度来缩放元素大小 + */ + designWidth?: number, + /** + * 全局数据对象,属性名不能以$或_开头,在页面中可通过 this 进行访问;如果全局数据属性与页面的数据属性重名,则页面初始化时,全局数据会覆盖页面中对应的属性值 + */ + data?: IOption +} + +type RouterConfig = { + /** + * 首页名称 + */ + entry: string, + /** + * 页面配置列表,key 值为页面名称(对应页面目录名,例如 Hello 对应'Hello'目录),value 为页面详细配置 page + */ + pages: RouterPage[] +} +type RouterPage = { + /** + * 页面对应的组件名,与 ux 文件名保持一致,例如'hello' 对应 'hello.ux' + */ + component: string, + /** + * 页面路径,例如“/user”,不填则默认为/<页面名称>。 + * path 必须唯一,不能和其他 page 的 path 相同。 + * 下面 page 的 path 因为缺失,会被设置为“/Index”: + * "Index": {"component": "index"} + */ + path?: string, + /** + * 声明页面可以处理某种请求 + */ + filter: { + [key: string]: { + uri: string + } + } +} + +interface IDefaultDisplayConfig { + /** + * 窗口背景颜色 + */ + backgroundColor?: string, + /** + * 是否是全屏模式,默认不会同时作用于 titleBar,titleBar 需要继续通过 titleBar 控制 + */ + fullScreen?: boolean, + /** + * 是否显示 titleBar + */ + titleBar?: boolean, + /** + * 标题栏背景色 + */ + titleBarBackgroundColor?: string, + /** + * 标题栏文字颜色 + */ + titleBarTextColor?: string, + /** + * 标题栏文字(也可通过页面跳转传递参数(titleBarText)设置) + */ + titleBarText?: string, + /** + * 是否显示标题栏右上角菜单按钮,点击菜单按钮调用页面生命周期 onMenuPress 方法,如果该方法未实现则显示系统默认菜单 + */ + menu?: boolean, + /** + * 软键盘弹出时为保证输入框可见,页面的调整方式。 adjustPan:上移页面; adjustResize:压缩页面显示区域,当页面全屏时,此设置不生效 + */ + windowSoftInputMode?: 'adjustPan' | 'adjustResize' +} + +interface IDisplayConfig extends IDefaultDisplayConfig { + /** + * 各个页面的显示样式,key 为页面名(与路由中的页面名保持一致),value 为窗口显示样式,页面样式覆盖 default 样式 + */ + pages?: { + [key: string]: IDefaultDisplayConfig + } +} + +export interface ITaroManifestConfig { + npm?: INpmConfig, + /** + * 应用包名,确认与原生应用的包名不一致,推荐采用 com.company.module 的格式,如:com.example.demo + */ + package: string, + /** + * 应用名称,6 个汉字以内,与应用商店保存的名称一致,用于在桌面图标、弹窗等处显示应用名称 + */ + name: string, + /** + * 应用图标,提供 192x192 大小的即可 + */ + icon: string, + /** + * 应用版本名称,如:"1.0" + */ + versionName?: string, + /** + * 应用版本号,从1自增,推荐每次重新上传包时versionCode+1 + */ + versionCode: number, + /** + * 支持的最小平台版本号,兼容性检查,避免上线后在低版本平台运行并导致不兼容;如果不填按照内测版本处理 + */ + minPlatformVersion?: string, + /** + * 接口列表,绝大部分接口都需要在这里声明,否则不能调用,详见每个接口的文档说明 + */ + features?: FeatureItem[], + /** + * + */ + logLevel?: LogLevel +} + +export interface IManifestConfig extends ITaroManifestConfig { + /** + * 系统配置信息 + */ + config: SystemConfig, + /** + * 路由信息 + */ + router: RouterConfig, + /** + * UI 显示相关配置 + */ + display?: IDisplayConfig +} + + export interface IProjectConfig { projectName?: string, date?: string, @@ -178,5 +339,6 @@ export interface IProjectConfig { defineConstants?: IOption, copy?: ICopyOptions, weapp?: IMiniAppConfig, - h5?: IH5Config + h5?: IH5Config, + quickApp?: ITaroManifestConfig } From 50067da1c6163054f9d80169a58d5deb514b072b Mon Sep 17 00:00:00 2001 From: luckyadam Date: Wed, 13 Mar 2019 11:34:37 +0800 Subject: [PATCH 038/126] =?UTF-8?q?feat:=20=E5=BF=AB=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E5=8F=8A=E5=BF=AB=E5=BA=94=E7=94=A8=E6=A1=86?= =?UTF-8?q?=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lerna.json | 1 + packages/taro-cli/src/mini/astProcess.ts | 14 ++- packages/taro-cli/src/mini/compileScript.ts | 4 +- packages/taro-cli/src/mini/compileStyle.ts | 3 +- packages/taro-cli/src/mini/component.ts | 4 +- packages/taro-cli/src/mini/constants.ts | 14 --- packages/taro-cli/src/mini/entry.ts | 4 +- packages/taro-cli/src/mini/native.ts | 3 +- packages/taro-cli/src/mini/page.ts | 5 +- packages/taro-cli/src/mini/watch.ts | 4 +- packages/taro-cli/src/quick/astProcess.ts | 25 +++++- packages/taro-cli/src/quick/constants.ts | 7 +- packages/taro-cli/src/quick/entry.ts | 5 +- packages/taro-cli/src/quick/helper.ts | 4 + packages/taro-cli/src/util/constants.ts | 16 ++++ packages/taro-quickapp/README.md | 3 + packages/taro-quickapp/index.js | 2 + packages/taro-quickapp/package.json | 29 +++++++ packages/taro-quickapp/rollup.config.js | 74 ++++++++++++++++ .../src/api/interactive/index.js | 0 .../src/api/request/index.js | 0 .../src/api/router/index.js | 12 +-- .../src/api/storage/index.js | 0 .../src/api/utils/index.js | 0 packages/taro-quickapp/src/component.js | 87 +++++++++++++++++++ packages/taro-quickapp/src/create-app.js | 26 ++++++ .../taro-quickapp/src/create-component.js | 3 + packages/taro-quickapp/src/index.js | 39 +++++++++ .../src/native-api.js | 0 packages/taro-quickapp/src/pure-component.js | 13 +++ 30 files changed, 347 insertions(+), 54 deletions(-) create mode 100644 packages/taro-quickapp/README.md create mode 100644 packages/taro-quickapp/index.js create mode 100644 packages/taro-quickapp/package.json create mode 100644 packages/taro-quickapp/rollup.config.js rename packages/{taro-qapp => taro-quickapp}/src/api/interactive/index.js (100%) rename packages/{taro-qapp => taro-quickapp}/src/api/request/index.js (100%) rename packages/{taro-qapp => taro-quickapp}/src/api/router/index.js (90%) rename packages/{taro-qapp => taro-quickapp}/src/api/storage/index.js (100%) rename packages/{taro-qapp => taro-quickapp}/src/api/utils/index.js (100%) create mode 100644 packages/taro-quickapp/src/component.js create mode 100644 packages/taro-quickapp/src/create-app.js create mode 100644 packages/taro-quickapp/src/create-component.js create mode 100644 packages/taro-quickapp/src/index.js rename packages/{taro-qapp => taro-quickapp}/src/native-api.js (100%) create mode 100644 packages/taro-quickapp/src/pure-component.js diff --git a/lerna.json b/lerna.json index 0987eea2d6a6..d575ec444194 100644 --- a/lerna.json +++ b/lerna.json @@ -26,6 +26,7 @@ "packages/taro-swan", "packages/taro-alipay", "packages/taro-tt", + "packages/taro-quickapp", "packages/taro-webpack-runner", "packages/postcss-plugin-constparse", "packages/eslint-config-taro", diff --git a/packages/taro-cli/src/mini/astProcess.ts b/packages/taro-cli/src/mini/astProcess.ts index 09322ae69827..dc0bdc70890d 100644 --- a/packages/taro-cli/src/mini/astProcess.ts +++ b/packages/taro-cli/src/mini/astProcess.ts @@ -21,7 +21,12 @@ import { CSS_EXT, processTypeEnum, BUILD_TYPES, - NODE_MODULES_REG + NODE_MODULES_REG, + PARSE_AST_TYPE, + taroJsComponents, + taroJsRedux, + taroJsFramework, + DEVICE_RATIO_NAME } from '../util/constants' import { resolveScriptPath, @@ -36,13 +41,6 @@ import { convertObjectToAstExpression, convertArrayToAstExpression } from '../ut import babylonConfig from '../config/babylon' import { getExactedNpmFilePath, getNotExistNpmList } from '../util/npmExact' -import { - PARSE_AST_TYPE, - taroJsComponents, - taroJsRedux, - taroJsFramework, - DEVICE_RATIO_NAME -} from './constants' import { IComponentObj } from './interface' import { getBuildData, diff --git a/packages/taro-cli/src/mini/compileScript.ts b/packages/taro-cli/src/mini/compileScript.ts index 66804b65bd84..32e1f94b3828 100644 --- a/packages/taro-cli/src/mini/compileScript.ts +++ b/packages/taro-cli/src/mini/compileScript.ts @@ -12,7 +12,8 @@ import { BUILD_TYPES, processTypeEnum, REG_TYPESCRIPT, - NODE_MODULES_REG + NODE_MODULES_REG, + PARSE_AST_TYPE } from '../util/constants' import { callPlugin } from '../util/npm' import { IWxTransformResult } from '../util/types' @@ -26,7 +27,6 @@ import { uglifyJS } from './helper' import { parseAst } from './astProcess' -import { PARSE_AST_TYPE } from './constants' import { IDependency } from './interface' const isBuildingScripts: Map = new Map() diff --git a/packages/taro-cli/src/mini/compileStyle.ts b/packages/taro-cli/src/mini/compileStyle.ts index 85c079420772..4f83384d4f6a 100644 --- a/packages/taro-cli/src/mini/compileStyle.ts +++ b/packages/taro-cli/src/mini/compileStyle.ts @@ -18,13 +18,12 @@ import { processStyleImports, promoteRelativePath } from '../util' -import { CSS_EXT, FILE_PROCESSOR_MAP } from '../util/constants' +import { CSS_EXT, FILE_PROCESSOR_MAP, DEVICE_RATIO_NAME } from '../util/constants' import { IMiniAppConfig } from '../util/types' import { getBuildData } from './helper' -import { DEVICE_RATIO_NAME } from './constants' const cssUrlParse = require('postcss-url') const genericNames = require('generic-names') diff --git a/packages/taro-cli/src/mini/component.ts b/packages/taro-cli/src/mini/component.ts index 21ee131d48c7..c899ffdf2dbd 100644 --- a/packages/taro-cli/src/mini/component.ts +++ b/packages/taro-cli/src/mini/component.ts @@ -11,7 +11,8 @@ import { REG_TYPESCRIPT, processTypeEnum, NODE_MODULES_REG, - NODE_MODULES + NODE_MODULES, + PARSE_AST_TYPE } from '../util/constants' import { printLog, @@ -39,7 +40,6 @@ import { import { compileScriptFile, compileDepScripts } from './compileScript' import { compileDepStyles } from './compileStyle' import { transfromNativeComponents, processNativeWxml } from './native' -import { PARSE_AST_TYPE } from './constants' const notTaroComponents = new Set() const componentsNamedMap = new Map() diff --git a/packages/taro-cli/src/mini/constants.ts b/packages/taro-cli/src/mini/constants.ts index d0f91d80ad25..8b137891791f 100644 --- a/packages/taro-cli/src/mini/constants.ts +++ b/packages/taro-cli/src/mini/constants.ts @@ -1,15 +1 @@ -import * as os from 'os' -export const taroJsFramework = '@tarojs/taro' -export const taroJsComponents = '@tarojs/components' -export const taroJsRedux = '@tarojs/redux' - -export enum PARSE_AST_TYPE { - ENTRY = 'ENTRY', - PAGE = 'PAGE', - COMPONENT = 'COMPONENT', - NORMAL = 'NORMAL' -} - -export const DEVICE_RATIO_NAME = 'deviceRatio' -export const isWindows = os.platform() === 'win32' diff --git a/packages/taro-cli/src/mini/entry.ts b/packages/taro-cli/src/mini/entry.ts index fb45bddb8d34..0991d605e2e7 100644 --- a/packages/taro-cli/src/mini/entry.ts +++ b/packages/taro-cli/src/mini/entry.ts @@ -8,7 +8,8 @@ import { REG_SCRIPTS, REG_TYPESCRIPT, CONFIG_MAP, - processTypeEnum + processTypeEnum, + PARSE_AST_TYPE } from '../util/constants' import { isDifferentArray, @@ -19,7 +20,6 @@ import { import { IWxTransformResult } from '../util/types' import { getBuildData, uglifyJS, copyFilesFromSrcToOutput, getDependencyTree } from './helper' -import { PARSE_AST_TYPE } from './constants' import { compileDepScripts, compileScriptFile } from './compileScript' import { compileDepStyles } from './compileStyle' import { parseAst } from './astProcess' diff --git a/packages/taro-cli/src/mini/native.ts b/packages/taro-cli/src/mini/native.ts index 42305af74ced..e5077fa405dd 100644 --- a/packages/taro-cli/src/mini/native.ts +++ b/packages/taro-cli/src/mini/native.ts @@ -4,11 +4,10 @@ import * as path from 'path' import { Config as IConfig } from '@tarojs/taro' import chalk from 'chalk' -import { REG_WXML_IMPORT, processTypeEnum } from '../util/constants' +import { REG_WXML_IMPORT, processTypeEnum, taroJsFramework } from '../util/constants' import { isEmptyObject, printLog, resolveScriptPath, copyFileSync } from '../util' import { buildDepComponents } from './component' -import { taroJsFramework } from './constants' import { compileDepScripts } from './compileScript' import { compileDepStyles } from './compileStyle' import { getBuildData } from './helper' diff --git a/packages/taro-cli/src/mini/page.ts b/packages/taro-cli/src/mini/page.ts index 7cacc4048992..1d4f0dcfbf95 100644 --- a/packages/taro-cli/src/mini/page.ts +++ b/packages/taro-cli/src/mini/page.ts @@ -8,7 +8,9 @@ import * as _ from 'lodash' import { REG_TYPESCRIPT, processTypeEnum, - NODE_MODULES_REG + NODE_MODULES_REG, + PARSE_AST_TYPE, + taroJsFramework } from '../util/constants' import { resolveScriptPath, @@ -21,7 +23,6 @@ import { import { IWxTransformResult } from '../util/types' import { IComponentObj } from './interface' -import { PARSE_AST_TYPE, taroJsFramework } from './constants' import { getBuildData, getRealComponentsPathList, diff --git a/packages/taro-cli/src/mini/watch.ts b/packages/taro-cli/src/mini/watch.ts index 31127e2e1dad..1985ff4fb40f 100644 --- a/packages/taro-cli/src/mini/watch.ts +++ b/packages/taro-cli/src/mini/watch.ts @@ -8,7 +8,8 @@ import { REG_SCRIPT, REG_STYLE, processTypeEnum, - NODE_MODULES_REG + NODE_MODULES_REG, + isWindows } from '../util/constants' import { printLog, @@ -30,7 +31,6 @@ import { import { buildEntry } from './entry' import { buildPages, buildSinglePage } from './page' import { buildSingleComponent, getComponentsNamedMap } from './component' -import { isWindows } from './constants' export function watchFiles () { const appPath = process.cwd() diff --git a/packages/taro-cli/src/quick/astProcess.ts b/packages/taro-cli/src/quick/astProcess.ts index 6221fadddea2..7069e4e3556f 100644 --- a/packages/taro-cli/src/quick/astProcess.ts +++ b/packages/taro-cli/src/quick/astProcess.ts @@ -8,10 +8,10 @@ import traverse from 'babel-traverse' import _ from 'lodash' import { Config as IConfig } from '@tarojs/taro' -import { PARSE_AST_TYPE } from './constants' -import { getBuildData } from './helper' +import { PARSE_AST_TYPE, taroJsComponents, taroJsQuickAppComponents } from '../util/constants' +import { getBuildData, isQuickAppPkg } from './helper' import { getNotExistNpmList } from '../util/npmExact' -import { traverseObjectNode } from '../util' +import { traverseObjectNode, isAliasPath, replaceAliasPath, isNpmPkg } from '../util' export function parseAst ( type: PARSE_AST_TYPE, @@ -162,6 +162,25 @@ export function parseAst ( if (node.key.name === 'config') { configObj = traverseObjectNode(node, buildAdapter) } + }, + + ImportDeclaration (astPath) { + const node = astPath.node + const source = node.source + let value = source.value + const specifiers = node.specifiers + if (isAliasPath(value, pathAlias)) { + value = replaceAliasPath(sourceFilePath, value, pathAlias) + source.value = value + } + if (isNpmPkg(value) + && !isQuickAppPkg(value) + && !notExistNpmList.has(value)) { + if (value === taroJsComponents) { + source.value = taroJsQuickAppComponents + } + + } } }) return { diff --git a/packages/taro-cli/src/quick/constants.ts b/packages/taro-cli/src/quick/constants.ts index 7feed344bca2..8b137891791f 100644 --- a/packages/taro-cli/src/quick/constants.ts +++ b/packages/taro-cli/src/quick/constants.ts @@ -1,6 +1 @@ -export enum PARSE_AST_TYPE { - ENTRY = 'ENTRY', - PAGE = 'PAGE', - COMPONENT = 'COMPONENT', - NORMAL = 'NORMAL' -} + diff --git a/packages/taro-cli/src/quick/entry.ts b/packages/taro-cli/src/quick/entry.ts index 3227bf257d54..151240a63bb0 100644 --- a/packages/taro-cli/src/quick/entry.ts +++ b/packages/taro-cli/src/quick/entry.ts @@ -4,12 +4,11 @@ import * as path from 'path' import * as wxTransformer from '@tarojs/transformer-wx' import { IWxTransformResult } from '../util/types' -import { processTypeEnum, REG_TYPESCRIPT } from '../util/constants' +import { processTypeEnum, REG_TYPESCRIPT, PARSE_AST_TYPE } from '../util/constants' import { printLog } from '../util' import { getBuildData, setAppConfig, getDependencyTree } from './helper' import { parseAst } from './astProcess' -import { PARSE_AST_TYPE } from './constants' export async function buildEntry () { const { @@ -40,7 +39,7 @@ export async function buildEntry () { const { configObj, code } = parseAst(PARSE_AST_TYPE.ENTRY, transformResult.ast, entryFilePath, outputEntryFilePath) const dependencyTree = getDependencyTree() setAppConfig(configObj) - console.log(transformResult.template) + console.log(code) } catch (err) { console.log(err) } diff --git a/packages/taro-cli/src/quick/helper.ts b/packages/taro-cli/src/quick/helper.ts index 084ca7f68fbd..41201f5c9b7a 100644 --- a/packages/taro-cli/src/quick/helper.ts +++ b/packages/taro-cli/src/quick/helper.ts @@ -103,3 +103,7 @@ export function setManifestJSON (key, value) { export function getDependencyTree (): Map { return dependencyTree } + +export function isQuickAppPkg (name: string): boolean { + return /@system\./.test(name) +} diff --git a/packages/taro-cli/src/util/constants.ts b/packages/taro-cli/src/util/constants.ts index ec895f0561d4..90450b338f2e 100644 --- a/packages/taro-cli/src/util/constants.ts +++ b/packages/taro-cli/src/util/constants.ts @@ -1,3 +1,4 @@ +import * as os from 'os' import chalk, { Chalk } from 'chalk' export const enum processTypeEnum { @@ -277,3 +278,18 @@ export const UPDATE_PACKAGE_LIST = [ '@tarojs/mobx-common', '@tarojs/mobx-prop-types' ] + +export enum PARSE_AST_TYPE { + ENTRY = 'ENTRY', + PAGE = 'PAGE', + COMPONENT = 'COMPONENT', + NORMAL = 'NORMAL' +} + +export const taroJsComponents = '@tarojs/components' +export const taroJsQuickAppComponents = '@tarojs/components-qa' +export const taroJsFramework = '@tarojs/taro' +export const taroJsRedux = '@tarojs/redux' + +export const DEVICE_RATIO_NAME = 'deviceRatio' +export const isWindows = os.platform() === 'win32' diff --git a/packages/taro-quickapp/README.md b/packages/taro-quickapp/README.md new file mode 100644 index 000000000000..c0cfd431f7be --- /dev/null +++ b/packages/taro-quickapp/README.md @@ -0,0 +1,3 @@ +# @tarojs/taro-quickapp + +多端解决方案快应用端基础框架 diff --git a/packages/taro-quickapp/index.js b/packages/taro-quickapp/index.js new file mode 100644 index 000000000000..437a6d4788f4 --- /dev/null +++ b/packages/taro-quickapp/index.js @@ -0,0 +1,2 @@ +module.exports = require('./dist/index.js').default +module.exports.default = module.exports diff --git a/packages/taro-quickapp/package.json b/packages/taro-quickapp/package.json new file mode 100644 index 000000000000..c800e5b32fa0 --- /dev/null +++ b/packages/taro-quickapp/package.json @@ -0,0 +1,29 @@ +{ + "name": "@tarojs/taro-quickapp", + "version": "1.2.13", + "description": "Taro quickapp framework", + "main": "index.js", + "files": [ + "dist", + "src", + "index.js", + "package.json" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "rollup -c rollup.config.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/NervJS/taro.git" + }, + "keywords": [ + "taro" + ], + "author": "O2Team", + "license": "MIT", + "dependencies": { + "@tarojs/taro": "1.2.13", + "@tarojs/utils": "1.2.13" + } +} diff --git a/packages/taro-quickapp/rollup.config.js b/packages/taro-quickapp/rollup.config.js new file mode 100644 index 000000000000..419b7f40bc33 --- /dev/null +++ b/packages/taro-quickapp/rollup.config.js @@ -0,0 +1,74 @@ +const { join } = require('path') +const resolve = require('rollup-plugin-node-resolve') +const babel = require('rollup-plugin-babel') +const common = require('rollup-plugin-commonjs') +const alias = require('rollup-plugin-alias') +const cwd = __dirname + +const baseConfig = { + input: join(cwd, 'src/index.js'), + external: ['nervjs'], + output: [ + { + file: join(cwd, 'dist/index.js'), + format: 'cjs', + sourcemap: true, + exports: 'named' + }, + { + file: join(cwd, 'dist/taro-quickapp.js'), + format: 'umd', + name: 'TaroAuickapp', + sourcemap: true, + exports: 'named' + } + ], + plugins: [ + alias({ + '@tarojs/taro': join(cwd, '../taro/src/index'), + '@tarojs/utils': join(cwd, '../taro-utils/dist/index') + }), + resolve({ + preferBuiltins: false + }), + + common({ + include: 'node_modules/**' + }), + babel({ + babelrc: false, + presets: [ + ['@babel/preset-env', { + modules: false + }] + ], + plugins: [ + '@babel/plugin-proposal-class-properties', + '@babel/plugin-proposal-object-rest-spread', + ['@babel/plugin-transform-react-jsx', { + 'pragma': 'Nerv.createElement' + }] + ] + }) + ] +} +const esmConfig = Object.assign({}, baseConfig, { + output: Object.assign({}, baseConfig.output, { + sourcemap: true, + format: 'es', + file: join(cwd, 'dist/index.esm.js') + }) +}) + +function rollup () { + const target = process.env.TARGET + + if (target === 'umd') { + return baseConfig + } else if (target === 'esm') { + return esmConfig + } else { + return [baseConfig, esmConfig] + } +} +module.exports = rollup() diff --git a/packages/taro-qapp/src/api/interactive/index.js b/packages/taro-quickapp/src/api/interactive/index.js similarity index 100% rename from packages/taro-qapp/src/api/interactive/index.js rename to packages/taro-quickapp/src/api/interactive/index.js diff --git a/packages/taro-qapp/src/api/request/index.js b/packages/taro-quickapp/src/api/request/index.js similarity index 100% rename from packages/taro-qapp/src/api/request/index.js rename to packages/taro-quickapp/src/api/request/index.js diff --git a/packages/taro-qapp/src/api/router/index.js b/packages/taro-quickapp/src/api/router/index.js similarity index 90% rename from packages/taro-qapp/src/api/router/index.js rename to packages/taro-quickapp/src/api/router/index.js index 82e40db19e6c..8e91e2c89139 100644 --- a/packages/taro-qapp/src/api/router/index.js +++ b/packages/taro-quickapp/src/api/router/index.js @@ -42,7 +42,7 @@ function qappNavigate (options = {}, method = 'push') { try { router[method]({ uri: url, - params, + params }) success && success(res) complete && complete(res) @@ -58,18 +58,18 @@ function qappNavigate (options = {}, method = 'push') { function getUrlParams (url = '') { let params = {} -  url && url.replace(/(\w+)=(\w+)/ig, function (a, b, c) { + url && url.replace(/(\w+)=(\w+)/ig, function (a, b, c) { params[b] = unescape(c) }) -  return params + return params } -export default { +export default { reLaunch, switchTab, navigateTo, redirectTo, navigateBack, - getCurrentPages -} \ No newline at end of file + getCurrentPages +} diff --git a/packages/taro-qapp/src/api/storage/index.js b/packages/taro-quickapp/src/api/storage/index.js similarity index 100% rename from packages/taro-qapp/src/api/storage/index.js rename to packages/taro-quickapp/src/api/storage/index.js diff --git a/packages/taro-qapp/src/api/utils/index.js b/packages/taro-quickapp/src/api/utils/index.js similarity index 100% rename from packages/taro-qapp/src/api/utils/index.js rename to packages/taro-quickapp/src/api/utils/index.js diff --git a/packages/taro-quickapp/src/component.js b/packages/taro-quickapp/src/component.js new file mode 100644 index 000000000000..152a402c3361 --- /dev/null +++ b/packages/taro-quickapp/src/component.js @@ -0,0 +1,87 @@ +import { + internal_safe_get as safeGet +} from '@tarojs/taro' + +export default class BaseComponent { + // _createData的时候生成,小程序中通过data.__createData访问 + __computed = {} + // this.props,小程序中通过data.__props访问 + __props = {} + __isReady = false + // 会在componentDidMount后置为true + __mounted = false + _dirty = true + _disable = true + _pendingStates = [] + _pendingCallbacks = [] + $componentType = '' + $router = { + params: {}, + path: '' + } + + constructor (props = {}, isPage) { + this.state = {} + this.props = {} + this.$componentType = isPage ? 'PAGE' : 'COMPONENT' + this.isTaroComponent = this.$componentType && this.$router && this._pendingStates + } + _constructor (props) { + this.props = props || {} + } + _init (scope) { + this.$scope = scope + } + setState (state, callback) { + + } + + getState () { + const { _pendingStates, state, props } = this + const stateClone = Object.assign({}, state) + delete stateClone.__data + if (!_pendingStates.length) { + return stateClone + } + const queue = _pendingStates.concat() + this._pendingStates.length = 0 + queue.forEach((nextState) => { + if (typeof nextState === 'function') { + nextState = nextState.call(this, stateClone, props) + } + Object.assign(stateClone, nextState) + }) + return stateClone + } + + forceUpdate (callback) { + if (typeof callback === 'function') { + (this._pendingCallbacks = this._pendingCallbacks || []).push(callback) + } + } + + // 会被匿名函数调用 + __triggerPropsFn (key, args) { + const keyChain = key.split('.') + const reduxFnPrefix = '__event_' + const reduxFnName = reduxFnPrefix + keyChain.shift() + // redux标识过的方法,直接调用 + if (reduxFnName in this) { + const scope = args.shift() + let fn + if (keyChain.length > 0) { + fn = safeGet(this[reduxFnName], keyChain.join('.')) + } else { + fn = this[reduxFnName] + } + fn.apply(scope, args) + } else { + // 普通的 + const keyLower = key.toLocaleLowerCase() + this.$scope.triggerEvent(keyLower, { + __isCustomEvt: true, + __arguments: args + }) + } + } +} diff --git a/packages/taro-quickapp/src/create-app.js b/packages/taro-quickapp/src/create-app.js new file mode 100644 index 000000000000..6e7e99351582 --- /dev/null +++ b/packages/taro-quickapp/src/create-app.js @@ -0,0 +1,26 @@ +function createApp (AppClass) { + const app = new AppClass() + const appConf = { + onCreate (options) { + app.$app = this + app.$app.$router = app.$router = { + params: options + } + if (app.componentWillMount) { + app.componentWillMount() + } + if (app.componentDidMount) { + app.componentDidMount() + } + }, + + onDestroy () { + if (app.componentWillUnmount) { + app.componentWillUnmount() + } + } + } + return Object.assign(appConf, app) +} + +export default createApp diff --git a/packages/taro-quickapp/src/create-component.js b/packages/taro-quickapp/src/create-component.js new file mode 100644 index 000000000000..5eb23c89978a --- /dev/null +++ b/packages/taro-quickapp/src/create-component.js @@ -0,0 +1,3 @@ +export default function createComponent (ComponentClass, isPage) { + +} diff --git a/packages/taro-quickapp/src/index.js b/packages/taro-quickapp/src/index.js new file mode 100644 index 000000000000..ef1b9fe07edf --- /dev/null +++ b/packages/taro-quickapp/src/index.js @@ -0,0 +1,39 @@ +/* eslint-disable camelcase */ +import { + getEnv, + Events, + eventCenter, + ENV_TYPE, + render, + internal_safe_get, + internal_safe_set, + internal_inline_style, + internal_get_original +} from '@tarojs/taro' + +import Component from './component' +import PureComponent from './pure-component' +import createApp from './create-app' +import createComponent from './create-component' +import initNativeApi from './native-api' + +export const Taro = { + Component, + PureComponent, + createApp, + initNativeApi, + Events, + eventCenter, + getEnv, + render, + ENV_TYPE, + internal_safe_get, + internal_safe_set, + internal_inline_style, + createComponent, + internal_get_original +} + +export default Taro + +initNativeApi(Taro) diff --git a/packages/taro-qapp/src/native-api.js b/packages/taro-quickapp/src/native-api.js similarity index 100% rename from packages/taro-qapp/src/native-api.js rename to packages/taro-quickapp/src/native-api.js diff --git a/packages/taro-quickapp/src/pure-component.js b/packages/taro-quickapp/src/pure-component.js new file mode 100644 index 000000000000..5aea70022c69 --- /dev/null +++ b/packages/taro-quickapp/src/pure-component.js @@ -0,0 +1,13 @@ +import { shallowEqual } from '@tarojs/utils' + +import Component from './component' + +class PureComponent extends Component { + isPureComponent = true + + shouldComponentUpdate (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState) + } +} + +export default PureComponent From 7a08f0c2d9ce7b99faea32a189b529dc11d14a2f Mon Sep 17 00:00:00 2001 From: luckyadam Date: Thu, 14 Mar 2019 16:40:10 +0800 Subject: [PATCH 039/126] =?UTF-8?q?feat:=20=E5=BF=AB=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/build.ts | 2 +- packages/taro-cli/src/mini/astProcess.ts | 43 +- packages/taro-cli/src/mini/compileScript.ts | 10 +- packages/taro-cli/src/mini/entry.ts | 89 ++-- packages/taro-cli/src/mini/helper.ts | 3 +- packages/taro-cli/src/mini/index.ts | 6 +- packages/taro-cli/src/quick/astProcess.ts | 492 +++++++++++++++++- packages/taro-cli/src/quick/entry.ts | 8 +- packages/taro-cli/src/quick/helper.ts | 18 +- packages/taro-cli/src/quick/interface.ts | 6 + packages/taro-cli/src/util/constants.ts | 18 +- packages/taro-cli/src/util/index.ts | 33 +- packages/taro-cli/src/util/npm.ts | 23 +- .../taro-cli/src/util/resolve_npm_files.ts | 6 +- .../components/{button.js => button}/img.js | 0 .../components/{button.js => button}/index.ux | 0 16 files changed, 674 insertions(+), 83 deletions(-) rename packages/taro-components-qa/src/components/{button.js => button}/img.js (100%) rename packages/taro-components-qa/src/components/{button.js => button}/index.ux (100%) diff --git a/packages/taro-cli/src/build.ts b/packages/taro-cli/src/build.ts index 1454299f85ff..614ffbead5fa 100644 --- a/packages/taro-cli/src/build.ts +++ b/packages/taro-cli/src/build.ts @@ -94,7 +94,7 @@ function buildForRN ({ watch }: IBuildConfig) { } function buildForQuickApp ({ watch }: IBuildConfig) { - require('./quick').build({ + require('./mini').build({ watch, adapter: BUILD_TYPES.QUICKAPP }) diff --git a/packages/taro-cli/src/mini/astProcess.ts b/packages/taro-cli/src/mini/astProcess.ts index dc0bdc70890d..73622607417f 100644 --- a/packages/taro-cli/src/mini/astProcess.ts +++ b/packages/taro-cli/src/mini/astProcess.ts @@ -26,7 +26,8 @@ import { taroJsComponents, taroJsRedux, taroJsFramework, - DEVICE_RATIO_NAME + DEVICE_RATIO_NAME, + taroJsQuickAppComponents } from '../util/constants' import { resolveScriptPath, @@ -35,7 +36,8 @@ import { isNpmPkg, isAliasPath, replaceAliasPath, - traverseObjectNode + traverseObjectNode, + isQuickAppPkg } from '../util' import { convertObjectToAstExpression, convertArrayToAstExpression } from '../util/astConvert' import babylonConfig from '../config/babylon' @@ -243,9 +245,14 @@ export function parseAst ( let taroImportDefaultName let needExportDefault = false let exportTaroReduxConnected: string | null = null + const isQuickApp = buildAdapter === BUILD_TYPES.QUICKAPP + const cannotRemoves = [taroJsFramework, 'react', 'nervjs'] + if (isQuickApp) { + cannotRemoves.push(taroJsComponents) + } ast = babel.transformFromAst(ast, '', { plugins: [ - [require('babel-plugin-danger-remove-unused-import'), { ignore: ['@tarojs/taro', 'react', 'nervjs'] }], + [require('babel-plugin-danger-remove-unused-import'), { ignore: cannotRemoves }], [require('babel-plugin-transform-define').default, constantsReplaceList] ] }).ast as t.File @@ -375,8 +382,11 @@ export function parseAst ( value = replaceAliasPath(sourceFilePath, value, pathAlias) source.value = value } - if (isNpmPkg(value) && !notExistNpmList.has(value)) { + if (isNpmPkg(value) && !isQuickAppPkg(value) && !notExistNpmList.has(value)) { if (value === taroJsComponents) { + if (isQuickApp) { + console.log(specifiers) + } astPath.remove() } else { let isDepComponent = false @@ -460,9 +470,14 @@ export function parseAst ( value = replaceAliasPath(sourceFilePath, value, pathAlias) args[0].value = value } - if (isNpmPkg(value) && !notExistNpmList.has(value)) { + if (isNpmPkg(value) && !isQuickAppPkg(value) && !notExistNpmList.has(value)) { if (value === taroJsComponents) { - astPath.remove() + if (buildAdapter === BUILD_TYPES.QUICKAPP) { + args[0].value = taroJsQuickAppComponents + value = taroJsQuickAppComponents + } else { + astPath.remove() + } } else { let isDepComponent = false if (depComponents && depComponents.length) { @@ -720,7 +735,7 @@ export function parseAst ( }) const node = astPath.node as t.Program const exportVariableName = exportTaroReduxConnected || componentClassName - if (needExportDefault) { + if (needExportDefault && buildAdapter !== BUILD_TYPES.QUICKAPP) { const exportDefault = template(`export default ${exportVariableName}`, babylonConfig as any)() node.body.push(exportDefault as any) } @@ -741,18 +756,28 @@ export function parseAst ( if (projectConfig.hasOwnProperty(DEVICE_RATIO_NAME)) { pxTransformConfig[DEVICE_RATIO_NAME] = projectConfig.deviceRatio } - node.body.push(template(`App(require('${taroMiniAppFrameworkPath}').default.createApp(${exportVariableName}))`, babylonConfig as any)() as any) + if (buildAdapter === BUILD_TYPES.QUICKAPP) { + node.body.push(template(`export default require('${taroMiniAppFrameworkPath}').default.createApp(${exportVariableName})`, babylonConfig as any)() as any) + } else { + node.body.push(template(`App(require('${taroMiniAppFrameworkPath}').default.createApp(${exportVariableName}))`, babylonConfig as any)() as any) + } node.body.push(template(`Taro.initPxTransform(${JSON.stringify(pxTransformConfig)})`, babylonConfig as any)() as any) break case PARSE_AST_TYPE.PAGE: if (buildAdapter === BUILD_TYPES.WEAPP) { node.body.push(template(`Component(require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}, true))`, babylonConfig as any)() as any) + } else if (buildAdapter === BUILD_TYPES.QUICKAPP) { + node.body.push(template(`export default require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}, true)`, babylonConfig as any)() as any) } else { node.body.push(template(`Page(require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}, true))`, babylonConfig as any)() as any) } break case PARSE_AST_TYPE.COMPONENT: - node.body.push(template(`Component(require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}))`, babylonConfig as any)() as any) + if (buildAdapter === BUILD_TYPES.QUICKAPP) { + node.body.push(template(`export default require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName})`, babylonConfig as any)() as any) + } else { + node.body.push(template(`Component(require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}))`, babylonConfig as any)() as any) + } break default: break diff --git a/packages/taro-cli/src/mini/compileScript.ts b/packages/taro-cli/src/mini/compileScript.ts index 32e1f94b3828..dc717a665735 100644 --- a/packages/taro-cli/src/mini/compileScript.ts +++ b/packages/taro-cli/src/mini/compileScript.ts @@ -35,7 +35,7 @@ export function initCompileScripts () { isBuildingScripts.clear() } -export function compileDepScripts (scriptFiles: string[], buildDepSync?: boolean) { +export function compileDepScripts (scriptFiles: string[], needUseBabel?: boolean, buildDepSync?: boolean) { const { nodeModulesPath, npmOutputDir, @@ -88,7 +88,9 @@ export function compileDepScripts (scriptFiles: string[], buildDepSync?: boolean const res = parseAst(PARSE_AST_TYPE.NORMAL, ast, [], item, outputItem) const fileDep = dependencyTree.get(item) || {} as IDependency let resCode = res.code - resCode = await compileScriptFile(res.code, item, outputItem, buildAdapter) + if (needUseBabel) { + resCode = await compileScriptFile(res.code, item, outputItem, buildAdapter) + } fs.ensureDirSync(path.dirname(outputItem)) if (isProduction) { uglifyJS(resCode, item) @@ -100,9 +102,9 @@ export function compileDepScripts (scriptFiles: string[], buildDepSync?: boolean // 编译依赖的脚本文件 if (isDifferentArray(fileDep['script'], res.scriptFiles)) { if (buildDepSync) { - await Promise.all(compileDepScripts(res.scriptFiles, buildDepSync)) + await Promise.all(compileDepScripts(res.scriptFiles, needUseBabel, buildDepSync)) } else { - compileDepScripts(res.scriptFiles, buildDepSync) + compileDepScripts(res.scriptFiles, needUseBabel, buildDepSync) } } // 拷贝依赖文件 diff --git a/packages/taro-cli/src/mini/entry.ts b/packages/taro-cli/src/mini/entry.ts index 0991d605e2e7..b04fb46d2088 100644 --- a/packages/taro-cli/src/mini/entry.ts +++ b/packages/taro-cli/src/mini/entry.ts @@ -9,13 +9,16 @@ import { REG_TYPESCRIPT, CONFIG_MAP, processTypeEnum, - PARSE_AST_TYPE + PARSE_AST_TYPE, + BUILD_TYPES } from '../util/constants' import { isDifferentArray, printLog, isEmptyObject, - resolveScriptPath + resolveScriptPath, + promoteRelativePath, + generateQuickAppUx } from '../util' import { IWxTransformResult } from '../util/types' @@ -109,21 +112,11 @@ export async function buildEntry (): Promise { // app.js的template忽略 const res = parseAst(PARSE_AST_TYPE.ENTRY, transformResult.ast, [], entryFilePath, outputEntryFilePath) let resCode = res.code - resCode = await compileScriptFile(resCode, entryFilePath, outputEntryFilePath, buildAdapter) - if (isProduction) { - resCode = uglifyJS(resCode, entryFilePath) - } - if (appOutput) { - fs.writeFileSync(path.join(outputDir, 'app.json'), JSON.stringify(res.configObj, null, 2)) - printLog(processTypeEnum.GENERATE, '入口配置', `${outputDirName}/app.json`) - fs.writeFileSync(path.join(outputDir, 'app.js'), resCode) - printLog(processTypeEnum.GENERATE, '入口文件', `${outputDirName}/app.js`) - } - if (res.configObj.workers) { - buildWorkers(res.configObj.workers) - } - if (res.configObj.tabBar && res.configObj.tabBar.custom) { - await buildCustomTabbar() + if (buildAdapter !== BUILD_TYPES.QUICKAPP) { + resCode = await compileScriptFile(resCode, entryFilePath, outputEntryFilePath, buildAdapter) + if (isProduction) { + resCode = uglifyJS(resCode, entryFilePath) + } } const dependencyTree = getDependencyTree() const fileDep = dependencyTree.get(entryFilePath) || { @@ -134,7 +127,7 @@ export async function buildEntry (): Promise { } // 编译依赖的脚本文件 if (isDifferentArray(fileDep['script'], res.scriptFiles)) { - compileDepScripts(res.scriptFiles) + compileDepScripts(res.scriptFiles, buildAdapter !== BUILD_TYPES.QUICKAPP) } // 编译样式文件 if (isDifferentArray(fileDep['style'], res.styleFiles) && appOutput) { @@ -146,25 +139,6 @@ export async function buildEntry (): Promise { copyFilesFromSrcToOutput(res.jsonFiles) } - // 处理res.configObj 中的tabBar配置 - const tabBar = res.configObj.tabBar - if (tabBar && typeof tabBar === 'object' && !isEmptyObject(tabBar)) { - const { - list: listConfig, - iconPath: pathConfig, - selectedIconPath: selectedPathConfig - } = CONFIG_MAP[buildAdapter] - const list = tabBar[listConfig] || [] - let tabBarIcons: string[] = [] - list.forEach(item => { - item[pathConfig] && tabBarIcons.push(item[pathConfig]) - item[selectedPathConfig] && tabBarIcons.push(item[selectedPathConfig]) - }) - tabBarIcons = tabBarIcons.map(item => path.resolve(sourceDir, item)) - if (tabBarIcons && tabBarIcons.length) { - res.mediaFiles = res.mediaFiles.concat(tabBarIcons) - } - } if (isDifferentArray(fileDep['media'], res.mediaFiles)) { copyFilesFromSrcToOutput(res.mediaFiles) } @@ -173,6 +147,47 @@ export async function buildEntry (): Promise { fileDep['json'] = res.jsonFiles fileDep['media'] = res.mediaFiles dependencyTree.set(entryFilePath, fileDep) + if (buildAdapter === BUILD_TYPES.QUICKAPP) { + // 生成 快应用 ux 文件 + const styleRelativePath = promoteRelativePath(path.relative(outputEntryFilePath, path.join(outputDir, `app${outputFilesTypes.STYLE}`))) + const uxTxt = generateQuickAppUx({ + script: resCode, + style: styleRelativePath + }) + fs.writeFileSync(path.join(outputDir, `app${outputFilesTypes.TEMPL}`), uxTxt) + } else { + if (res.configObj.workers) { + buildWorkers(res.configObj.workers) + } + if (res.configObj.tabBar && res.configObj.tabBar.custom) { + await buildCustomTabbar() + } + // 处理res.configObj 中的tabBar配置 + const tabBar = res.configObj.tabBar + if (tabBar && typeof tabBar === 'object' && !isEmptyObject(tabBar)) { + const { + list: listConfig, + iconPath: pathConfig, + selectedIconPath: selectedPathConfig + } = CONFIG_MAP[buildAdapter] + const list = tabBar[listConfig] || [] + let tabBarIcons: string[] = [] + list.forEach(item => { + item[pathConfig] && tabBarIcons.push(item[pathConfig]) + item[selectedPathConfig] && tabBarIcons.push(item[selectedPathConfig]) + }) + tabBarIcons = tabBarIcons.map(item => path.resolve(sourceDir, item)) + if (tabBarIcons && tabBarIcons.length) { + res.mediaFiles = res.mediaFiles.concat(tabBarIcons) + } + } + if (appOutput) { + fs.writeFileSync(path.join(outputDir, 'app.json'), JSON.stringify(res.configObj, null, 2)) + printLog(processTypeEnum.GENERATE, '入口配置', `${outputDirName}/app.json`) + fs.writeFileSync(path.join(outputDir, 'app.js'), resCode) + printLog(processTypeEnum.GENERATE, '入口文件', `${outputDirName}/app.js`) + } + } return res.configObj } catch (err) { console.log(err) diff --git a/packages/taro-cli/src/mini/helper.ts b/packages/taro-cli/src/mini/helper.ts index c17f687f235d..237d30c90ac0 100644 --- a/packages/taro-cli/src/mini/helper.ts +++ b/packages/taro-cli/src/mini/helper.ts @@ -11,7 +11,8 @@ import { PROJECT_CONFIG, processTypeEnum, REG_SCRIPTS, - NODE_MODULES_REG + NODE_MODULES_REG, + REG_STYLE } from '../util/constants' import { resolveScriptPath, diff --git a/packages/taro-cli/src/mini/index.ts b/packages/taro-cli/src/mini/index.ts index 663e28357c06..2f80eeb26a88 100644 --- a/packages/taro-cli/src/mini/index.ts +++ b/packages/taro-cli/src/mini/index.ts @@ -111,7 +111,7 @@ export async function build ({ watch, adapter = BUILD_TYPES.WEAPP, envHasBeenSet const appConfig = await buildEntry() setAppConfig(appConfig) await buildPages() - if (watch) { - watchFiles() - } + // if (watch) { + // watchFiles() + // } } diff --git a/packages/taro-cli/src/quick/astProcess.ts b/packages/taro-cli/src/quick/astProcess.ts index 7069e4e3556f..5a10381b89d7 100644 --- a/packages/taro-cli/src/quick/astProcess.ts +++ b/packages/taro-cli/src/quick/astProcess.ts @@ -8,10 +8,175 @@ import traverse from 'babel-traverse' import _ from 'lodash' import { Config as IConfig } from '@tarojs/taro' -import { PARSE_AST_TYPE, taroJsComponents, taroJsQuickAppComponents } from '../util/constants' -import { getBuildData, isQuickAppPkg } from './helper' -import { getNotExistNpmList } from '../util/npmExact' -import { traverseObjectNode, isAliasPath, replaceAliasPath, isNpmPkg } from '../util' +const template = require('babel-template') + +import { + PARSE_AST_TYPE, + taroJsComponents, + taroJsQuickAppComponents, + taroJsFramework, + CSS_EXT, + processTypeEnum, + REG_SCRIPT, + REG_TYPESCRIPT, + REG_JSON, + REG_FONT, + REG_IMAGE, + REG_MEDIA, + NODE_MODULES_REG, + REG_STYLE, + taroJsRedux, + DEVICE_RATIO_NAME, + BUILD_TYPES +} from '../util/constants' +import babylonConfig from '../config/babylon' +import { getNotExistNpmList, getExactedNpmFilePath } from '../util/npmExact' +import { + traverseObjectNode, + isAliasPath, + replaceAliasPath, + isNpmPkg, + printLog, + resolveScriptPath, + promoteRelativePath +} from '../util' +import { convertArrayToAstExpression, convertObjectToAstExpression } from '../util/astConvert' +import { getBuildData, isQuickAppPkg, isFileToBePage } from './helper' + +interface IAnalyzeImportUrlOptions { + astPath: any, + value: string, + sourceFilePath: string, + filePath: string, + styleFiles: string[], + scriptFiles: string[], + jsonFiles: string[], + mediaFiles: string[] +} + +function analyzeImportUrl ({ + astPath, + value, + sourceFilePath, + filePath, + styleFiles, + scriptFiles, + jsonFiles, + mediaFiles +}: IAnalyzeImportUrlOptions): void { + const valueExtname = path.extname(value) + const node = astPath.node + const { + nodeModulesPath, + npmOutputDir, + sourceDir, + outputDir + } = getBuildData() + if (value.indexOf('.') === 0) { + let importPath = path.resolve(path.dirname(sourceFilePath), value) + importPath = resolveScriptPath(importPath) + if (isFileToBePage(importPath)) { + astPath.remove() + } else { + if (REG_SCRIPT.test(valueExtname) || REG_TYPESCRIPT.test(valueExtname)) { + const vpath = path.resolve(sourceFilePath, '..', value) + let fPath = value + if (fs.existsSync(vpath) && vpath !== sourceFilePath) { + fPath = vpath + } + if (scriptFiles.indexOf(fPath) < 0) { + scriptFiles.push(fPath) + } + } else if (REG_JSON.test(valueExtname)) { + const vpath = path.resolve(sourceFilePath, '..', value) + if (jsonFiles.indexOf(vpath) < 0) { + jsonFiles.push(vpath) + } + if (fs.existsSync(vpath)) { + const obj = JSON.parse(fs.readFileSync(vpath).toString()) + const specifiers = node.specifiers + let defaultSpecifier = null + specifiers.forEach(item => { + if (item.type === 'ImportDefaultSpecifier') { + defaultSpecifier = item.local.name + } + }) + if (defaultSpecifier) { + let objArr: t.NullLiteral | t.Expression = t.nullLiteral() + if (Array.isArray(obj)) { + objArr = t.arrayExpression(convertArrayToAstExpression(obj)) + } else { + objArr = t.objectExpression(convertObjectToAstExpression(obj)) + } + astPath.replaceWith(t.variableDeclaration('const', [t.variableDeclarator(t.identifier(defaultSpecifier), objArr)])) + } + } + } else if (REG_FONT.test(valueExtname) || REG_IMAGE.test(valueExtname) || REG_MEDIA.test(valueExtname)) { + const vpath = path.resolve(sourceFilePath, '..', value) + if (!fs.existsSync(vpath)) { + printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) + return + } + if (mediaFiles.indexOf(vpath) < 0) { + mediaFiles.push(vpath) + } + const specifiers = node.specifiers + let defaultSpecifier = null + specifiers.forEach(item => { + if (item.type === 'ImportDefaultSpecifier') { + defaultSpecifier = item.local.name + } + }) + let sourceDirPath = sourceDir + if (NODE_MODULES_REG.test(vpath)) { + sourceDirPath = nodeModulesPath + } + + if (defaultSpecifier) { + astPath.replaceWith(t.variableDeclaration('const', [t.variableDeclarator(t.identifier(defaultSpecifier), t.stringLiteral(vpath.replace(sourceDirPath, '').replace(/\\/g, '/')))])) + } else { + astPath.remove() + } + } else if (REG_STYLE.test(valueExtname)) { + const stylePath = path.resolve(path.dirname(sourceFilePath), value) + if (styleFiles.indexOf(stylePath) < 0) { + styleFiles.push(stylePath) + } + astPath.remove() + } else { + let vpath = resolveScriptPath(path.resolve(sourceFilePath, '..', value)) + let outputVpath + if (NODE_MODULES_REG.test(vpath)) { + outputVpath = vpath.replace(nodeModulesPath, npmOutputDir) + } else { + outputVpath = vpath.replace(sourceDir, outputDir) + } + let relativePath = path.relative(filePath, outputVpath) + if (vpath && vpath !== sourceFilePath) { + if (!fs.existsSync(vpath)) { + printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) + } else { + if (fs.lstatSync(vpath).isDirectory()) { + if (fs.existsSync(path.join(vpath, 'index.js'))) { + vpath = path.join(vpath, 'index.js') + relativePath = path.join(relativePath, 'index.js') + } else { + printLog(processTypeEnum.ERROR, '引用目录', `文件 ${sourceFilePath} 中引用了目录 ${value}!`) + return + } + } + if (scriptFiles.indexOf(vpath) < 0) { + scriptFiles.push(vpath) + } + relativePath = promoteRelativePath(relativePath) + relativePath = relativePath.replace(path.extname(relativePath), '.js') + node.source.value = relativePath + } + } + } + } + } +} export function parseAst ( type: PARSE_AST_TYPE, @@ -39,9 +204,12 @@ export function parseAst ( } = getBuildData() const notExistNpmList = getNotExistNpmList() const taroMiniAppFramework = `@tarojs/taro-${buildAdapter}` + let taroImportDefaultName let needExportDefault = false let configObj: IConfig = {} + let taroJsReduxConnect: string = '' let componentClassName: string = '' + let exportTaroReduxConnected: string | null = null ast = babel.transformFromAst(ast, '', { plugins: [ [require('babel-plugin-danger-remove-unused-import'), { ignore: ['@tarojs/taro', 'react', 'nervjs'] }], @@ -178,8 +346,324 @@ export function parseAst ( && !notExistNpmList.has(value)) { if (value === taroJsComponents) { source.value = taroJsQuickAppComponents + value = taroJsQuickAppComponents + } else if (value === taroJsFramework) { + let defaultSpecifier: string | null = null + specifiers.forEach(item => { + if (item.type === 'ImportDefaultSpecifier') { + defaultSpecifier = item.local.name + } + }) + if (defaultSpecifier) { + taroImportDefaultName = defaultSpecifier + } + value = taroMiniAppFramework + } else if (value === taroJsRedux) { + specifiers.forEach(item => { + if (item.type === 'ImportSpecifier') { + const local = item.local + if (local.type === 'Identifier' && local.name === 'connect') { + taroJsReduxConnect = item.imported.name + } + } + }) + } + if (!npmSkip) { + source.value = getExactedNpmFilePath({ + npmName: value, + filePath, + isProduction, + npmConfig, + buildAdapter, + npmOutputDir, + compileInclude: [] + }) + } else { + source.value = value } + } else if (CSS_EXT.indexOf(path.extname(value)) !== -1 && specifiers.length > 0) { // 对 使用 import style from './style.css' 语法引入的做转化处理 + } else if (path.isAbsolute(value)) { + printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 是绝对路径!`) + } + }, + + CallExpression (astPath) { + const node = astPath.node + const callee = node.callee as (t.Identifier | t.MemberExpression) + if (t.isMemberExpression(callee)) { + if (taroImportDefaultName && (callee.object as t.Identifier).name === taroImportDefaultName && (callee.property as t.Identifier).name === 'render') { + astPath.remove() + } + } else if (callee.name === 'require') { + const args = node.arguments as t.StringLiteral[] + let value = args[0].value + if (isAliasPath(value, pathAlias)) { + value = replaceAliasPath(sourceFilePath, value, pathAlias) + args[0].value = value + } + if (isNpmPkg(value) + && !isQuickAppPkg(value) + && !notExistNpmList.has(value)) { + if (value === taroJsComponents) { + args[0].value = taroJsQuickAppComponents + value = taroJsQuickAppComponents + } else if (t.isVariableDeclaration(astPath.parentPath.parentPath)) { + const parentNode = astPath.parentPath.parentPath.node as t.VariableDeclaration + if (parentNode.declarations.length === 1 && parentNode.declarations[0].init) { + const id = parentNode.declarations[0].id + if (value === taroJsFramework && id.type === 'Identifier') { + taroImportDefaultName = id.name + value = taroMiniAppFramework + } else if (value === taroJsRedux) { + const declarations = parentNode.declarations + declarations.forEach(item => { + const id = item.id + if (id.type === 'ObjectPattern') { + const properties = id.properties as any + properties.forEach(p => { + if (p.type === 'ObjectProperty') { + if (p.value.type === 'Identifier' && p.value.name === 'connect') { + taroJsReduxConnect = p.key.name + } + } + }) + } + }) + } + } + } + if (!npmSkip) { + args[0].value = getExactedNpmFilePath({ + npmName: value, + filePath, + isProduction, + npmConfig, + buildAdapter, + npmOutputDir, + compileInclude: [] + }) + } else { + args[0].value = value + } + } else if (CSS_EXT.indexOf(path.extname(value)) !== -1 && t.isVariableDeclarator(astPath.parentPath)) { // 对 使用 const style = require('./style.css') 语法引入的做转化处理 + + } else if (path.isAbsolute(value)) { + printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 是绝对路径!`) + } + } + }, + + ExportDefaultDeclaration (astPath) { + const node = astPath.node + const declaration = node.declaration + needExportDefault = false + if ( + declaration && + (declaration.type === 'ClassDeclaration' || declaration.type === 'ClassExpression') + ) { + const superClass = declaration.superClass + if (superClass) { + let hasCreateData = false + astPath.traverse({ + ClassMethod (astPath) { + if (astPath.get('key').isIdentifier({ name: '_createData' })) { + hasCreateData = true + } + } + }) + if (hasCreateData) { + needExportDefault = true + if (declaration.id === null) { + componentClassName = '_TaroComponentClass' + } else if (declaration.id.name === 'App') { + componentClassName = '_App' + } else { + componentClassName = declaration.id.name + } + const isClassDcl = declaration.type === 'ClassDeclaration' + const classDclProps = [t.identifier(componentClassName), superClass, declaration.body, declaration.decorators || []] + astPath.replaceWith(isClassDcl ? t.classDeclaration.apply(null, classDclProps) : t.classExpression.apply(null, classDclProps)) + } + } + } else if (declaration.type === 'CallExpression') { + const callee = declaration.callee + if (callee && callee.type === 'CallExpression') { + const subCallee = callee.callee + if (subCallee.type === 'Identifier' && subCallee.name === taroJsReduxConnect) { + const args = declaration.arguments as t.Identifier[] + if (args.length === 1 && args[0].name === componentClassName) { + needExportDefault = true + exportTaroReduxConnected = `${componentClassName}__Connected` + astPath.replaceWith(t.variableDeclaration('const', [t.variableDeclarator(t.identifier(`${componentClassName}__Connected`), t.callExpression(declaration.callee as t.Expression, declaration.arguments as Array))])) + } + } + } + } + }, + + ExportNamedDeclaration (astPath) { + const node = astPath.node + const source = node.source + if (source && source.type === 'StringLiteral') { + const value = source.value + analyzeImportUrl({ astPath, value, sourceFilePath, filePath, styleFiles, scriptFiles, jsonFiles, mediaFiles }) + } + }, + + ExportAllDeclaration (astPath) { + const node = astPath.node + const source = node.source + if (source && source.type === 'StringLiteral') { + const value = source.value + analyzeImportUrl({ astPath, value, sourceFilePath, filePath, styleFiles, scriptFiles, jsonFiles, mediaFiles }) + } + }, + Program: { + exit (astPath) { + astPath.traverse({ + ImportDeclaration (astPath) { + const node = astPath.node + const source = node.source + const value = source.value + analyzeImportUrl({ astPath, value, sourceFilePath, filePath, styleFiles, scriptFiles, jsonFiles, mediaFiles }) + }, + CallExpression (astPath) { + const node = astPath.node + const callee = node.callee as t.Identifier + if (callee.name === 'require') { + const args = node.arguments as t.StringLiteral[] + const value = args[0].value + const valueExtname = path.extname(value) + if (value.indexOf('.') === 0) { + let importPath = path.resolve(path.dirname(sourceFilePath), value) + importPath = resolveScriptPath(importPath) + if (isFileToBePage(importPath)) { + if (astPath.parent.type === 'AssignmentExpression' || 'ExpressionStatement') { + astPath.parentPath.remove() + } else if (astPath.parent.type === 'VariableDeclarator') { + astPath.parentPath.parentPath.remove() + } else { + astPath.remove() + } + } else { + if (REG_STYLE.test(valueExtname)) { + const stylePath = path.resolve(path.dirname(sourceFilePath), value) + if (styleFiles.indexOf(stylePath) < 0) { + styleFiles.push(stylePath) + } + if (astPath.parent.type === 'AssignmentExpression' || 'ExpressionStatement') { + astPath.parentPath.remove() + } else if (astPath.parent.type === 'VariableDeclarator') { + astPath.parentPath.parentPath.remove() + } else { + astPath.remove() + } + } else if (REG_JSON.test(valueExtname)) { + const vpath = path.resolve(sourceFilePath, '..', value) + if (jsonFiles.indexOf(vpath) < 0) { + jsonFiles.push(vpath) + } + if (fs.existsSync(vpath)) { + const obj = JSON.parse(fs.readFileSync(vpath).toString()) + let objArr: t.NullLiteral | t.Expression = t.nullLiteral() + if (Array.isArray(obj)) { + objArr = t.arrayExpression(convertArrayToAstExpression(obj)) + } else { + objArr = t.objectExpression(convertObjectToAstExpression(obj)) + } + astPath.replaceWith(t.objectExpression(objArr as any)) + } + } else if (REG_SCRIPT.test(valueExtname) || REG_TYPESCRIPT.test(valueExtname)) { + const vpath = path.resolve(sourceFilePath, '..', value) + let fPath = value + if (fs.existsSync(vpath) && vpath !== sourceFilePath) { + fPath = vpath + } + if (scriptFiles.indexOf(fPath) < 0) { + scriptFiles.push(fPath) + } + } else if (REG_FONT.test(valueExtname) || REG_IMAGE.test(valueExtname) || REG_MEDIA.test(valueExtname)) { + const vpath = path.resolve(sourceFilePath, '..', value) + if (mediaFiles.indexOf(vpath) < 0) { + mediaFiles.push(vpath) + } + let sourceDirPath = sourceDir + if (NODE_MODULES_REG.test(vpath)) { + sourceDirPath = nodeModulesPath + } + astPath.replaceWith(t.stringLiteral(vpath.replace(sourceDirPath, '').replace(/\\/g, '/'))) + } else { + let vpath = resolveScriptPath(path.resolve(sourceFilePath, '..', value)) + let outputVpath + if (NODE_MODULES_REG.test(vpath)) { + outputVpath = vpath.replace(nodeModulesPath, npmOutputDir) + } else { + outputVpath = vpath.replace(sourceDir, outputDir) + } + let relativePath = path.relative(filePath, outputVpath) + if (vpath) { + if (!fs.existsSync(vpath)) { + printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) + } else { + if (fs.lstatSync(vpath).isDirectory()) { + if (fs.existsSync(path.join(vpath, 'index.js'))) { + vpath = path.join(vpath, 'index.js') + relativePath = path.join(relativePath, 'index.js') + } else { + printLog(processTypeEnum.ERROR, '引用目录', `文件 ${sourceFilePath} 中引用了目录 ${value}!`) + return + } + } + if (scriptFiles.indexOf(vpath) < 0) { + scriptFiles.push(vpath) + } + relativePath = promoteRelativePath(relativePath) + relativePath = relativePath.replace(path.extname(relativePath), '.js') + args[0].value = relativePath + } + } + } + } + } + } + } + }) + const node = astPath.node as t.Program + const exportVariableName = exportTaroReduxConnected || componentClassName + if (needExportDefault) { + const exportDefault = template(`export default ${exportVariableName}`, babylonConfig as any)() + node.body.push(exportDefault as any) + } + const taroMiniAppFrameworkPath = !npmSkip ? getExactedNpmFilePath({ + npmName: taroMiniAppFramework, + filePath, + isProduction, + npmConfig, + buildAdapter, + npmOutputDir, + compileInclude: [] + }) : taroMiniAppFramework + switch (type) { + case PARSE_AST_TYPE.ENTRY: + const pxTransformConfig = { + designWidth: projectConfig.designWidth || 750 + } + if (projectConfig.hasOwnProperty(DEVICE_RATIO_NAME)) { + pxTransformConfig[DEVICE_RATIO_NAME] = projectConfig.deviceRatio + } + node.body.push(template(`export default require('${taroMiniAppFrameworkPath}').default.createApp(${exportVariableName})`, babylonConfig as any)() as any) + node.body.push(template(`Taro.initPxTransform(${JSON.stringify(pxTransformConfig)})`, babylonConfig as any)() as any) + break + case PARSE_AST_TYPE.PAGE: + node.body.push(template(`export default require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}, true)`, babylonConfig as any)() as any) + break + case PARSE_AST_TYPE.COMPONENT: + node.body.push(template(`export default require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName})`, babylonConfig as any)() as any) + break + default: + break + } } } }) diff --git a/packages/taro-cli/src/quick/entry.ts b/packages/taro-cli/src/quick/entry.ts index 151240a63bb0..4002e4516605 100644 --- a/packages/taro-cli/src/quick/entry.ts +++ b/packages/taro-cli/src/quick/entry.ts @@ -8,7 +8,7 @@ import { processTypeEnum, REG_TYPESCRIPT, PARSE_AST_TYPE } from '../util/constan import { printLog } from '../util' import { getBuildData, setAppConfig, getDependencyTree } from './helper' -import { parseAst } from './astProcess' +import { parseAst } from '../mini/astProcess' export async function buildEntry () { const { @@ -36,10 +36,10 @@ export async function buildEntry () { adapter: buildAdapter, env: constantsReplaceList }) - const { configObj, code } = parseAst(PARSE_AST_TYPE.ENTRY, transformResult.ast, entryFilePath, outputEntryFilePath) + const res = parseAst(PARSE_AST_TYPE.ENTRY, transformResult.ast, [], entryFilePath, outputEntryFilePath) const dependencyTree = getDependencyTree() - setAppConfig(configObj) - console.log(code) + setAppConfig(res.configObj) + console.log(res) } catch (err) { console.log(err) } diff --git a/packages/taro-cli/src/quick/helper.ts b/packages/taro-cli/src/quick/helper.ts index 41201f5c9b7a..0551389cf61a 100644 --- a/packages/taro-cli/src/quick/helper.ts +++ b/packages/taro-cli/src/quick/helper.ts @@ -5,7 +5,8 @@ import { AppConfig } from '@tarojs/taro' import { BUILD_TYPES, - PROJECT_CONFIG + PROJECT_CONFIG, + REG_SCRIPTS } from '../util/constants' import CONFIG from '../config' import { @@ -104,6 +105,17 @@ export function getDependencyTree (): Map { return dependencyTree } -export function isQuickAppPkg (name: string): boolean { - return /@system\./.test(name) +export function isFileToBePage (filePath: string): boolean { + let isPage = false + const { appConfig, sourceDir } = BuildData + const extname = path.extname(filePath) + const pages = appConfig.pages || [] + const filePathWithoutExt = filePath.replace(extname, '') + pages.forEach(page => { + if (filePathWithoutExt === path.join(sourceDir, page)) { + isPage = true + } + }) + return isPage && REG_SCRIPTS.test(extname) } + diff --git a/packages/taro-cli/src/quick/interface.ts b/packages/taro-cli/src/quick/interface.ts index db83f46215ee..8c9bd99c94b4 100644 --- a/packages/taro-cli/src/quick/interface.ts +++ b/packages/taro-cli/src/quick/interface.ts @@ -4,3 +4,9 @@ export interface IDependency { json: string[], media: string[] } + +export interface IComponentObj { + name?: string, + path: string | null, + type?: string +} diff --git a/packages/taro-cli/src/util/constants.ts b/packages/taro-cli/src/util/constants.ts index 90450b338f2e..749b72991c82 100644 --- a/packages/taro-cli/src/util/constants.ts +++ b/packages/taro-cli/src/util/constants.ts @@ -106,28 +106,32 @@ export const enum TEMPLATE_TYPES { WEAPP = '.wxml', SWAN = '.swan', ALIPAY = '.axml', - TT = '.ttml' + TT = '.ttml', + QUICKAPP = '.ux' } export const enum STYLE_TYPES { WEAPP = '.wxss', SWAN = '.css', ALIPAY = '.acss', - TT = '.ttss' + TT = '.ttss', + QUICKAPP = '.css' } export const enum SCRIPT_TYPES { WEAPP = '.js', SWAN = '.js', ALIPAY = '.js', - TT = '.js' + TT = '.js', + QUICKAPP = '.js' } export const enum CONFIG_TYPES { WEAPP = '.json', SWAN = '.json', ALIPAY = '.json', - TT = '.json' + TT = '.json', + QUICKAPP = '.json' } export type IMINI_APP_FILE_TYPE = { @@ -164,6 +168,12 @@ export const MINI_APP_FILES: IMINI_APP_FILES = { STYLE: STYLE_TYPES.TT, SCRIPT: SCRIPT_TYPES.TT, CONFIG: CONFIG_TYPES.TT + }, + [BUILD_TYPES.QUICKAPP]: { + TEMPL: TEMPLATE_TYPES.QUICKAPP, + STYLE: STYLE_TYPES.QUICKAPP, + SCRIPT: SCRIPT_TYPES.QUICKAPP, + CONFIG: CONFIG_TYPES.QUICKAPP } } diff --git a/packages/taro-cli/src/util/index.ts b/packages/taro-cli/src/util/index.ts index 72c2685f0d4d..42cfc93e77cd 100644 --- a/packages/taro-cli/src/util/index.ts +++ b/packages/taro-cli/src/util/index.ts @@ -17,7 +17,8 @@ import { processTypeEnum, MINI_APP_FILES, BUILD_TYPES, - CONFIG_MAP + CONFIG_MAP, + REG_STYLE } from './constants' import { ICopyArgOptions, ICopyOptions } from './types' @@ -498,3 +499,33 @@ export function copyFiles (appPath: string, copyConfig: ICopyOptions | void) { }) } } + +export function isQuickAppPkg (name: string): boolean { + return /@system\./.test(name) +} + +export function generateQuickAppUx ({ + script, + template, + style +}: { + script?: string, + template?: string, + style?: string +}) { + let uxTxt = '' + if (style) { + if (REG_STYLE.test(style)) { + uxTxt += `\n` + } else { + uxTxt += `\n` + } + } + if (template) { + uxTxt += `\n` + } + if (script) { + uxTxt += `\n` + } + return uxTxt +} diff --git a/packages/taro-cli/src/util/npm.ts b/packages/taro-cli/src/util/npm.ts index accb12051e75..96c5abaa6c17 100644 --- a/packages/taro-cli/src/util/npm.ts +++ b/packages/taro-cli/src/util/npm.ts @@ -43,17 +43,18 @@ export function resolveNpmSync (pluginName: string): string { } return npmCached[pluginName] } catch (err) { - if (err.code === 'MODULE_NOT_FOUND') { - console.log(chalk.cyan(`缺少npm包${pluginName},开始安装...`)) - const installOptions: IInstallOptions = { - dev: false - } - if (pluginName.indexOf(taroPluginPrefix) >= 0) { - installOptions.dev = true - } - installNpmPkg(pluginName, installOptions) - return resolveNpmSync(pluginName) - } + console.log(err) + // if (err.code === 'MODULE_NOT_FOUND') { + // console.log(chalk.cyan(`缺少npm包${pluginName},开始安装...`)) + // const installOptions: IInstallOptions = { + // dev: false + // } + // if (pluginName.indexOf(taroPluginPrefix) >= 0) { + // installOptions.dev = true + // } + // installNpmPkg(pluginName, installOptions) + // return resolveNpmSync(pluginName) + // } return '' } } diff --git a/packages/taro-cli/src/util/resolve_npm_files.ts b/packages/taro-cli/src/util/resolve_npm_files.ts index 0bba2c0698b0..39707027d8a7 100644 --- a/packages/taro-cli/src/util/resolve_npm_files.ts +++ b/packages/taro-cli/src/util/resolve_npm_files.ts @@ -13,7 +13,8 @@ import { promoteRelativePath, printLog, recursiveFindNodeModules, - generateEnvList + generateEnvList, + isQuickAppPkg } from './index' import { @@ -138,6 +139,9 @@ function parseAst ( const args = node.arguments as Array let requirePath = args[0].value if (excludeRequire.indexOf(requirePath) < 0) { + if (!isQuickAppPkg(requirePath)) { + return + } if (isNpmPkg(requirePath)) { if (excludeNpmPkgs.indexOf(requirePath) < 0) { const res = resolveNpmFilesPath(requirePath, isProduction, npmConfig, buildAdapter, path.dirname(recursiveFindNodeModules(filePath)), compileInclude) diff --git a/packages/taro-components-qa/src/components/button.js/img.js b/packages/taro-components-qa/src/components/button/img.js similarity index 100% rename from packages/taro-components-qa/src/components/button.js/img.js rename to packages/taro-components-qa/src/components/button/img.js diff --git a/packages/taro-components-qa/src/components/button.js/index.ux b/packages/taro-components-qa/src/components/button/index.ux similarity index 100% rename from packages/taro-components-qa/src/components/button.js/index.ux rename to packages/taro-components-qa/src/components/button/index.ux From 0be90c098eb98704d916ba74b447dd44d50d65b3 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Thu, 14 Mar 2019 21:41:18 +0800 Subject: [PATCH 040/126] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E5=BF=AB?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E5=85=A5=E5=8F=A3=E6=96=87=E4=BB=B6=E5=8F=8A?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E7=BC=96=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/mini/astProcess.ts | 36 +- packages/taro-cli/src/mini/entry.ts | 1 + packages/taro-cli/src/mini/page.ts | 146 +++-- packages/taro-cli/src/quick/astProcess.ts | 679 ---------------------- packages/taro-cli/src/quick/constants.ts | 1 - packages/taro-cli/src/quick/entry.ts | 46 -- packages/taro-cli/src/quick/helper.ts | 121 ---- packages/taro-cli/src/quick/index.ts | 22 - packages/taro-cli/src/quick/interface.ts | 12 - packages/taro-cli/src/util/index.ts | 28 +- 10 files changed, 140 insertions(+), 952 deletions(-) delete mode 100644 packages/taro-cli/src/quick/astProcess.ts delete mode 100644 packages/taro-cli/src/quick/constants.ts delete mode 100644 packages/taro-cli/src/quick/entry.ts delete mode 100644 packages/taro-cli/src/quick/helper.ts delete mode 100644 packages/taro-cli/src/quick/index.ts delete mode 100644 packages/taro-cli/src/quick/interface.ts diff --git a/packages/taro-cli/src/mini/astProcess.ts b/packages/taro-cli/src/mini/astProcess.ts index 73622607417f..38e9400f2b8c 100644 --- a/packages/taro-cli/src/mini/astProcess.ts +++ b/packages/taro-cli/src/mini/astProcess.ts @@ -5,7 +5,7 @@ import * as babel from 'babel-core' import * as t from 'babel-types' import generate from 'babel-generator' import traverse from 'babel-traverse' -import _ from 'lodash' +import * as _ from 'lodash' import { Config as IConfig } from '@tarojs/taro' const template = require('babel-template') @@ -26,8 +26,7 @@ import { taroJsComponents, taroJsRedux, taroJsFramework, - DEVICE_RATIO_NAME, - taroJsQuickAppComponents + DEVICE_RATIO_NAME } from '../util/constants' import { resolveScriptPath, @@ -208,7 +207,8 @@ export interface IParseAstReturn { jsonFiles: string[], mediaFiles: string[] configObj: IConfig, - componentClassName: string + componentClassName: string, + taroSelfComponents: Set } export function parseAst ( @@ -250,6 +250,7 @@ export function parseAst ( if (isQuickApp) { cannotRemoves.push(taroJsComponents) } + const taroSelfComponents = new Set() ast = babel.transformFromAst(ast, '', { plugins: [ [require('babel-plugin-danger-remove-unused-import'), { ignore: cannotRemoves }], @@ -385,7 +386,9 @@ export function parseAst ( if (isNpmPkg(value) && !isQuickAppPkg(value) && !notExistNpmList.has(value)) { if (value === taroJsComponents) { if (isQuickApp) { - console.log(specifiers) + specifiers.forEach(specifier => { + taroSelfComponents.add(_.kebabCase(specifier.local.name)) + }) } astPath.remove() } else { @@ -466,6 +469,7 @@ export function parseAst ( } else if (callee.name === 'require') { const args = node.arguments as t.StringLiteral[] let value = args[0].value + const parentNode = astPath.parentPath.parentPath.node as t.VariableDeclaration if (isAliasPath(value, pathAlias)) { value = replaceAliasPath(sourceFilePath, value, pathAlias) args[0].value = value @@ -473,11 +477,21 @@ export function parseAst ( if (isNpmPkg(value) && !isQuickAppPkg(value) && !notExistNpmList.has(value)) { if (value === taroJsComponents) { if (buildAdapter === BUILD_TYPES.QUICKAPP) { - args[0].value = taroJsQuickAppComponents - value = taroJsQuickAppComponents - } else { - astPath.remove() + if (isQuickApp) { + if (parentNode.declarations.length === 1 && parentNode.declarations[0].init) { + const id = parentNode.declarations[0].id + if (id.type === 'ObjectPattern') { + const properties = id.properties as any + properties.forEach(p => { + if (p.type === 'ObjectProperty' && p.value.type === 'Identifier') { + taroSelfComponents.add(_.kebabCase(p.value.name)) + } + }) + } + } + } } + astPath.remove() } else { let isDepComponent = false if (depComponents && depComponents.length) { @@ -491,7 +505,6 @@ export function parseAst ( astPath.remove() } else { if (t.isVariableDeclaration(astPath.parentPath.parentPath)) { - const parentNode = astPath.parentPath.parentPath.node as t.VariableDeclaration if (parentNode.declarations.length === 1 && parentNode.declarations[0].init) { const id = parentNode.declarations[0].id if (value === taroJsFramework && id.type === 'Identifier') { @@ -792,7 +805,8 @@ export function parseAst ( jsonFiles, configObj, mediaFiles, - componentClassName + componentClassName, + taroSelfComponents } } diff --git a/packages/taro-cli/src/mini/entry.ts b/packages/taro-cli/src/mini/entry.ts index b04fb46d2088..575cda3efb25 100644 --- a/packages/taro-cli/src/mini/entry.ts +++ b/packages/taro-cli/src/mini/entry.ts @@ -155,6 +155,7 @@ export async function buildEntry (): Promise { style: styleRelativePath }) fs.writeFileSync(path.join(outputDir, `app${outputFilesTypes.TEMPL}`), uxTxt) + printLog(processTypeEnum.GENERATE, '入口文件', `${outputDirName}/app${outputFilesTypes.TEMPL}`) } else { if (res.configObj.workers) { buildWorkers(res.configObj.workers) diff --git a/packages/taro-cli/src/mini/page.ts b/packages/taro-cli/src/mini/page.ts index 1d4f0dcfbf95..ff8b4a12b96d 100644 --- a/packages/taro-cli/src/mini/page.ts +++ b/packages/taro-cli/src/mini/page.ts @@ -10,7 +10,9 @@ import { processTypeEnum, NODE_MODULES_REG, PARSE_AST_TYPE, - taroJsFramework + taroJsFramework, + BUILD_TYPES, + taroJsQuickAppComponents } from '../util/constants' import { resolveScriptPath, @@ -18,7 +20,9 @@ import { isEmptyObject, promoteRelativePath, isDifferentArray, - copyFileSync + copyFileSync, + getInstalledNpmPkgPath, + generateQuickAppUx } from '../util' import { IWxTransformResult } from '../util/types' @@ -58,6 +62,7 @@ export async function buildSinglePage (page: string) { const pageJs = resolveScriptPath(pagePath) const dependencyTree = getDependencyTree() const depComponents = getDepComponents() + const isQuickApp = buildAdapter === BUILD_TYPES.QUICKAPP printLog(processTypeEnum.COMPILE, '页面文件', `${sourceDirName}/${page}`) if (!fs.existsSync(pageJs)) { @@ -102,11 +107,8 @@ export async function buildSinglePage (page: string) { const pageWXMLContent = isProduction ? transformResult.compressedTemplate : transformResult.template const res = parseAst(PARSE_AST_TYPE.PAGE, transformResult.ast, pageDepComponents, pageJs, outputPageJSPath) let resCode = res.code - resCode = await compileScriptFile(resCode, pageJs, outputPageJSPath, buildAdapter) - if (isProduction) { - uglifyJS(resCode, pageJs) - } fs.ensureDirSync(outputPagePath) + // 解析原生组件 const { usingComponents = {} }: IConfig = res.configObj if (usingComponents && !isEmptyObject(usingComponents)) { const keys = Object.keys(usingComponents) @@ -120,56 +122,18 @@ export async function buildSinglePage (page: string) { transfromNativeComponents(outputPageJSONPath.replace(outputDir, sourceDir), res.configObj) } const fileDep = dependencyTree.get(pageJs) || {} - // 编译依赖的组件文件 - let realComponentsPathList: IComponentObj[] = [] - if (pageDepComponents.length) { - realComponentsPathList = getRealComponentsPathList(pageJs, pageDepComponents) - res.scriptFiles = res.scriptFiles.map(item => { - for (let i = 0; i < realComponentsPathList.length; i++) { - const componentObj = realComponentsPathList[i] - const componentPath = componentObj.path - if (item === componentPath) { - return '' - } - } - return item - }).filter(item => item) - await buildDepComponents(realComponentsPathList) - } - const componentExportsMap = getComponentExportsMap() - if (!isEmptyObject(componentExportsMap) && realComponentsPathList.length) { - const mapKeys = Object.keys(componentExportsMap) - realComponentsPathList.forEach(component => { - if (mapKeys.indexOf(component.path as string) >= 0) { - const componentMap = componentExportsMap.get(component.path as string) - componentMap && componentMap.forEach(component => { - pageDepComponents.forEach(depComponent => { - if (depComponent.name === component.name) { - let componentPath = component.path - let realPath - if (NODE_MODULES_REG.test(componentPath as string)) { - componentPath = (componentPath as string).replace(nodeModulesPath, npmOutputDir) - realPath = promoteRelativePath(path.relative(outputPageJSPath, componentPath)) - } else { - realPath = promoteRelativePath(path.relative(pageJs, componentPath as string)) - } - depComponent.path = realPath.replace(path.extname(realPath), '') - } - }) - }) - } - }) + if (!isQuickApp) { + fs.writeFileSync(outputPageJSONPath, JSON.stringify(_.merge({}, buildUsingComponents(pageJs, pageDepComponents), res.configObj), null, 2)) + printLog(processTypeEnum.GENERATE, '页面配置', `${outputDirName}/${page}${outputFilesTypes.CONFIG}`) + fs.writeFileSync(outputPageJSPath, resCode) + printLog(processTypeEnum.GENERATE, '页面逻辑', `${outputDirName}/${page}${outputFilesTypes.SCRIPT}`) + fs.writeFileSync(outputPageWXMLPath, pageWXMLContent) + processNativeWxml(outputPageWXMLPath.replace(outputDir, sourceDir), pageWXMLContent, outputPageWXMLPath) + printLog(processTypeEnum.GENERATE, '页面模板', `${outputDirName}/${page}${outputFilesTypes.TEMPL}`) } - fs.writeFileSync(outputPageJSONPath, JSON.stringify(_.merge({}, buildUsingComponents(pageJs, pageDepComponents), res.configObj), null, 2)) - printLog(processTypeEnum.GENERATE, '页面配置', `${outputDirName}/${page}${outputFilesTypes.CONFIG}`) - fs.writeFileSync(outputPageJSPath, resCode) - printLog(processTypeEnum.GENERATE, '页面逻辑', `${outputDirName}/${page}${outputFilesTypes.SCRIPT}`) - fs.writeFileSync(outputPageWXMLPath, pageWXMLContent) - processNativeWxml(outputPageWXMLPath.replace(outputDir, sourceDir), pageWXMLContent, outputPageWXMLPath) - printLog(processTypeEnum.GENERATE, '页面模板', `${outputDirName}/${page}${outputFilesTypes.TEMPL}`) // 编译依赖的脚本文件 if (isDifferentArray(fileDep['script'], res.scriptFiles)) { - compileDepScripts(res.scriptFiles) + compileDepScripts(res.scriptFiles, buildAdapter !== BUILD_TYPES.QUICKAPP) } // 编译样式文件 if (isDifferentArray(fileDep['style'], res.styleFiles) || isDifferentArray(depComponents.get(pageJs) || [], pageDepComponents)) { @@ -183,12 +147,86 @@ export async function buildSinglePage (page: string) { if (isDifferentArray(fileDep['media'], res.mediaFiles)) { copyFilesFromSrcToOutput(res.mediaFiles) } - depComponents.set(pageJs, pageDepComponents) fileDep['style'] = res.styleFiles fileDep['script'] = res.scriptFiles fileDep['json'] = res.jsonFiles fileDep['media'] = res.mediaFiles dependencyTree[pageJs] = fileDep + if (!isQuickApp) { + resCode = await compileScriptFile(resCode, pageJs, outputPageJSPath, buildAdapter) + if (isProduction) { + uglifyJS(resCode, pageJs) + } + // 编译依赖的组件文件 + let realComponentsPathList: IComponentObj[] = [] + if (pageDepComponents.length) { + realComponentsPathList = getRealComponentsPathList(pageJs, pageDepComponents) + res.scriptFiles = res.scriptFiles.map(item => { + for (let i = 0; i < realComponentsPathList.length; i++) { + const componentObj = realComponentsPathList[i] + const componentPath = componentObj.path + if (item === componentPath) { + return '' + } + } + return item + }).filter(item => item) + await buildDepComponents(realComponentsPathList) + } + const componentExportsMap = getComponentExportsMap() + if (!isEmptyObject(componentExportsMap) && realComponentsPathList.length) { + const mapKeys = Object.keys(componentExportsMap) + realComponentsPathList.forEach(component => { + if (mapKeys.indexOf(component.path as string) >= 0) { + const componentMap = componentExportsMap.get(component.path as string) + componentMap && componentMap.forEach(component => { + pageDepComponents.forEach(depComponent => { + if (depComponent.name === component.name) { + let componentPath = component.path + let realPath + if (NODE_MODULES_REG.test(componentPath as string)) { + componentPath = (componentPath as string).replace(nodeModulesPath, npmOutputDir) + realPath = promoteRelativePath(path.relative(outputPageJSPath, componentPath)) + } else { + realPath = promoteRelativePath(path.relative(pageJs, componentPath as string)) + } + depComponent.path = realPath.replace(path.extname(realPath), '') + } + }) + }) + } + }) + } + depComponents.set(pageJs, pageDepComponents) + } else { + // 快应用编译,搜集创建页面 ux 文件 + const importTaroSelfComponents = new Set<{ path: string, name: string }>() + const taroJsQuickAppComponentsPkg = getInstalledNpmPkgPath(taroJsQuickAppComponents, nodeModulesPath) + if (!taroJsQuickAppComponentsPkg) { + printLog(processTypeEnum.ERROR, '包安装', `缺少包 ${taroJsQuickAppComponents},请安装!`) + process.exit(0) + } + const taroJsQuickAppComponentsPath = path.join(path.dirname(taroJsQuickAppComponentsPkg as string), 'src/components') + res.taroSelfComponents.forEach(c => { + const cPath = path.join(taroJsQuickAppComponentsPath, c, 'index') + const cRelativePath = promoteRelativePath(path.relative(outputPageJSPath, cPath.replace(nodeModulesPath, npmOutputDir))) + importTaroSelfComponents.add({ + path: cRelativePath, + name: c + }) + }) + // 快应用编译组件 + // TODO + const styleRelativePath = promoteRelativePath(path.relative(outputPageJSPath, outputPageWXSSPath)) + const uxTxt = generateQuickAppUx({ + script: resCode, + style: styleRelativePath, + imports: importTaroSelfComponents, + template: pageWXMLContent + }) + fs.writeFileSync(outputPageWXMLPath, uxTxt) + printLog(processTypeEnum.GENERATE, '页面文件', `${outputDirName}/${page}${outputFilesTypes.TEMPL}`) + } } catch (err) { printLog(processTypeEnum.ERROR, '页面编译', `页面${pagePath}编译失败!`) console.log(err) diff --git a/packages/taro-cli/src/quick/astProcess.ts b/packages/taro-cli/src/quick/astProcess.ts deleted file mode 100644 index 5a10381b89d7..000000000000 --- a/packages/taro-cli/src/quick/astProcess.ts +++ /dev/null @@ -1,679 +0,0 @@ -import * as fs from 'fs-extra' -import * as path from 'path' - -import * as babel from 'babel-core' -import * as t from 'babel-types' -import generate from 'babel-generator' -import traverse from 'babel-traverse' -import _ from 'lodash' -import { Config as IConfig } from '@tarojs/taro' - -const template = require('babel-template') - -import { - PARSE_AST_TYPE, - taroJsComponents, - taroJsQuickAppComponents, - taroJsFramework, - CSS_EXT, - processTypeEnum, - REG_SCRIPT, - REG_TYPESCRIPT, - REG_JSON, - REG_FONT, - REG_IMAGE, - REG_MEDIA, - NODE_MODULES_REG, - REG_STYLE, - taroJsRedux, - DEVICE_RATIO_NAME, - BUILD_TYPES -} from '../util/constants' -import babylonConfig from '../config/babylon' -import { getNotExistNpmList, getExactedNpmFilePath } from '../util/npmExact' -import { - traverseObjectNode, - isAliasPath, - replaceAliasPath, - isNpmPkg, - printLog, - resolveScriptPath, - promoteRelativePath -} from '../util' -import { convertArrayToAstExpression, convertObjectToAstExpression } from '../util/astConvert' -import { getBuildData, isQuickAppPkg, isFileToBePage } from './helper' - -interface IAnalyzeImportUrlOptions { - astPath: any, - value: string, - sourceFilePath: string, - filePath: string, - styleFiles: string[], - scriptFiles: string[], - jsonFiles: string[], - mediaFiles: string[] -} - -function analyzeImportUrl ({ - astPath, - value, - sourceFilePath, - filePath, - styleFiles, - scriptFiles, - jsonFiles, - mediaFiles -}: IAnalyzeImportUrlOptions): void { - const valueExtname = path.extname(value) - const node = astPath.node - const { - nodeModulesPath, - npmOutputDir, - sourceDir, - outputDir - } = getBuildData() - if (value.indexOf('.') === 0) { - let importPath = path.resolve(path.dirname(sourceFilePath), value) - importPath = resolveScriptPath(importPath) - if (isFileToBePage(importPath)) { - astPath.remove() - } else { - if (REG_SCRIPT.test(valueExtname) || REG_TYPESCRIPT.test(valueExtname)) { - const vpath = path.resolve(sourceFilePath, '..', value) - let fPath = value - if (fs.existsSync(vpath) && vpath !== sourceFilePath) { - fPath = vpath - } - if (scriptFiles.indexOf(fPath) < 0) { - scriptFiles.push(fPath) - } - } else if (REG_JSON.test(valueExtname)) { - const vpath = path.resolve(sourceFilePath, '..', value) - if (jsonFiles.indexOf(vpath) < 0) { - jsonFiles.push(vpath) - } - if (fs.existsSync(vpath)) { - const obj = JSON.parse(fs.readFileSync(vpath).toString()) - const specifiers = node.specifiers - let defaultSpecifier = null - specifiers.forEach(item => { - if (item.type === 'ImportDefaultSpecifier') { - defaultSpecifier = item.local.name - } - }) - if (defaultSpecifier) { - let objArr: t.NullLiteral | t.Expression = t.nullLiteral() - if (Array.isArray(obj)) { - objArr = t.arrayExpression(convertArrayToAstExpression(obj)) - } else { - objArr = t.objectExpression(convertObjectToAstExpression(obj)) - } - astPath.replaceWith(t.variableDeclaration('const', [t.variableDeclarator(t.identifier(defaultSpecifier), objArr)])) - } - } - } else if (REG_FONT.test(valueExtname) || REG_IMAGE.test(valueExtname) || REG_MEDIA.test(valueExtname)) { - const vpath = path.resolve(sourceFilePath, '..', value) - if (!fs.existsSync(vpath)) { - printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) - return - } - if (mediaFiles.indexOf(vpath) < 0) { - mediaFiles.push(vpath) - } - const specifiers = node.specifiers - let defaultSpecifier = null - specifiers.forEach(item => { - if (item.type === 'ImportDefaultSpecifier') { - defaultSpecifier = item.local.name - } - }) - let sourceDirPath = sourceDir - if (NODE_MODULES_REG.test(vpath)) { - sourceDirPath = nodeModulesPath - } - - if (defaultSpecifier) { - astPath.replaceWith(t.variableDeclaration('const', [t.variableDeclarator(t.identifier(defaultSpecifier), t.stringLiteral(vpath.replace(sourceDirPath, '').replace(/\\/g, '/')))])) - } else { - astPath.remove() - } - } else if (REG_STYLE.test(valueExtname)) { - const stylePath = path.resolve(path.dirname(sourceFilePath), value) - if (styleFiles.indexOf(stylePath) < 0) { - styleFiles.push(stylePath) - } - astPath.remove() - } else { - let vpath = resolveScriptPath(path.resolve(sourceFilePath, '..', value)) - let outputVpath - if (NODE_MODULES_REG.test(vpath)) { - outputVpath = vpath.replace(nodeModulesPath, npmOutputDir) - } else { - outputVpath = vpath.replace(sourceDir, outputDir) - } - let relativePath = path.relative(filePath, outputVpath) - if (vpath && vpath !== sourceFilePath) { - if (!fs.existsSync(vpath)) { - printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) - } else { - if (fs.lstatSync(vpath).isDirectory()) { - if (fs.existsSync(path.join(vpath, 'index.js'))) { - vpath = path.join(vpath, 'index.js') - relativePath = path.join(relativePath, 'index.js') - } else { - printLog(processTypeEnum.ERROR, '引用目录', `文件 ${sourceFilePath} 中引用了目录 ${value}!`) - return - } - } - if (scriptFiles.indexOf(vpath) < 0) { - scriptFiles.push(vpath) - } - relativePath = promoteRelativePath(relativePath) - relativePath = relativePath.replace(path.extname(relativePath), '.js') - node.source.value = relativePath - } - } - } - } - } -} - -export function parseAst ( - type: PARSE_AST_TYPE, - ast: t.File, - sourceFilePath: string, - filePath: string, - npmSkip: boolean = false -) { - const styleFiles: string[] = [] - const scriptFiles: string[] = [] - const jsonFiles: string[] = [] - const mediaFiles: string[] = [] - - const { - nodeModulesPath, - npmOutputDir, - sourceDir, - outputDir, - buildAdapter, - constantsReplaceList, - isProduction, - npmConfig, - alias: pathAlias, - projectConfig - } = getBuildData() - const notExistNpmList = getNotExistNpmList() - const taroMiniAppFramework = `@tarojs/taro-${buildAdapter}` - let taroImportDefaultName - let needExportDefault = false - let configObj: IConfig = {} - let taroJsReduxConnect: string = '' - let componentClassName: string = '' - let exportTaroReduxConnected: string | null = null - ast = babel.transformFromAst(ast, '', { - plugins: [ - [require('babel-plugin-danger-remove-unused-import'), { ignore: ['@tarojs/taro', 'react', 'nervjs'] }], - [require('babel-plugin-transform-define').default, constantsReplaceList] - ] - }).ast as t.File - traverse(ast, { - ClassDeclaration (astPath) { - const node = astPath.node - let hasCreateData = false - if (astPath.isProperty({ superClass: true })) { - astPath.traverse({ - ClassMethod (astPath) { - if (astPath.get('key').isIdentifier({ name: '_createData' })) { - hasCreateData = true - } - } - }) - if (hasCreateData) { - needExportDefault = true - astPath.traverse({ - ClassMethod (astPath) { - const node = astPath.node - if (node.kind === 'constructor') { - astPath.traverse({ - ExpressionStatement (astPath) { - const node = astPath.node - if (node.expression && - node.expression.type === 'AssignmentExpression' && - node.expression.operator === '=') { - const left = node.expression.left - if (left.type === 'MemberExpression' && - left.object.type === 'ThisExpression' && - left.property.type === 'Identifier' && - left.property.name === 'config') { - configObj = traverseObjectNode(node.expression.right, buildAdapter) - } - } - } - }) - } - } - }) - if (node.id === null) { - componentClassName = '_TaroComponentClass' - astPath.replaceWith( - t.classDeclaration( - t.identifier(componentClassName), - node.superClass as t.Expression, - node.body as t.ClassBody, - node.decorators as t.Decorator[] || [] - ) - ) - } else if (node.id.name === 'App') { - componentClassName = '_App' - astPath.replaceWith( - t.classDeclaration( - t.identifier(componentClassName), - node.superClass as t.Expression, - node.body as t.ClassBody, - node.decorators as t.Decorator[] || [] - ) - ) - } else { - componentClassName = node.id.name - } - } - } - }, - - ClassExpression (astPath) { - const node = astPath.node - if (node.superClass) { - let hasCreateData = false - astPath.traverse({ - ClassMethod (astPath) { - if (astPath.get('key').isIdentifier({ name: '_createData' })) { - hasCreateData = true - } - } - }) - if (hasCreateData) { - needExportDefault = true - if (node.id === null) { - const parentNode = astPath.parentPath.node as any - if (t.isVariableDeclarator(astPath.parentPath)) { - componentClassName = parentNode.id.name - } else { - componentClassName = '_TaroComponentClass' - } - astPath.replaceWith( - t.classExpression( - t.identifier(componentClassName), - node.superClass as t.Expression, - node.body as t.ClassBody, - node.decorators as t.Decorator[] || [] - ) - ) - } else if (node.id.name === 'App') { - componentClassName = '_App' - astPath.replaceWith( - t.classExpression( - t.identifier(componentClassName), - node.superClass as t.Expression, - node.body as t.ClassBody, - node.decorators as t.Decorator[] || [] - ) - ) - } else { - componentClassName = node.id.name - } - } - } - }, - - ClassProperty (astPath) { - const node = astPath.node - if (node.key.name === 'config') { - configObj = traverseObjectNode(node, buildAdapter) - } - }, - - ImportDeclaration (astPath) { - const node = astPath.node - const source = node.source - let value = source.value - const specifiers = node.specifiers - if (isAliasPath(value, pathAlias)) { - value = replaceAliasPath(sourceFilePath, value, pathAlias) - source.value = value - } - if (isNpmPkg(value) - && !isQuickAppPkg(value) - && !notExistNpmList.has(value)) { - if (value === taroJsComponents) { - source.value = taroJsQuickAppComponents - value = taroJsQuickAppComponents - } else if (value === taroJsFramework) { - let defaultSpecifier: string | null = null - specifiers.forEach(item => { - if (item.type === 'ImportDefaultSpecifier') { - defaultSpecifier = item.local.name - } - }) - if (defaultSpecifier) { - taroImportDefaultName = defaultSpecifier - } - value = taroMiniAppFramework - } else if (value === taroJsRedux) { - specifiers.forEach(item => { - if (item.type === 'ImportSpecifier') { - const local = item.local - if (local.type === 'Identifier' && local.name === 'connect') { - taroJsReduxConnect = item.imported.name - } - } - }) - } - if (!npmSkip) { - source.value = getExactedNpmFilePath({ - npmName: value, - filePath, - isProduction, - npmConfig, - buildAdapter, - npmOutputDir, - compileInclude: [] - }) - } else { - source.value = value - } - } else if (CSS_EXT.indexOf(path.extname(value)) !== -1 && specifiers.length > 0) { // 对 使用 import style from './style.css' 语法引入的做转化处理 - - } else if (path.isAbsolute(value)) { - printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 是绝对路径!`) - } - }, - - CallExpression (astPath) { - const node = astPath.node - const callee = node.callee as (t.Identifier | t.MemberExpression) - if (t.isMemberExpression(callee)) { - if (taroImportDefaultName && (callee.object as t.Identifier).name === taroImportDefaultName && (callee.property as t.Identifier).name === 'render') { - astPath.remove() - } - } else if (callee.name === 'require') { - const args = node.arguments as t.StringLiteral[] - let value = args[0].value - if (isAliasPath(value, pathAlias)) { - value = replaceAliasPath(sourceFilePath, value, pathAlias) - args[0].value = value - } - if (isNpmPkg(value) - && !isQuickAppPkg(value) - && !notExistNpmList.has(value)) { - if (value === taroJsComponents) { - args[0].value = taroJsQuickAppComponents - value = taroJsQuickAppComponents - } else if (t.isVariableDeclaration(astPath.parentPath.parentPath)) { - const parentNode = astPath.parentPath.parentPath.node as t.VariableDeclaration - if (parentNode.declarations.length === 1 && parentNode.declarations[0].init) { - const id = parentNode.declarations[0].id - if (value === taroJsFramework && id.type === 'Identifier') { - taroImportDefaultName = id.name - value = taroMiniAppFramework - } else if (value === taroJsRedux) { - const declarations = parentNode.declarations - declarations.forEach(item => { - const id = item.id - if (id.type === 'ObjectPattern') { - const properties = id.properties as any - properties.forEach(p => { - if (p.type === 'ObjectProperty') { - if (p.value.type === 'Identifier' && p.value.name === 'connect') { - taroJsReduxConnect = p.key.name - } - } - }) - } - }) - } - } - } - if (!npmSkip) { - args[0].value = getExactedNpmFilePath({ - npmName: value, - filePath, - isProduction, - npmConfig, - buildAdapter, - npmOutputDir, - compileInclude: [] - }) - } else { - args[0].value = value - } - } else if (CSS_EXT.indexOf(path.extname(value)) !== -1 && t.isVariableDeclarator(astPath.parentPath)) { // 对 使用 const style = require('./style.css') 语法引入的做转化处理 - - } else if (path.isAbsolute(value)) { - printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 是绝对路径!`) - } - } - }, - - ExportDefaultDeclaration (astPath) { - const node = astPath.node - const declaration = node.declaration - needExportDefault = false - if ( - declaration && - (declaration.type === 'ClassDeclaration' || declaration.type === 'ClassExpression') - ) { - const superClass = declaration.superClass - if (superClass) { - let hasCreateData = false - astPath.traverse({ - ClassMethod (astPath) { - if (astPath.get('key').isIdentifier({ name: '_createData' })) { - hasCreateData = true - } - } - }) - if (hasCreateData) { - needExportDefault = true - if (declaration.id === null) { - componentClassName = '_TaroComponentClass' - } else if (declaration.id.name === 'App') { - componentClassName = '_App' - } else { - componentClassName = declaration.id.name - } - const isClassDcl = declaration.type === 'ClassDeclaration' - const classDclProps = [t.identifier(componentClassName), superClass, declaration.body, declaration.decorators || []] - astPath.replaceWith(isClassDcl ? t.classDeclaration.apply(null, classDclProps) : t.classExpression.apply(null, classDclProps)) - } - } - } else if (declaration.type === 'CallExpression') { - const callee = declaration.callee - if (callee && callee.type === 'CallExpression') { - const subCallee = callee.callee - if (subCallee.type === 'Identifier' && subCallee.name === taroJsReduxConnect) { - const args = declaration.arguments as t.Identifier[] - if (args.length === 1 && args[0].name === componentClassName) { - needExportDefault = true - exportTaroReduxConnected = `${componentClassName}__Connected` - astPath.replaceWith(t.variableDeclaration('const', [t.variableDeclarator(t.identifier(`${componentClassName}__Connected`), t.callExpression(declaration.callee as t.Expression, declaration.arguments as Array))])) - } - } - } - } - }, - - ExportNamedDeclaration (astPath) { - const node = astPath.node - const source = node.source - if (source && source.type === 'StringLiteral') { - const value = source.value - analyzeImportUrl({ astPath, value, sourceFilePath, filePath, styleFiles, scriptFiles, jsonFiles, mediaFiles }) - } - }, - - ExportAllDeclaration (astPath) { - const node = astPath.node - const source = node.source - if (source && source.type === 'StringLiteral') { - const value = source.value - analyzeImportUrl({ astPath, value, sourceFilePath, filePath, styleFiles, scriptFiles, jsonFiles, mediaFiles }) - } - }, - Program: { - exit (astPath) { - astPath.traverse({ - ImportDeclaration (astPath) { - const node = astPath.node - const source = node.source - const value = source.value - analyzeImportUrl({ astPath, value, sourceFilePath, filePath, styleFiles, scriptFiles, jsonFiles, mediaFiles }) - }, - CallExpression (astPath) { - const node = astPath.node - const callee = node.callee as t.Identifier - if (callee.name === 'require') { - const args = node.arguments as t.StringLiteral[] - const value = args[0].value - const valueExtname = path.extname(value) - if (value.indexOf('.') === 0) { - let importPath = path.resolve(path.dirname(sourceFilePath), value) - importPath = resolveScriptPath(importPath) - if (isFileToBePage(importPath)) { - if (astPath.parent.type === 'AssignmentExpression' || 'ExpressionStatement') { - astPath.parentPath.remove() - } else if (astPath.parent.type === 'VariableDeclarator') { - astPath.parentPath.parentPath.remove() - } else { - astPath.remove() - } - } else { - if (REG_STYLE.test(valueExtname)) { - const stylePath = path.resolve(path.dirname(sourceFilePath), value) - if (styleFiles.indexOf(stylePath) < 0) { - styleFiles.push(stylePath) - } - if (astPath.parent.type === 'AssignmentExpression' || 'ExpressionStatement') { - astPath.parentPath.remove() - } else if (astPath.parent.type === 'VariableDeclarator') { - astPath.parentPath.parentPath.remove() - } else { - astPath.remove() - } - } else if (REG_JSON.test(valueExtname)) { - const vpath = path.resolve(sourceFilePath, '..', value) - if (jsonFiles.indexOf(vpath) < 0) { - jsonFiles.push(vpath) - } - if (fs.existsSync(vpath)) { - const obj = JSON.parse(fs.readFileSync(vpath).toString()) - let objArr: t.NullLiteral | t.Expression = t.nullLiteral() - if (Array.isArray(obj)) { - objArr = t.arrayExpression(convertArrayToAstExpression(obj)) - } else { - objArr = t.objectExpression(convertObjectToAstExpression(obj)) - } - astPath.replaceWith(t.objectExpression(objArr as any)) - } - } else if (REG_SCRIPT.test(valueExtname) || REG_TYPESCRIPT.test(valueExtname)) { - const vpath = path.resolve(sourceFilePath, '..', value) - let fPath = value - if (fs.existsSync(vpath) && vpath !== sourceFilePath) { - fPath = vpath - } - if (scriptFiles.indexOf(fPath) < 0) { - scriptFiles.push(fPath) - } - } else if (REG_FONT.test(valueExtname) || REG_IMAGE.test(valueExtname) || REG_MEDIA.test(valueExtname)) { - const vpath = path.resolve(sourceFilePath, '..', value) - if (mediaFiles.indexOf(vpath) < 0) { - mediaFiles.push(vpath) - } - let sourceDirPath = sourceDir - if (NODE_MODULES_REG.test(vpath)) { - sourceDirPath = nodeModulesPath - } - astPath.replaceWith(t.stringLiteral(vpath.replace(sourceDirPath, '').replace(/\\/g, '/'))) - } else { - let vpath = resolveScriptPath(path.resolve(sourceFilePath, '..', value)) - let outputVpath - if (NODE_MODULES_REG.test(vpath)) { - outputVpath = vpath.replace(nodeModulesPath, npmOutputDir) - } else { - outputVpath = vpath.replace(sourceDir, outputDir) - } - let relativePath = path.relative(filePath, outputVpath) - if (vpath) { - if (!fs.existsSync(vpath)) { - printLog(processTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 不存在!`) - } else { - if (fs.lstatSync(vpath).isDirectory()) { - if (fs.existsSync(path.join(vpath, 'index.js'))) { - vpath = path.join(vpath, 'index.js') - relativePath = path.join(relativePath, 'index.js') - } else { - printLog(processTypeEnum.ERROR, '引用目录', `文件 ${sourceFilePath} 中引用了目录 ${value}!`) - return - } - } - if (scriptFiles.indexOf(vpath) < 0) { - scriptFiles.push(vpath) - } - relativePath = promoteRelativePath(relativePath) - relativePath = relativePath.replace(path.extname(relativePath), '.js') - args[0].value = relativePath - } - } - } - } - } - } - } - }) - const node = astPath.node as t.Program - const exportVariableName = exportTaroReduxConnected || componentClassName - if (needExportDefault) { - const exportDefault = template(`export default ${exportVariableName}`, babylonConfig as any)() - node.body.push(exportDefault as any) - } - const taroMiniAppFrameworkPath = !npmSkip ? getExactedNpmFilePath({ - npmName: taroMiniAppFramework, - filePath, - isProduction, - npmConfig, - buildAdapter, - npmOutputDir, - compileInclude: [] - }) : taroMiniAppFramework - switch (type) { - case PARSE_AST_TYPE.ENTRY: - const pxTransformConfig = { - designWidth: projectConfig.designWidth || 750 - } - if (projectConfig.hasOwnProperty(DEVICE_RATIO_NAME)) { - pxTransformConfig[DEVICE_RATIO_NAME] = projectConfig.deviceRatio - } - node.body.push(template(`export default require('${taroMiniAppFrameworkPath}').default.createApp(${exportVariableName})`, babylonConfig as any)() as any) - node.body.push(template(`Taro.initPxTransform(${JSON.stringify(pxTransformConfig)})`, babylonConfig as any)() as any) - break - case PARSE_AST_TYPE.PAGE: - node.body.push(template(`export default require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}, true)`, babylonConfig as any)() as any) - break - case PARSE_AST_TYPE.COMPONENT: - node.body.push(template(`export default require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName})`, babylonConfig as any)() as any) - break - default: - break - } - } - } - }) - return { - code: generate(ast).code, - styleFiles, - scriptFiles, - jsonFiles, - configObj, - mediaFiles, - componentClassName - } -} diff --git a/packages/taro-cli/src/quick/constants.ts b/packages/taro-cli/src/quick/constants.ts deleted file mode 100644 index 8b137891791f..000000000000 --- a/packages/taro-cli/src/quick/constants.ts +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packages/taro-cli/src/quick/entry.ts b/packages/taro-cli/src/quick/entry.ts deleted file mode 100644 index 4002e4516605..000000000000 --- a/packages/taro-cli/src/quick/entry.ts +++ /dev/null @@ -1,46 +0,0 @@ -import * as fs from 'fs-extra' -import * as path from 'path' - -import * as wxTransformer from '@tarojs/transformer-wx' - -import { IWxTransformResult } from '../util/types' -import { processTypeEnum, REG_TYPESCRIPT, PARSE_AST_TYPE } from '../util/constants' -import { printLog } from '../util' - -import { getBuildData, setAppConfig, getDependencyTree } from './helper' -import { parseAst } from '../mini/astProcess' - -export async function buildEntry () { - const { - buildAdapter, - constantsReplaceList, - entryFilePath, - outputDir, - entryFileName, - sourceDirName, - projectConfig - } = getBuildData() - - const quickAppConf = projectConfig.quickApp - const entryFileCode = fs.readFileSync(entryFilePath).toString() - const outputEntryFilePath = path.join(outputDir, entryFileName) - - printLog(processTypeEnum.COMPILE, '入口文件', `${sourceDirName}/${entryFileName}`) - try { - const transformResult: IWxTransformResult = wxTransformer({ - code: entryFileCode, - sourcePath: entryFilePath, - outputPath: outputEntryFilePath, - isApp: true, - isTyped: REG_TYPESCRIPT.test(entryFilePath), - adapter: buildAdapter, - env: constantsReplaceList - }) - const res = parseAst(PARSE_AST_TYPE.ENTRY, transformResult.ast, [], entryFilePath, outputEntryFilePath) - const dependencyTree = getDependencyTree() - setAppConfig(res.configObj) - console.log(res) - } catch (err) { - console.log(err) - } -} diff --git a/packages/taro-cli/src/quick/helper.ts b/packages/taro-cli/src/quick/helper.ts deleted file mode 100644 index 0551389cf61a..000000000000 --- a/packages/taro-cli/src/quick/helper.ts +++ /dev/null @@ -1,121 +0,0 @@ -import * as path from 'path' - -import * as _ from 'lodash' -import { AppConfig } from '@tarojs/taro' - -import { - BUILD_TYPES, - PROJECT_CONFIG, - REG_SCRIPTS -} from '../util/constants' -import CONFIG from '../config' -import { - resolveScriptPath, - generateEnvList, - generateConstantsList -} from '../util' -import { IProjectConfig, INpmConfig, IOption } from '../util/types' -import { getNodeModulesPath, getNpmOutputDir } from '../util/npmExact' -import { IDependency } from './interface' - -const appPath = process.cwd() -const configDir = path.join(appPath, PROJECT_CONFIG) -const projectConfig = require(configDir)(_.merge) -const sourceDirName = projectConfig.sourceRoot || CONFIG.SOURCE_DIR -const outputDirName = projectConfig.outputRoot || CONFIG.OUTPUT_DIR -const sourceDir = path.join(appPath, sourceDirName) -const outputDir = path.join(appPath, outputDirName) -const entryFilePath = resolveScriptPath(path.join(sourceDir, CONFIG.ENTRY)) -const entryFileName = path.basename(entryFilePath) - -const pathAlias = projectConfig.alias || {} -const quickAppConf = projectConfig.quickApp || {} -const npmConfig = Object.assign({ - name: CONFIG.NPM_DIR, - dir: null -}, quickAppConf.npm) - -const minifestJSON = {} -const dependencyTree: Map = new Map() - -export interface IBuildData { - appPath: string, - configDir: string, - sourceDirName: string, - outputDirName: string, - sourceDir: string, - outputDir: string, - entryFilePath: string, - entryFileName: string, - projectConfig: IProjectConfig, - npmConfig: INpmConfig, - appConfig: AppConfig, - alias: IOption, - isProduction: boolean, - buildAdapter: BUILD_TYPES, - constantsReplaceList: IOption, - nodeModulesPath: string, - npmOutputDir: string -} - -const BuildData: IBuildData = { - appPath, - configDir, - sourceDirName, - outputDirName, - sourceDir, - outputDir, - entryFilePath, - entryFileName, - projectConfig, - npmConfig, - alias: pathAlias, - isProduction: false, - appConfig: {}, - buildAdapter: BUILD_TYPES.WEAPP, - constantsReplaceList: {}, - nodeModulesPath: getNodeModulesPath(), - npmOutputDir: getNpmOutputDir(outputDir, configDir, npmConfig) -} - -export function setAppConfig (appConfig: AppConfig) { - BuildData.appConfig = appConfig -} - -export function setIsProduction (isProduction: boolean) { - BuildData.isProduction = isProduction -} - -export function setBuildAdapter (adapter: BUILD_TYPES) { - BuildData.buildAdapter = adapter - BuildData.constantsReplaceList = Object.assign({}, generateEnvList(projectConfig.env || {}), generateConstantsList(projectConfig.defineConstants || {}), { - 'process.env.TARO_ENV': adapter - }) -} - -export function getBuildData (): IBuildData { - return BuildData -} - -export function setManifestJSON (key, value) { - minifestJSON[key] = value -} - -export function getDependencyTree (): Map { - return dependencyTree -} - -export function isFileToBePage (filePath: string): boolean { - let isPage = false - const { appConfig, sourceDir } = BuildData - const extname = path.extname(filePath) - const pages = appConfig.pages || [] - const filePathWithoutExt = filePath.replace(extname, '') - pages.forEach(page => { - if (filePathWithoutExt === path.join(sourceDir, page)) { - isPage = true - } - }) - return isPage && REG_SCRIPTS.test(extname) -} - diff --git a/packages/taro-cli/src/quick/index.ts b/packages/taro-cli/src/quick/index.ts deleted file mode 100644 index 69a02a8669eb..000000000000 --- a/packages/taro-cli/src/quick/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { BUILD_TYPES } from '../util/constants' -import { IMiniAppBuildConfig } from '../util/types' - -import { - getBuildData, - setIsProduction, - setBuildAdapter, - setAppConfig -} from './helper' -import { copyFiles } from '../util' - -import { buildEntry } from './entry' - -export async function build ({ watch, adapter = BUILD_TYPES.QUICKAPP }: IMiniAppBuildConfig) { - const { projectConfig, appPath } = getBuildData() - process.env.TARO_ENV = adapter - setIsProduction(process.env.NODE_ENV === 'production' || !watch) - setBuildAdapter(adapter) - copyFiles(appPath, projectConfig.copy) - const appConfig = await buildEntry() - // setAppConfig(appConfig) -} diff --git a/packages/taro-cli/src/quick/interface.ts b/packages/taro-cli/src/quick/interface.ts deleted file mode 100644 index 8c9bd99c94b4..000000000000 --- a/packages/taro-cli/src/quick/interface.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface IDependency { - style: string[], - script: string[], - json: string[], - media: string[] -} - -export interface IComponentObj { - name?: string, - path: string | null, - type?: string -} diff --git a/packages/taro-cli/src/util/index.ts b/packages/taro-cli/src/util/index.ts index 42cfc93e77cd..7d079dd529b3 100644 --- a/packages/taro-cli/src/util/index.ts +++ b/packages/taro-cli/src/util/index.ts @@ -399,17 +399,23 @@ export function recursiveFindNodeModules (filePath: string): string { export const pascalCase: (str: string) => string = (str: string): string => str.charAt(0).toUpperCase() + _.camelCase(str.substr(1)) -export function getInstalledNpmPkgVersion (pkgName: string, basedir: string): string | null { +export function getInstalledNpmPkgPath (pkgName: string, basedir: string): string | null { const resolvePath = require('resolve') try { - const pkg = resolvePath.sync(`${pkgName}/package.json`, { basedir }) - const pkgJson = fs.readJSONSync(pkg) - return pkgJson.version + return resolvePath.sync(`${pkgName}/package.json`, { basedir }) } catch (err) { return null } } +export function getInstalledNpmPkgVersion (pkgName: string, basedir: string): string | null { + const pkgPath = getInstalledNpmPkgPath(pkgName, basedir) + if (!pkgPath) { + return null + } + return fs.readJSONSync(pkgPath).version +} + export function traverseObjectNode (node, buildAdapter: string) { if (node.type === 'ClassProperty' || node.type === 'ObjectProperty') { const properties = node.value.properties @@ -507,13 +513,23 @@ export function isQuickAppPkg (name: string): boolean { export function generateQuickAppUx ({ script, template, - style + style, + imports }: { script?: string, template?: string, - style?: string + style?: string, + imports?: Set<{ + path: string, + name: string + }> }) { let uxTxt = '' + if (imports && imports.size) { + imports.forEach(item => { + uxTxt += `\n` + }) + } if (style) { if (REG_STYLE.test(style)) { uxTxt += `\n` From 2a6493d37a3d8fb1f8df4cd2b66a8ab6d04b90d6 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Thu, 14 Mar 2019 21:58:25 +0800 Subject: [PATCH 041/126] =?UTF-8?q?feat:=20=E7=BC=96=E8=AF=91=E5=BF=AB?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E9=A1=B5=E9=9D=A2=E6=97=B6=20copy=20?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E4=BE=9D=E8=B5=96=E7=9A=84=20taro=20?= =?UTF-8?q?=E5=86=85=E7=BD=AE=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/mini/page.ts | 7 +++++-- packages/taro-cli/src/util/npm.ts | 23 +++++++++++------------ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/taro-cli/src/mini/page.ts b/packages/taro-cli/src/mini/page.ts index ff8b4a12b96d..1246b3483c9a 100644 --- a/packages/taro-cli/src/mini/page.ts +++ b/packages/taro-cli/src/mini/page.ts @@ -208,8 +208,11 @@ export async function buildSinglePage (page: string) { } const taroJsQuickAppComponentsPath = path.join(path.dirname(taroJsQuickAppComponentsPkg as string), 'src/components') res.taroSelfComponents.forEach(c => { - const cPath = path.join(taroJsQuickAppComponentsPath, c, 'index') - const cRelativePath = promoteRelativePath(path.relative(outputPageJSPath, cPath.replace(nodeModulesPath, npmOutputDir))) + const cPath = path.join(taroJsQuickAppComponentsPath, c) + const cMainPath = path.join(cPath, 'index') + const cFiles = fs.readdirSync(cPath).map(item => path.join(cPath, item)) + copyFilesFromSrcToOutput(cFiles) + const cRelativePath = promoteRelativePath(path.relative(outputPageJSPath, cMainPath.replace(nodeModulesPath, npmOutputDir))) importTaroSelfComponents.add({ path: cRelativePath, name: c diff --git a/packages/taro-cli/src/util/npm.ts b/packages/taro-cli/src/util/npm.ts index 96c5abaa6c17..accb12051e75 100644 --- a/packages/taro-cli/src/util/npm.ts +++ b/packages/taro-cli/src/util/npm.ts @@ -43,18 +43,17 @@ export function resolveNpmSync (pluginName: string): string { } return npmCached[pluginName] } catch (err) { - console.log(err) - // if (err.code === 'MODULE_NOT_FOUND') { - // console.log(chalk.cyan(`缺少npm包${pluginName},开始安装...`)) - // const installOptions: IInstallOptions = { - // dev: false - // } - // if (pluginName.indexOf(taroPluginPrefix) >= 0) { - // installOptions.dev = true - // } - // installNpmPkg(pluginName, installOptions) - // return resolveNpmSync(pluginName) - // } + if (err.code === 'MODULE_NOT_FOUND') { + console.log(chalk.cyan(`缺少npm包${pluginName},开始安装...`)) + const installOptions: IInstallOptions = { + dev: false + } + if (pluginName.indexOf(taroPluginPrefix) >= 0) { + installOptions.dev = true + } + installNpmPkg(pluginName, installOptions) + return resolveNpmSync(pluginName) + } return '' } } From 73fb96d04fa0227082ce4ecb50aabc4d6b37a647 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Thu, 14 Mar 2019 22:02:58 +0800 Subject: [PATCH 042/126] =?UTF-8?q?feat:=20=E4=B8=BA=E4=BA=86=E9=81=BF?= =?UTF-8?q?=E5=85=8D=E5=BF=AB=E5=BA=94=E7=94=A8=E5=9F=BA=E7=A1=80=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E4=B8=8E=E5=8E=9F=E7=94=9F=E7=BB=84=E4=BB=B6=E5=90=8D?= =?UTF-8?q?=E5=86=B2=E7=AA=81=EF=BC=8C=E9=83=A8=E5=88=86=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20taro=20=E5=89=8D=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-components-qa/index.js | 1 + packages/taro-components-qa/package.json | 12 ++++++++++++ .../src/components/{rich_text => rich-text}/index.ux | 0 .../src/components/{camera => taro-camera}/index.ux | 0 .../src/components/{image => taro-image}/index.ux | 0 .../src/components/{input => taro-input}/index.ux | 0 .../src/components/{label => taro-label}/index.ux | 0 .../src/components/{picker => taro-picker}/index.ux | 0 .../components/{progress => taro-progress}/index.ux | 0 .../src/components/{slider => taro-slider}/index.ux | 0 .../src/components/{swiper => taro-swiper}/index.ux | 0 .../src/components/{switch => taro-switch}/index.ux | 0 .../src/components/{text => taro-text}/index.ux | 0 .../components/{textarea => taro-textarea}/index.ux | 0 .../src/components/{video => taro-video}/index.ux | 0 15 files changed, 13 insertions(+) create mode 100644 packages/taro-components-qa/index.js create mode 100644 packages/taro-components-qa/package.json rename packages/taro-components-qa/src/components/{rich_text => rich-text}/index.ux (100%) rename packages/taro-components-qa/src/components/{camera => taro-camera}/index.ux (100%) rename packages/taro-components-qa/src/components/{image => taro-image}/index.ux (100%) rename packages/taro-components-qa/src/components/{input => taro-input}/index.ux (100%) rename packages/taro-components-qa/src/components/{label => taro-label}/index.ux (100%) rename packages/taro-components-qa/src/components/{picker => taro-picker}/index.ux (100%) rename packages/taro-components-qa/src/components/{progress => taro-progress}/index.ux (100%) rename packages/taro-components-qa/src/components/{slider => taro-slider}/index.ux (100%) rename packages/taro-components-qa/src/components/{swiper => taro-swiper}/index.ux (100%) rename packages/taro-components-qa/src/components/{switch => taro-switch}/index.ux (100%) rename packages/taro-components-qa/src/components/{text => taro-text}/index.ux (100%) rename packages/taro-components-qa/src/components/{textarea => taro-textarea}/index.ux (100%) rename packages/taro-components-qa/src/components/{video => taro-video}/index.ux (100%) diff --git a/packages/taro-components-qa/index.js b/packages/taro-components-qa/index.js new file mode 100644 index 000000000000..9e362c0ef8a9 --- /dev/null +++ b/packages/taro-components-qa/index.js @@ -0,0 +1 @@ +// 空的占位文件 diff --git a/packages/taro-components-qa/package.json b/packages/taro-components-qa/package.json new file mode 100644 index 000000000000..6aafe86b8638 --- /dev/null +++ b/packages/taro-components-qa/package.json @@ -0,0 +1,12 @@ +{ + "name": "@tarojs/components-qa", + "version": "1.2.13", + "description": "多端解决方案基础组件(快应用)", + "main": "./index.js", + "files": [ + "src", + "index.js" + ], + "author": "O2Team", + "license": "MIT" +} diff --git a/packages/taro-components-qa/src/components/rich_text/index.ux b/packages/taro-components-qa/src/components/rich-text/index.ux similarity index 100% rename from packages/taro-components-qa/src/components/rich_text/index.ux rename to packages/taro-components-qa/src/components/rich-text/index.ux diff --git a/packages/taro-components-qa/src/components/camera/index.ux b/packages/taro-components-qa/src/components/taro-camera/index.ux similarity index 100% rename from packages/taro-components-qa/src/components/camera/index.ux rename to packages/taro-components-qa/src/components/taro-camera/index.ux diff --git a/packages/taro-components-qa/src/components/image/index.ux b/packages/taro-components-qa/src/components/taro-image/index.ux similarity index 100% rename from packages/taro-components-qa/src/components/image/index.ux rename to packages/taro-components-qa/src/components/taro-image/index.ux diff --git a/packages/taro-components-qa/src/components/input/index.ux b/packages/taro-components-qa/src/components/taro-input/index.ux similarity index 100% rename from packages/taro-components-qa/src/components/input/index.ux rename to packages/taro-components-qa/src/components/taro-input/index.ux diff --git a/packages/taro-components-qa/src/components/label/index.ux b/packages/taro-components-qa/src/components/taro-label/index.ux similarity index 100% rename from packages/taro-components-qa/src/components/label/index.ux rename to packages/taro-components-qa/src/components/taro-label/index.ux diff --git a/packages/taro-components-qa/src/components/picker/index.ux b/packages/taro-components-qa/src/components/taro-picker/index.ux similarity index 100% rename from packages/taro-components-qa/src/components/picker/index.ux rename to packages/taro-components-qa/src/components/taro-picker/index.ux diff --git a/packages/taro-components-qa/src/components/progress/index.ux b/packages/taro-components-qa/src/components/taro-progress/index.ux similarity index 100% rename from packages/taro-components-qa/src/components/progress/index.ux rename to packages/taro-components-qa/src/components/taro-progress/index.ux diff --git a/packages/taro-components-qa/src/components/slider/index.ux b/packages/taro-components-qa/src/components/taro-slider/index.ux similarity index 100% rename from packages/taro-components-qa/src/components/slider/index.ux rename to packages/taro-components-qa/src/components/taro-slider/index.ux diff --git a/packages/taro-components-qa/src/components/swiper/index.ux b/packages/taro-components-qa/src/components/taro-swiper/index.ux similarity index 100% rename from packages/taro-components-qa/src/components/swiper/index.ux rename to packages/taro-components-qa/src/components/taro-swiper/index.ux diff --git a/packages/taro-components-qa/src/components/switch/index.ux b/packages/taro-components-qa/src/components/taro-switch/index.ux similarity index 100% rename from packages/taro-components-qa/src/components/switch/index.ux rename to packages/taro-components-qa/src/components/taro-switch/index.ux diff --git a/packages/taro-components-qa/src/components/text/index.ux b/packages/taro-components-qa/src/components/taro-text/index.ux similarity index 100% rename from packages/taro-components-qa/src/components/text/index.ux rename to packages/taro-components-qa/src/components/taro-text/index.ux diff --git a/packages/taro-components-qa/src/components/textarea/index.ux b/packages/taro-components-qa/src/components/taro-textarea/index.ux similarity index 100% rename from packages/taro-components-qa/src/components/textarea/index.ux rename to packages/taro-components-qa/src/components/taro-textarea/index.ux diff --git a/packages/taro-components-qa/src/components/video/index.ux b/packages/taro-components-qa/src/components/taro-video/index.ux similarity index 100% rename from packages/taro-components-qa/src/components/video/index.ux rename to packages/taro-components-qa/src/components/taro-video/index.ux From 8f3a3c2c4db2b9d74a01d6aff381e5d6d3f8937d Mon Sep 17 00:00:00 2001 From: luckyadam Date: Fri, 15 Mar 2019 11:45:00 +0800 Subject: [PATCH 043/126] =?UTF-8?q?feat:=20=E7=BC=96=E8=AF=91=E5=BF=AB?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E4=BE=9D=E8=B5=96=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/mini/component.ts | 54 ++++++--- packages/taro-cli/src/mini/helper.ts | 31 ++++- packages/taro-cli/src/mini/page.ts | 143 +++++++++++------------- 3 files changed, 132 insertions(+), 96 deletions(-) diff --git a/packages/taro-cli/src/mini/component.ts b/packages/taro-cli/src/mini/component.ts index c899ffdf2dbd..472cbd10fc12 100644 --- a/packages/taro-cli/src/mini/component.ts +++ b/packages/taro-cli/src/mini/component.ts @@ -12,13 +12,17 @@ import { processTypeEnum, NODE_MODULES_REG, NODE_MODULES, - PARSE_AST_TYPE + PARSE_AST_TYPE, + BUILD_TYPES, + taroJsQuickAppComponents } from '../util/constants' import { printLog, isEmptyObject, promoteRelativePath, - isDifferentArray + isDifferentArray, + getInstalledNpmPkgPath, + generateQuickAppUx } from '../util' import { parseComponentExportAst, parseAst } from './astProcess' @@ -35,7 +39,8 @@ import { getComponentsBuildResult, getDependencyTree, buildUsingComponents, - getDepComponents + getDepComponents, + getImportTaroSelfComponents } from './helper' import { compileScriptFile, compileDepScripts } from './compileScript' import { compileDepStyles } from './compileStyle' @@ -142,6 +147,7 @@ export async function buildSingleComponent ( isProduction, jsxAttributeNameReplace } = getBuildData() + const isQuickApp = buildAdapter === BUILD_TYPES.QUICKAPP if (componentObj.path) { componentsNamedMap.set(componentObj.path, { @@ -225,11 +231,8 @@ export async function buildSingleComponent ( const componentDepComponents = transformResult.components const res = parseAst(PARSE_AST_TYPE.COMPONENT, transformResult.ast, componentDepComponents, component, outputComponentJSPath, buildConfig.npmSkip) let resCode = res.code - resCode = await compileScriptFile(resCode, component, outputComponentJSPath, buildAdapter) fs.ensureDirSync(path.dirname(outputComponentJSPath)) - if (isProduction) { - uglifyJS(resCode, component) - } + // 解析原生组件 const { usingComponents = {} }: IConfig = res.configObj if (usingComponents && !isEmptyObject(usingComponents)) { const keys = Object.keys(usingComponents) @@ -242,6 +245,25 @@ export async function buildSingleComponent ( }) transfromNativeComponents(outputComponentJSONPath.replace(buildConfig.outputDir || buildOutputDir, sourceDirPath), res.configObj) } + if (!isQuickApp) { + resCode = await compileScriptFile(resCode, component, outputComponentJSPath, buildAdapter) + if (isProduction) { + uglifyJS(resCode, component) + } + } else { + // 快应用编译,搜集创建组件 ux 文件 + const importTaroSelfComponents = getImportTaroSelfComponents(outputComponentJSPath, res.taroSelfComponents) + const styleRelativePath = promoteRelativePath(path.relative(outputComponentJSPath, outputComponentWXSSPath)) + const uxTxt = generateQuickAppUx({ + script: resCode, + style: styleRelativePath, + imports: importTaroSelfComponents, + template: componentWXMLContent + }) + fs.writeFileSync(outputComponentWXMLPath, uxTxt) + printLog(processTypeEnum.GENERATE, '组件文件', `${outputDirName}/${componentObj.name}${outputFilesTypes.TEMPL}`) + } + const dependencyTree = getDependencyTree() const fileDep = dependencyTree.get(component) || {} // 编译依赖的组件文件 @@ -284,16 +306,18 @@ export async function buildSingleComponent ( } }) } - fs.writeFileSync(outputComponentJSONPath, JSON.stringify(_.merge({}, buildUsingComponents(component, componentDepComponents, true), res.configObj), null, 2)) - printLog(processTypeEnum.GENERATE, '组件配置', `${outputDirName}/${outputComponentShowPath}${outputFilesTypes.CONFIG}`) - fs.writeFileSync(outputComponentJSPath, resCode) - printLog(processTypeEnum.GENERATE, '组件逻辑', `${outputDirName}/${outputComponentShowPath}${outputFilesTypes.SCRIPT}`) - fs.writeFileSync(outputComponentWXMLPath, componentWXMLContent) - processNativeWxml(outputComponentWXMLPath.replace(outputDir, sourceDir), componentWXMLContent, outputComponentWXMLPath) - printLog(processTypeEnum.GENERATE, '组件模板', `${outputDirName}/${outputComponentShowPath}${outputFilesTypes.TEMPL}`) + if (!isQuickApp) { + fs.writeFileSync(outputComponentJSONPath, JSON.stringify(_.merge({}, buildUsingComponents(component, componentDepComponents, true), res.configObj), null, 2)) + printLog(processTypeEnum.GENERATE, '组件配置', `${outputDirName}/${outputComponentShowPath}${outputFilesTypes.CONFIG}`) + fs.writeFileSync(outputComponentJSPath, resCode) + printLog(processTypeEnum.GENERATE, '组件逻辑', `${outputDirName}/${outputComponentShowPath}${outputFilesTypes.SCRIPT}`) + fs.writeFileSync(outputComponentWXMLPath, componentWXMLContent) + processNativeWxml(outputComponentWXMLPath.replace(outputDir, sourceDir), componentWXMLContent, outputComponentWXMLPath) + printLog(processTypeEnum.GENERATE, '组件模板', `${outputDirName}/${outputComponentShowPath}${outputFilesTypes.TEMPL}`) + } // 编译依赖的脚本文件 if (isDifferentArray(fileDep['script'], res.scriptFiles)) { - compileDepScripts(res.scriptFiles) + compileDepScripts(res.scriptFiles, !isQuickApp) } const depComponents = getDepComponents() // 编译样式文件 diff --git a/packages/taro-cli/src/mini/helper.ts b/packages/taro-cli/src/mini/helper.ts index 237d30c90ac0..fbd4cf94e152 100644 --- a/packages/taro-cli/src/mini/helper.ts +++ b/packages/taro-cli/src/mini/helper.ts @@ -12,7 +12,7 @@ import { processTypeEnum, REG_SCRIPTS, NODE_MODULES_REG, - REG_STYLE + taroJsQuickAppComponents } from '../util/constants' import { resolveScriptPath, @@ -23,7 +23,8 @@ import { printLog, generateEnvList, generateConstantsList, - isEmptyObject + isEmptyObject, + getInstalledNpmPkgPath } from '../util' import { callPluginSync } from '../util/npm' import { resolveNpmPkgMainPath } from '../util/resolve_npm_files' @@ -333,3 +334,29 @@ export function copyFilesFromSrcToOutput (files: string[]) { } }) } + +export function getTaroJsQuickAppComponentsPath () { + const taroJsQuickAppComponentsPkg = getInstalledNpmPkgPath(taroJsQuickAppComponents, getNodeModulesPath()) + if (!taroJsQuickAppComponentsPkg) { + printLog(processTypeEnum.ERROR, '包安装', `缺少包 ${taroJsQuickAppComponents},请安装!`) + process.exit(0) + } + return path.join(path.dirname(taroJsQuickAppComponentsPkg as string), 'src/components') +} + +export function getImportTaroSelfComponents (filePath, taroSelfComponents) { + const importTaroSelfComponents = new Set<{ path: string, name: string }>() + const taroJsQuickAppComponentsPath = getTaroJsQuickAppComponentsPath() + taroSelfComponents.forEach(c => { + const cPath = path.join(taroJsQuickAppComponentsPath, c) + const cMainPath = path.join(cPath, 'index') + const cFiles = fs.readdirSync(cPath).map(item => path.join(cPath, item)) + copyFilesFromSrcToOutput(cFiles) + const cRelativePath = promoteRelativePath(path.relative(filePath, cMainPath.replace(getNodeModulesPath(), BuildData.npmOutputDir))) + importTaroSelfComponents.add({ + path: cRelativePath, + name: c + }) + }) + return importTaroSelfComponents +} diff --git a/packages/taro-cli/src/mini/page.ts b/packages/taro-cli/src/mini/page.ts index 1246b3483c9a..4fc998c43b87 100644 --- a/packages/taro-cli/src/mini/page.ts +++ b/packages/taro-cli/src/mini/page.ts @@ -35,7 +35,9 @@ import { copyFilesFromSrcToOutput, getDependencyTree, getComponentExportsMap, - getDepComponents + getDepComponents, + getTaroJsQuickAppComponentsPath, + getImportTaroSelfComponents } from './helper' import { compileDepScripts, compileScriptFile } from './compileScript' import { compileDepStyles } from './compileStyle' @@ -121,6 +123,66 @@ export async function buildSinglePage (page: string) { }) transfromNativeComponents(outputPageJSONPath.replace(outputDir, sourceDir), res.configObj) } + + if (!isQuickApp) { + resCode = await compileScriptFile(resCode, pageJs, outputPageJSPath, buildAdapter) + if (isProduction) { + uglifyJS(resCode, pageJs) + } + } else { + // 快应用编译,搜集创建页面 ux 文件 + const importTaroSelfComponents = getImportTaroSelfComponents(outputPageJSPath, res.taroSelfComponents) + // 生成页面 ux 文件 + const styleRelativePath = promoteRelativePath(path.relative(outputPageJSPath, outputPageWXSSPath)) + const uxTxt = generateQuickAppUx({ + script: resCode, + style: styleRelativePath, + imports: importTaroSelfComponents, + template: pageWXMLContent + }) + fs.writeFileSync(outputPageWXMLPath, uxTxt) + printLog(processTypeEnum.GENERATE, '页面文件', `${outputDirName}/${page}${outputFilesTypes.TEMPL}`) + } + // 编译依赖的组件文件 + let realComponentsPathList: IComponentObj[] = [] + if (pageDepComponents.length) { + realComponentsPathList = getRealComponentsPathList(pageJs, pageDepComponents) + res.scriptFiles = res.scriptFiles.map(item => { + for (let i = 0; i < realComponentsPathList.length; i++) { + const componentObj = realComponentsPathList[i] + const componentPath = componentObj.path + if (item === componentPath) { + return '' + } + } + return item + }).filter(item => item) + await buildDepComponents(realComponentsPathList) + } + const componentExportsMap = getComponentExportsMap() + if (!isEmptyObject(componentExportsMap) && realComponentsPathList.length) { + const mapKeys = Object.keys(componentExportsMap) + realComponentsPathList.forEach(component => { + if (mapKeys.indexOf(component.path as string) >= 0) { + const componentMap = componentExportsMap.get(component.path as string) + componentMap && componentMap.forEach(component => { + pageDepComponents.forEach(depComponent => { + if (depComponent.name === component.name) { + let componentPath = component.path + let realPath + if (NODE_MODULES_REG.test(componentPath as string)) { + componentPath = (componentPath as string).replace(nodeModulesPath, npmOutputDir) + realPath = promoteRelativePath(path.relative(outputPageJSPath, componentPath)) + } else { + realPath = promoteRelativePath(path.relative(pageJs, componentPath as string)) + } + depComponent.path = realPath.replace(path.extname(realPath), '') + } + }) + }) + } + }) + } const fileDep = dependencyTree.get(pageJs) || {} if (!isQuickApp) { fs.writeFileSync(outputPageJSONPath, JSON.stringify(_.merge({}, buildUsingComponents(pageJs, pageDepComponents), res.configObj), null, 2)) @@ -147,89 +209,12 @@ export async function buildSinglePage (page: string) { if (isDifferentArray(fileDep['media'], res.mediaFiles)) { copyFilesFromSrcToOutput(res.mediaFiles) } + depComponents.set(pageJs, pageDepComponents) fileDep['style'] = res.styleFiles fileDep['script'] = res.scriptFiles fileDep['json'] = res.jsonFiles fileDep['media'] = res.mediaFiles dependencyTree[pageJs] = fileDep - if (!isQuickApp) { - resCode = await compileScriptFile(resCode, pageJs, outputPageJSPath, buildAdapter) - if (isProduction) { - uglifyJS(resCode, pageJs) - } - // 编译依赖的组件文件 - let realComponentsPathList: IComponentObj[] = [] - if (pageDepComponents.length) { - realComponentsPathList = getRealComponentsPathList(pageJs, pageDepComponents) - res.scriptFiles = res.scriptFiles.map(item => { - for (let i = 0; i < realComponentsPathList.length; i++) { - const componentObj = realComponentsPathList[i] - const componentPath = componentObj.path - if (item === componentPath) { - return '' - } - } - return item - }).filter(item => item) - await buildDepComponents(realComponentsPathList) - } - const componentExportsMap = getComponentExportsMap() - if (!isEmptyObject(componentExportsMap) && realComponentsPathList.length) { - const mapKeys = Object.keys(componentExportsMap) - realComponentsPathList.forEach(component => { - if (mapKeys.indexOf(component.path as string) >= 0) { - const componentMap = componentExportsMap.get(component.path as string) - componentMap && componentMap.forEach(component => { - pageDepComponents.forEach(depComponent => { - if (depComponent.name === component.name) { - let componentPath = component.path - let realPath - if (NODE_MODULES_REG.test(componentPath as string)) { - componentPath = (componentPath as string).replace(nodeModulesPath, npmOutputDir) - realPath = promoteRelativePath(path.relative(outputPageJSPath, componentPath)) - } else { - realPath = promoteRelativePath(path.relative(pageJs, componentPath as string)) - } - depComponent.path = realPath.replace(path.extname(realPath), '') - } - }) - }) - } - }) - } - depComponents.set(pageJs, pageDepComponents) - } else { - // 快应用编译,搜集创建页面 ux 文件 - const importTaroSelfComponents = new Set<{ path: string, name: string }>() - const taroJsQuickAppComponentsPkg = getInstalledNpmPkgPath(taroJsQuickAppComponents, nodeModulesPath) - if (!taroJsQuickAppComponentsPkg) { - printLog(processTypeEnum.ERROR, '包安装', `缺少包 ${taroJsQuickAppComponents},请安装!`) - process.exit(0) - } - const taroJsQuickAppComponentsPath = path.join(path.dirname(taroJsQuickAppComponentsPkg as string), 'src/components') - res.taroSelfComponents.forEach(c => { - const cPath = path.join(taroJsQuickAppComponentsPath, c) - const cMainPath = path.join(cPath, 'index') - const cFiles = fs.readdirSync(cPath).map(item => path.join(cPath, item)) - copyFilesFromSrcToOutput(cFiles) - const cRelativePath = promoteRelativePath(path.relative(outputPageJSPath, cMainPath.replace(nodeModulesPath, npmOutputDir))) - importTaroSelfComponents.add({ - path: cRelativePath, - name: c - }) - }) - // 快应用编译组件 - // TODO - const styleRelativePath = promoteRelativePath(path.relative(outputPageJSPath, outputPageWXSSPath)) - const uxTxt = generateQuickAppUx({ - script: resCode, - style: styleRelativePath, - imports: importTaroSelfComponents, - template: pageWXMLContent - }) - fs.writeFileSync(outputPageWXMLPath, uxTxt) - printLog(processTypeEnum.GENERATE, '页面文件', `${outputDirName}/${page}${outputFilesTypes.TEMPL}`) - } } catch (err) { printLog(processTypeEnum.ERROR, '页面编译', `页面${pagePath}编译失败!`) console.log(err) From 015bcdc22b7f4d6732b176e12d76f670ebfae85a Mon Sep 17 00:00:00 2001 From: yuche Date: Fri, 15 Mar 2019 16:44:36 +0800 Subject: [PATCH 044/126] =?UTF-8?q?refactor(transformer):=20=E5=9C=A8?= =?UTF-8?q?=E5=BF=AB=E5=BA=94=E7=94=A8=E4=B8=AD=E4=BD=BF=E7=94=A8=20div=20?= =?UTF-8?q?=E6=9B=BF=E4=BB=A3=20block?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/index.ts | 1 + packages/taro-transformer-wx/src/jsx.ts | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/taro-transformer-wx/src/index.ts b/packages/taro-transformer-wx/src/index.ts index c8ea0d121a05..d193160f1f74 100644 --- a/packages/taro-transformer-wx/src/index.ts +++ b/packages/taro-transformer-wx/src/index.ts @@ -166,6 +166,7 @@ interface TransformResult extends Result { export default function transform (options: Options): TransformResult { if (options.adapter) { setAdapter(options.adapter) + if (Adapter.type === Adapters.quickapp) DEFAULT_Component_SET.add('div') } if (Adapter.type === Adapters.swan) { setLoopOriginal('privateOriginal') diff --git a/packages/taro-transformer-wx/src/jsx.ts b/packages/taro-transformer-wx/src/jsx.ts index c54fbb9cb99a..dd2e18eb9ac2 100644 --- a/packages/taro-transformer-wx/src/jsx.ts +++ b/packages/taro-transformer-wx/src/jsx.ts @@ -113,9 +113,10 @@ export function isAllLiteral (...args) { } export function buildBlockElement (attrs: t.JSXAttribute[] = []) { + const blockName = Adapter.type === Adapters.quickapp ? 'div' : 'block' return t.jSXElement( - t.jSXOpeningElement(t.jSXIdentifier('block'), attrs), - t.jSXClosingElement(t.jSXIdentifier('block')), + t.jSXOpeningElement(t.jSXIdentifier(blockName), attrs), + t.jSXClosingElement(t.jSXIdentifier(blockName)), [] ) } From 8db3620a1a5149278a0d58e07aaf7ba1929c3afb Mon Sep 17 00:00:00 2001 From: yuche Date: Fri, 15 Mar 2019 16:59:48 +0800 Subject: [PATCH 045/126] =?UTF-8?q?refactor(transformer):=20=E4=B8=8E?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=86=85=E7=BD=AE=E7=BB=84=E4=BB=B6=E9=87=8D?= =?UTF-8?q?=E5=90=8D=E7=9A=84=E5=BF=AB=E5=BA=94=E7=94=A8=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E9=87=8D=E5=91=BD=E5=90=8D=E4=B8=BA=20Taro=20=E5=BC=80?= =?UTF-8?q?=E5=A4=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/constant.ts | 17 +++++++++++++++++ packages/taro-transformer-wx/src/index.ts | 14 ++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/packages/taro-transformer-wx/src/constant.ts b/packages/taro-transformer-wx/src/constant.ts index 1a7deb47c48b..4c4ef1bbd55f 100644 --- a/packages/taro-transformer-wx/src/constant.ts +++ b/packages/taro-transformer-wx/src/constant.ts @@ -127,3 +127,20 @@ TRANSFORM_COMPONENT_PROPS.set(Adapters.alipay, { }) export const lessThanSignPlacehold = '__LESS_THAN_SIGN_PLACEHOLDER__' + +export const quickappComponentName = new Set([ + 'Swiper', + 'Image', + 'Progress', + 'Text', + 'Input', + 'Label', + 'Picker', + 'Slider', + 'Switch', + 'Textarea', + 'Video', + 'Camera', + 'Canvas', + 'Map' +]) diff --git a/packages/taro-transformer-wx/src/index.ts b/packages/taro-transformer-wx/src/index.ts index d193160f1f74..020565d7fc03 100644 --- a/packages/taro-transformer-wx/src/index.ts +++ b/packages/taro-transformer-wx/src/index.ts @@ -28,6 +28,7 @@ import { GEL_ELEMENT_BY_ID, lessThanSignPlacehold, COMPONENTS_PACKAGE_NAME, + quickappComponentName, PROPS_MANAGER, GEN_COMP_ID, GEN_LOOP_COMPID @@ -537,6 +538,19 @@ export default function transform (options: Options): TransformResult { importSources.add(source) } const names: string[] = [] + if (source === COMPONENTS_PACKAGE_NAME && Adapters.quickapp === Adapter.type) { + path.node.specifiers.forEach((s) => { + if (t.isImportSpecifier(s)) { + const originalName = s.imported.name + if (quickappComponentName.has(originalName)) { + const importedName = `Taro${originalName}` + s.imported.name = importedName + s.local.name = importedName + path.scope.rename(originalName, importedName) + } + } + }) + } if (source === TARO_PACKAGE_NAME) { isImportTaro = true path.node.specifiers.push( From 2e573a58414f65ad5317f345dc29b1361206e37f Mon Sep 17 00:00:00 2001 From: yuche Date: Mon, 18 Mar 2019 17:27:14 +0800 Subject: [PATCH 046/126] =?UTF-8?q?refactor(transformer):=20=20=E5=BF=AB?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E7=89=B9=E6=AE=8A=E7=BB=84=E4=BB=B6=E4=B8=8D?= =?UTF-8?q?=E7=94=A8=E5=8A=A0=E5=85=A5=E8=BF=94=E5=9B=9E=E7=9A=84=20compon?= =?UTF-8?q?ents?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/class.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/taro-transformer-wx/src/class.ts b/packages/taro-transformer-wx/src/class.ts index e919c5eda99b..4d2ad5c97b3c 100644 --- a/packages/taro-transformer-wx/src/class.ts +++ b/packages/taro-transformer-wx/src/class.ts @@ -13,7 +13,7 @@ import { incrementId, isContainStopPropagation } from './utils' -import { DEFAULT_Component_SET, ANONYMOUS_FUNC } from './constant' +import { DEFAULT_Component_SET, ANONYMOUS_FUNC, COMPONENTS_PACKAGE_NAME } from './constant' import { kebabCase, uniqueId, get as safeGet, set as safeSet } from 'lodash' import { RenderParser } from './render' import { findJSXAttrByName } from './jsx' @@ -739,6 +739,9 @@ class Transformer { setComponents () { this.customComponents.forEach((component, name) => { + if (name.startsWith('Taro') && component.sourcePath === COMPONENTS_PACKAGE_NAME) { + return + } this.result.components.push({ path: pathResolver(component.sourcePath, this.sourcePath), name: kebabCase(name), From c721f704244145a7e219fc6c147d8e23e90321fe Mon Sep 17 00:00:00 2001 From: yuche Date: Mon, 18 Mar 2019 20:36:19 +0800 Subject: [PATCH 047/126] =?UTF-8?q?refactor(transformer):=20=E7=BD=AE?= =?UTF-8?q?=E6=8D=A2=E7=89=B9=E6=AE=8A=E7=BB=84=E4=BB=B6=E6=94=BE=E5=88=B0?= =?UTF-8?q?=E6=9C=80=E5=90=8E=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../taro-transformer-wx/src/create-html-element.ts | 11 +++++++++++ packages/taro-transformer-wx/src/index.ts | 1 - 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/taro-transformer-wx/src/create-html-element.ts b/packages/taro-transformer-wx/src/create-html-element.ts index e0af61a9cdfc..7349e2748699 100644 --- a/packages/taro-transformer-wx/src/create-html-element.ts +++ b/packages/taro-transformer-wx/src/create-html-element.ts @@ -1,3 +1,6 @@ +import { Adapters, Adapter } from './adapter' +import { quickappComponentName } from './constant' + const voidHtmlTags = new Set([ // 'image', 'img', @@ -52,6 +55,14 @@ export const createHTMLElement = (options: Options) => { options ) + if (Adapters.quickapp === Adapter.type) { + const name = options.name + const nameCapitalized = name.charAt(0).toUpperCase() + name.slice(1) + if (quickappComponentName.has(nameCapitalized)) { + options.name = `taro-${name}` + } + } + const isVoidTag = voidHtmlTags.has(options.name) let ret = `<${options.name}${stringifyAttributes(options.attributes)}${isVoidTag ? `/` : '' }>` diff --git a/packages/taro-transformer-wx/src/index.ts b/packages/taro-transformer-wx/src/index.ts index 020565d7fc03..64ae9b99e208 100644 --- a/packages/taro-transformer-wx/src/index.ts +++ b/packages/taro-transformer-wx/src/index.ts @@ -546,7 +546,6 @@ export default function transform (options: Options): TransformResult { const importedName = `Taro${originalName}` s.imported.name = importedName s.local.name = importedName - path.scope.rename(originalName, importedName) } } }) From e1754b6f28de278ad143adf72e81003fa4ab8ac9 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Wed, 20 Mar 2019 17:45:58 +0800 Subject: [PATCH 048/126] =?UTF-8?q?feat(quickapp):=20=E5=BF=AB=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E8=BF=90=E8=A1=8C=E6=97=B6=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/mini/component.ts | 4 +- packages/taro-cli/src/mini/page.ts | 5 +- .../taro-cli/src/util/resolve_npm_files.ts | 2 +- packages/taro-quickapp/package.json | 4 +- packages/taro-quickapp/src/component.js | 13 +- .../taro-quickapp/src/create-component.js | 149 ++++++++++++ packages/taro-quickapp/src/data-cache.js | 15 ++ packages/taro-quickapp/src/lifecycle.js | 97 ++++++++ packages/taro-quickapp/src/next-tick.js | 7 + packages/taro-quickapp/src/render-queue.js | 23 ++ packages/taro-quickapp/src/util.js | 226 ++++++++++++++++++ 11 files changed, 535 insertions(+), 10 deletions(-) create mode 100644 packages/taro-quickapp/src/data-cache.js create mode 100644 packages/taro-quickapp/src/lifecycle.js create mode 100644 packages/taro-quickapp/src/next-tick.js create mode 100644 packages/taro-quickapp/src/render-queue.js create mode 100644 packages/taro-quickapp/src/util.js diff --git a/packages/taro-cli/src/mini/component.ts b/packages/taro-cli/src/mini/component.ts index 472cbd10fc12..0ca18e39624c 100644 --- a/packages/taro-cli/src/mini/component.ts +++ b/packages/taro-cli/src/mini/component.ts @@ -13,15 +13,13 @@ import { NODE_MODULES_REG, NODE_MODULES, PARSE_AST_TYPE, - BUILD_TYPES, - taroJsQuickAppComponents + BUILD_TYPES } from '../util/constants' import { printLog, isEmptyObject, promoteRelativePath, isDifferentArray, - getInstalledNpmPkgPath, generateQuickAppUx } from '../util' diff --git a/packages/taro-cli/src/mini/page.ts b/packages/taro-cli/src/mini/page.ts index 4fc998c43b87..65f062f94fa9 100644 --- a/packages/taro-cli/src/mini/page.ts +++ b/packages/taro-cli/src/mini/page.ts @@ -11,8 +11,7 @@ import { NODE_MODULES_REG, PARSE_AST_TYPE, taroJsFramework, - BUILD_TYPES, - taroJsQuickAppComponents + BUILD_TYPES } from '../util/constants' import { resolveScriptPath, @@ -21,7 +20,6 @@ import { promoteRelativePath, isDifferentArray, copyFileSync, - getInstalledNpmPkgPath, generateQuickAppUx } from '../util' import { IWxTransformResult } from '../util/types' @@ -36,7 +34,6 @@ import { getDependencyTree, getComponentExportsMap, getDepComponents, - getTaroJsQuickAppComponentsPath, getImportTaroSelfComponents } from './helper' import { compileDepScripts, compileScriptFile } from './compileScript' diff --git a/packages/taro-cli/src/util/resolve_npm_files.ts b/packages/taro-cli/src/util/resolve_npm_files.ts index 39707027d8a7..e57325a2ef47 100644 --- a/packages/taro-cli/src/util/resolve_npm_files.ts +++ b/packages/taro-cli/src/util/resolve_npm_files.ts @@ -139,7 +139,7 @@ function parseAst ( const args = node.arguments as Array let requirePath = args[0].value if (excludeRequire.indexOf(requirePath) < 0) { - if (!isQuickAppPkg(requirePath)) { + if (isQuickAppPkg(requirePath)) { return } if (isNpmPkg(requirePath)) { diff --git a/packages/taro-quickapp/package.json b/packages/taro-quickapp/package.json index c800e5b32fa0..8116513d5d0e 100644 --- a/packages/taro-quickapp/package.json +++ b/packages/taro-quickapp/package.json @@ -24,6 +24,8 @@ "license": "MIT", "dependencies": { "@tarojs/taro": "1.2.13", - "@tarojs/utils": "1.2.13" + "@tarojs/utils": "1.2.13", + "lodash": "^4.17.10", + "prop-types": "^15.6.1" } } diff --git a/packages/taro-quickapp/src/component.js b/packages/taro-quickapp/src/component.js index 152a402c3361..605bc98b096e 100644 --- a/packages/taro-quickapp/src/component.js +++ b/packages/taro-quickapp/src/component.js @@ -1,6 +1,8 @@ import { internal_safe_get as safeGet } from '@tarojs/taro' +import { enqueueRender } from './render-queue' +import { updateComponent } from './lifecycle' export default class BaseComponent { // _createData的时候生成,小程序中通过data.__createData访问 @@ -33,7 +35,15 @@ export default class BaseComponent { this.$scope = scope } setState (state, callback) { - + if (state) { + (this._pendingStates = this._pendingStates || []).push(state) + } + if (typeof callback === 'function') { + (this._pendingCallbacks = this._pendingCallbacks || []).push(callback) + } + if (!this._disable) { + enqueueRender(this) + } } getState () { @@ -58,6 +68,7 @@ export default class BaseComponent { if (typeof callback === 'function') { (this._pendingCallbacks = this._pendingCallbacks || []).push(callback) } + updateComponent(this) } // 会被匿名函数调用 diff --git a/packages/taro-quickapp/src/create-component.js b/packages/taro-quickapp/src/create-component.js index 5eb23c89978a..fe6f5fdc5714 100644 --- a/packages/taro-quickapp/src/create-component.js +++ b/packages/taro-quickapp/src/create-component.js @@ -1,3 +1,152 @@ +import { isEmptyObject, queryToJson } from './util' +import { cacheDataGet, cacheDataHas } from './data-cache' +import { updateComponent } from './lifecycle' + +const privatePropValName = '__triggerObserer' +const componentFnReg = /^__fn_/ +const PRELOAD_DATA_KEY = 'preload' +const pageExtraFns = ['onBackPress', 'onMenuPress'] + +function filterProps (properties, defaultProps = {}, componentProps = {}, componentData) { + let newProps = Object.assign({}, componentProps) + for (const propName in properties) { + if (propName === privatePropValName) { + continue + } + if (typeof componentProps[propName] === 'function') { + newProps[propName] = componentProps[propName] + } else if (propName in componentData) { + newProps[propName] = componentData[propName] + } + if (componentFnReg.test(propName)) { + if (componentData[propName] === true) { + const fnName = propName.replace(componentFnReg, '') + newProps[fnName] = noop + } + delete newProps[propName] + } + } + if (!isEmptyObject(defaultProps)) { + for (const propName in defaultProps) { + if (newProps[propName] === undefined || newProps[propName] === null) { + newProps[propName] = defaultProps[propName] + } + } + } + return newProps +} + +function getPageUrlParams (url) { + const queryStr = url.replace(/^.*\?&?/, '') + const params = queryToJson(queryStr) + return params +} + +let hasPageInited = false + +function initComponent (ComponentClass, isPage) { + if (this.$component.__isReady) return + this.$component.__isReady = true + if (isPage && !hasPageInited) { + hasPageInited = true + } + if (hasPageInited && !isPage) { + const nextProps = filterProps(ComponentClass.properties, ComponentClass.defaultProps, this.$component.props, this) + this.$component.props = nextProps + } + if (hasPageInited || isPage) { + updateComponent(this.$component) + } +} + +export function componentTrigger (component, key, args) { + args = args || [] + + component[key] && typeof component[key] === 'function' && component[key].call(component, ...args) + if (key === 'componentWillMount') { + component._dirty = false + component._disable = false + component.state = component.getState() + } + if (key === 'componentWillUnmount') { + component._dirty = true + component._disable = true + component.$router = { + params: {}, + path: '' + } + component._pendingStates = [] + component._pendingCallbacks = [] + } +} + export default function createComponent (ComponentClass, isPage) { + let initData = {} + const componentProps = filterProps(ComponentClass.properties, ComponentClass.defaultProps) + const componentInstance = new ComponentClass(componentProps) + componentInstance._constructor && componentInstance._constructor(componentProps) + try { + componentInstance.state = componentInstance._createData() || componentInstance.state + } catch (err) { + if (isPage) { + console.warn(`[Taro warn] 请给页面提供初始 \`state\` 以提高初次渲染性能!`) + } else { + console.warn(`[Taro warn] 请给组件提供一个 \`defaultProps\` 以提高初次渲染性能!`) + } + console.warn(err) + } + initData = Object.assign({}, initData, componentInstance.props, componentInstance.state) + const componentConf = { + data: initData, + onInit () { + isPage && (hasPageInited = false) + this.$component = new ComponentClass({}, isPage) + this.$component._init(this) + this.$component.render = this.$component._createData + this.$component.__propTypes = ComponentClass.propTypes + Object.assign(this.$component.$router.params, getPageUrlParams(this.$page.uri)) + if (isPage) { + if (cacheDataHas(PRELOAD_DATA_KEY)) { + const data = cacheDataGet(PRELOAD_DATA_KEY, true) + this.$component.$router.preload = data + } + // this.$component.$router.path = getCurrentPageUrl() + initComponent.apply(this, [ComponentClass, isPage]) + } + }, + + onReady () { + if (!isPage) { + initComponent.apply(this, [ComponentClass, isPage]) + } + const component = this.$component + if (!component.__mounted) { + component.__mounted = true + componentTrigger(component, 'componentDidMount') + } + }, + onDestroy () { + componentTrigger(this.$component, 'componentWillUnmount') + } + } + if (isPage) { + componentConf['onShow'] = function () { + componentTrigger(this.$component, 'componentDidShow') + } + componentConf['onHide'] = function () { + componentTrigger(this.$component, 'componentDidHide') + } + pageExtraFns.forEach(fn => { + if (componentInstance[fn] && typeof componentInstance[fn] === 'function') { + componentConf[fn] = function () { + const component = this.$component + if (component[fn] && typeof component[fn] === 'function') { + return component[fn](...arguments) + } + } + } + }) + } + return componentConf } diff --git a/packages/taro-quickapp/src/data-cache.js b/packages/taro-quickapp/src/data-cache.js new file mode 100644 index 000000000000..f11a760035da --- /dev/null +++ b/packages/taro-quickapp/src/data-cache.js @@ -0,0 +1,15 @@ +const data = {} + +export function cacheDataSet (key, val) { + data[key] = val +} + +export function cacheDataGet (key, delelteAfterGet) { + const temp = data[key] + delelteAfterGet && delete data[key] + return temp +} + +export function cacheDataHas (key) { + return key in data +} diff --git a/packages/taro-quickapp/src/lifecycle.js b/packages/taro-quickapp/src/lifecycle.js new file mode 100644 index 000000000000..0bb63bfebb99 --- /dev/null +++ b/packages/taro-quickapp/src/lifecycle.js @@ -0,0 +1,97 @@ +import PropTypes from 'prop-types' +import { + internal_safe_get as safeGet, + internal_safe_set as safeSet +} from '@tarojs/taro' +import { componentTrigger } from './create-component' +import { shakeFnFromObject, isEmptyObject } from './util' + +const isDEV = typeof process === 'undefined' || + !process.env || + process.env.NODE_ENV !== 'production' +const privatePropKeyName = '_triggerObserer' + +export function updateComponent (component) { + const { props, __propTypes } = component + if (isDEV && __propTypes) { + const componentName = component.constructor.name || component.constructor.toString().match(/^function\s*([^\s(]+)/)[1] + PropTypes.checkPropTypes(__propTypes, props, 'prop', componentName) + } + const prevProps = component.prevProps || props + component.props = prevProps + if (component.__mounted && component._unsafeCallUpdate === true && component.componentWillReceiveProps) { + component._disable = true + component.componentWillReceiveProps(props) + component._disable = false + } + // 在willMount前执行构造函数的副本 + if (!component.__componentWillMountTriggered) { + component._constructor && component._constructor(props) + } + let state = component.getState() + + const prevState = component.prevState || state + + let skip = false + if (component.__mounted) { + if (typeof component.shouldComponentUpdate === 'function' && + component.shouldComponentUpdate(props, state) === false) { + skip = true + } else if (typeof component.componentWillUpdate === 'function') { + component.componentWillUpdate(props, state) + } + } + component.props = props + component.state = state + component._dirty = false + if (!component.__componentWillMountTriggered) { + component.__componentWillMountTriggered = true + componentTrigger(component, 'componentWillMount') + } + if (!skip) { + doUpdate(component, prevProps, prevState) + } + component.prevProps = component.props + component.prevState = component.state +} + +function doUpdate (component, prevProps, prevState) { + const { state, props = {} } = component + let data = state || {} + if (component._createData) { + // 返回null或undefined则保持不变 + data = component._createData(state, props) || data + } + let privatePropKeyVal = component.$scope[privatePropKeyName] || false + + data = Object.assign({}, props, data) + if (component.$usedState && component.$usedState.length) { + const _data = {} + component.$usedState.forEach(key => { + let val = safeGet(data, key) + if (typeof val === 'undefined') { + return + } + if (typeof val === 'object') { + if (isEmptyObject(val)) return safeSet(_data, key, val) + + val = shakeFnFromObject(val) + // 避免筛选完 Fn 后产生了空对象还去渲染 + if (!isEmptyObject(val)) safeSet(_data, key, val) + } else { + safeSet(_data, key, val) + } + }) + data = _data + } + // 改变这个私有的props用来触发(observer)子组件的更新 + data[privatePropKeyName] = !privatePropKeyVal + + const __mounted = component.__mounted + // 每次 setData 都独立生成一个 callback 数组 + let cbs = [] + if (component._pendingCallbacks && component._pendingCallbacks.length) { + cbs = component._pendingCallbacks + component._pendingCallbacks = [] + } +} diff --git a/packages/taro-quickapp/src/next-tick.js b/packages/taro-quickapp/src/next-tick.js new file mode 100644 index 000000000000..567665ffe8ad --- /dev/null +++ b/packages/taro-quickapp/src/next-tick.js @@ -0,0 +1,7 @@ +const nextTick = (fn, ...args) => { + fn = typeof fn === 'function' ? fn.bind(null, ...args) : fn + const timerFunc = setTimeout + timerFunc(fn) +} + +export default nextTick diff --git a/packages/taro-quickapp/src/render-queue.js b/packages/taro-quickapp/src/render-queue.js new file mode 100644 index 000000000000..9f2c40f7767e --- /dev/null +++ b/packages/taro-quickapp/src/render-queue.js @@ -0,0 +1,23 @@ +import nextTick from './next-tick' +import { updateComponent } from './lifecycle' + +let items = [] + +export function enqueueRender (component) { + // tslint:disable-next-line:no-conditional-assignment + if (!component._dirty && (component._dirty = true) && items.push(component) === 1) { + nextTick(rerender) + } +} + +export function rerender () { + let p + const list = items + items = [] + // tslint:disable-next-line:no-conditional-assignment + while ((p = list.pop())) { + if (p._dirty) { + updateComponent(p, true) + } + } +} diff --git a/packages/taro-quickapp/src/util.js b/packages/taro-quickapp/src/util.js new file mode 100644 index 000000000000..dec47b85ecde --- /dev/null +++ b/packages/taro-quickapp/src/util.js @@ -0,0 +1,226 @@ +import isPlainObject from 'lodash/isPlainObject' + +export function isEmptyObject (obj) { + if (!obj || !isPlainObject(obj)) { + return false + } + for (const n in obj) { + if (obj.hasOwnProperty(n)) { + return false + } + } + return true +} + +/** + * JSON 克隆 + * @param {Object | Json} jsonObj json对象 + * @return {Object | Json} 新的json对象 + */ +export function objClone (jsonObj) { + let buf + if (Array.isArray(jsonObj)) { + buf = [] + let i = jsonObj.length + while (i--) { + buf[i] = objClone(jsonObj[i]) + } + return buf + } else if (isPlainObject(jsonObj)) { + buf = {} + for (const k in jsonObj) { + buf[k] = objClone(jsonObj[k]) + } + return buf + } else { + return jsonObj + } +} + +export function getPrototype (obj) { + /* eslint-disable */ + if (Object.getPrototypeOf) { + return Object.getPrototypeOf(obj) + } else if (obj.__proto__) { + return obj.__proto__ + } + /* eslint-enable */ + return obj.constructor.prototype +} + +export function getPrototypeChain (obj) { + const protoChain = [] + while ((obj = getPrototype(obj))) { + protoChain.push(obj) + } + return protoChain +} + +export function noop () {} + +export function isFunction (arg) { + return typeof arg === 'function' +} + +export function isArray (arg) { + return Array.isArray(arg) +} + +export function shakeFnFromObject (obj) { + let newObj + if (isArray(obj)) { + newObj = [] + const len = obj.length + for (let i = 0; i < len; i++) { + newObj.push(shakeFnFromObject(obj[i])) + } + } else if (isPlainObject(obj)) { + newObj = {} + for (const key in obj) { + if (isFunction(obj[key])) { + continue + } + const ret = shakeFnFromObject(obj[key]) + newObj[key] = ret + } + } else { + return obj + } + return newObj +} + +const keyList = Object.keys +const hasProp = Object.prototype.hasOwnProperty + +function diffArrToPath (to, from, res = {}, keyPrev = '') { + const len = to.length + for (let i = 0; i < len; i++) { + const toItem = to[i] + const fromItem = from[i] + const targetKey = `${keyPrev}[${i}]` + if (toItem === fromItem) { + continue + } else if (typeof toItem !== typeof fromItem) { + res[targetKey] = toItem + } else { + if (typeof toItem !== 'object') { + res[targetKey] = toItem + } else { + const arrTo = isArray(toItem) + const arrFrom = isArray(fromItem) + if (arrTo !== arrFrom) { + res[targetKey] = toItem + } else if (arrTo && arrFrom) { + if (toItem.length < fromItem.length) { + res[targetKey] = toItem + } else { + // 数组 + diffArrToPath(toItem, fromItem, res, `${targetKey}`) + } + } else { + if (!toItem || !fromItem || keyList(toItem).length < keyList(fromItem).length) { + res[targetKey] = toItem + } else { + // 对象 + diffObjToPath(toItem, fromItem, res, `${targetKey}.`) + } + } + } + } + } + return res +} + +// 比较的对象均为plainObject,且函数已被过滤 +export function diffObjToPath (to, from, res = {}, keyPrev = '') { + const keys = keyList(to) + const len = keys.length + + for (let i = 0; i < len; i++) { + const key = keys[i] + const toItem = to[key] + const fromItem = from[key] + const targetKey = `${keyPrev}${key}` + if (toItem === fromItem) { + continue + } else + if (!hasProp.call(from, key)) { + res[targetKey] = toItem + } else + if (typeof toItem !== typeof fromItem) { + res[targetKey] = toItem + } else { + if (typeof toItem !== 'object') { + res[targetKey] = toItem + } else { + const arrTo = isArray(toItem) + const arrFrom = isArray(fromItem) + if (arrTo !== arrFrom) { + res[targetKey] = toItem + } else if (arrTo && arrFrom) { + if (toItem.length < fromItem.length) { + res[targetKey] = toItem + } else { + // 数组 + diffArrToPath(toItem, fromItem, res, `${targetKey}`) + } + } else { + // null + if (!toItem || !fromItem || keyList(toItem).length < keyList(fromItem).length) { + res[targetKey] = toItem + } else { + // 对象 + diffObjToPath(toItem, fromItem, res, `${targetKey}.`) + } + } + } + } + } + return res +} + +export function queryToJson (str) { + const dec = decodeURIComponent + const qp = str.split('&') + let ret = {} + let name + let val + for (let i = 0, l = qp.length, item; i < l; ++i) { + item = qp[i] + if (item.length) { + const s = item.indexOf('=') + if (s < 0) { + name = dec(item) + val = '' + } else { + name = dec(item.slice(0, s)) + val = dec(item.slice(s + 1)) + } + if (typeof ret[name] === 'string') { // inline'd type check + ret[name] = [ret[name]] + } + + if (isArray(ret[name])) { + ret[name].push(val) + } else { + ret[name] = val + } + } + } + return ret // Object +} + +const _loadTime = (new Date()).getTime().toString() +let _i = 1 +export function getUniqueKey () { + return _loadTime + (_i++) +} + +export function getObjChainValue (obj, keyChain) { + const keys = keyChain.split('.') + for (let i = 0, len = keys.length; i < len; i++) { + const key = keys[i] + if (i === len - 1) return obj[key] + obj = obj[key] + } +} From eeaaf6593e6c411bd42d5f57a2b1108cd9992367 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Tue, 26 Mar 2019 22:25:43 +0800 Subject: [PATCH 049/126] =?UTF-8?q?feat(cli):=20=E5=BF=AB=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E7=BC=96=E8=AF=91=E7=8E=AF=E5=A2=83=E5=87=86=E5=A4=87?= =?UTF-8?q?=EF=BC=8C=E4=B8=80=E9=94=AE=E5=90=AF=E5=8A=A8=E5=BF=AB=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E7=BC=96=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/package.json | 17 +- packages/taro-cli/src/build.ts | 6 +- .../taro-cli/src/config/manifest.default.json | 20 + packages/taro-cli/src/mini/helper.ts | 16 +- packages/taro-cli/src/mini/index.ts | 160 +- packages/taro-cli/src/mini/page.ts | 5 +- packages/taro-cli/src/util/dowload.ts | 48 + packages/taro-cli/src/util/index.ts | 48 + .../taro-cli/src/util/resolve_npm_files.ts | 2 +- packages/taro-cli/yarn.lock | 1461 ++++++++--------- 10 files changed, 945 insertions(+), 838 deletions(-) create mode 100644 packages/taro-cli/src/config/manifest.default.json create mode 100644 packages/taro-cli/src/util/dowload.ts diff --git a/packages/taro-cli/package.json b/packages/taro-cli/package.json index d492759d0592..ae3af121e809 100644 --- a/packages/taro-cli/package.json +++ b/packages/taro-cli/package.json @@ -30,8 +30,9 @@ "author": "O2Team", "license": "MIT", "dependencies": { - "@tarojs/taroize": "1.2.27-beta.0", - "@tarojs/transformer-wx": "1.2.27-beta.0", + "@tarojs/taroize": "1.2.13", + "@tarojs/transformer-wx": "1.2.13", + "@types/request": "^2.48.1", "autoprefixer": "^8.4.1", "babel-core": "^6.26.3", "babel-eslint": "^8.2.3", @@ -86,6 +87,7 @@ "postcss-url": "^7.3.2", "prettier": "^1.16.4", "prop-types": "^15.6.2", + "request": "^2.88.0", "resolve": "^1.6.0", "semver": "^5.5.0", "shelljs": "^0.8.1", @@ -94,22 +96,23 @@ "stylelint-taro-rn": "1.2.27-beta.0", "through2": "^2.0.3", "vinyl": "^2.1.0", - "vinyl-fs": "^3.0.2" + "vinyl-fs": "^3.0.2", + "yauzl": "2.10.0" }, "devDependencies": { - "@types/autoprefixer": "^9.1.1", - "@types/klaw": "^3.0.0", - "@types/shelljs": "^0.8.5", - "@types/ejs": "^2.6.3", "@tarojs/taro": "^1.2.2", + "@types/autoprefixer": "^9.1.1", "@types/babel-core": "^6.25.5", "@types/babel-generator": "^6.25.2", "@types/babel-traverse": "^6.25.4", "@types/babel-types": "^6.25.2", + "@types/ejs": "^2.6.3", "@types/fs-extra": "^5.0.4", "@types/jest": "^23.3.10", + "@types/klaw": "^3.0.0", "@types/lodash": "^4.14.119", "@types/node": "^10.12.18", + "@types/shelljs": "^0.8.5", "babel-jest": "^23.6.0", "babel-plugin-transform-class-properties": "^6.24.1", "babel-preset-env": "^1.7.0", diff --git a/packages/taro-cli/src/build.ts b/packages/taro-cli/src/build.ts index 614ffbead5fa..c6745e0fa5ec 100644 --- a/packages/taro-cli/src/build.ts +++ b/packages/taro-cli/src/build.ts @@ -16,10 +16,8 @@ export default function build (args, buildConfig: IBuildConfig) { const outputPath = path.join(appPath, configDir.outputRoot || CONFIG.OUTPUT_DIR) if (!fs.existsSync(outputPath)) { fs.ensureDirSync(outputPath) - } else { - if (type !== BUILD_TYPES.H5) { - Util.emptyDirectory(outputPath) - } + } else if (type !== BUILD_TYPES.H5 && (type !== BUILD_TYPES.QUICKAPP || !watch)) { + Util.emptyDirectory(outputPath) } switch (type) { case BUILD_TYPES.H5: diff --git a/packages/taro-cli/src/config/manifest.default.json b/packages/taro-cli/src/config/manifest.default.json new file mode 100644 index 000000000000..9d5845985a90 --- /dev/null +++ b/packages/taro-cli/src/config/manifest.default.json @@ -0,0 +1,20 @@ +{ + "package": "com.application.demo", + "name": "TaroQuickApp", + "versionName": "1.0.0", + "versionCode": "1", + "minPlatformVersion": "101", + "features": [ + { "name": "system.prompt" }, + { "name": "system.router" }, + { "name": "system.shortcut" }, + { "name": "system.fetch" }, + { "name": "system.storage" } + ], + "permissions": [ + { "origin": "*" } + ], + "config": { + "logLevel": "debug" + } +} diff --git a/packages/taro-cli/src/mini/helper.ts b/packages/taro-cli/src/mini/helper.ts index fbd4cf94e152..0faa7ab46b8b 100644 --- a/packages/taro-cli/src/mini/helper.ts +++ b/packages/taro-cli/src/mini/helper.ts @@ -2,7 +2,7 @@ import * as fs from 'fs-extra' import * as path from 'path' import * as _ from 'lodash' -import { AppConfig } from '@tarojs/taro' +import { Config } from '@tarojs/taro' import { BUILD_TYPES, @@ -78,11 +78,13 @@ export interface IBuildData { outputDirName: string, sourceDir: string, outputDir: string, + originalOutputDir: string, entryFilePath: string, entryFileName: string, projectConfig: IProjectConfig, npmConfig: INpmConfig, - appConfig: AppConfig, + appConfig: Config, + pageConfigs: Map, alias: IOption, compileInclude: string[], isProduction: boolean, @@ -103,6 +105,7 @@ const BuildData: IBuildData = { outputDirName, sourceDir, outputDir, + originalOutputDir: outputDir, entryFilePath, entryFileName, projectConfig, @@ -110,6 +113,7 @@ const BuildData: IBuildData = { alias: pathAlias, isProduction: false, appConfig: {}, + pageConfigs: new Map(), compileInclude, buildAdapter: BUILD_TYPES.WEAPP, outputFilesTypes: MINI_APP_FILES[BUILD_TYPES.WEAPP], @@ -133,7 +137,7 @@ export const shouldTransformAgain = (function () { return false })() -export function setAppConfig (appConfig: AppConfig) { +export function setAppConfig (appConfig: Config) { BuildData.appConfig = appConfig } @@ -151,6 +155,12 @@ export function setBuildAdapter (adapter: BUILD_TYPES) { BuildData.constantsReplaceList = Object.assign({}, generateEnvList(projectConfig.env || {}), generateConstantsList(projectConfig.defineConstants || {}), { 'process.env.TARO_ENV': adapter }) + if (adapter === BUILD_TYPES.QUICKAPP) { + BuildData.originalOutputDir = outputDir + BuildData.outputDirName = `${outputDirName}/src` + BuildData.outputDir = path.join(appPath, BuildData.outputDirName) + BuildData.npmOutputDir = getNpmOutputDir(BuildData.outputDir, configDir, npmConfig) + } } export function getBuildData (): IBuildData { diff --git a/packages/taro-cli/src/mini/index.ts b/packages/taro-cli/src/mini/index.ts index 2f80eeb26a88..c4abbdb1d091 100644 --- a/packages/taro-cli/src/mini/index.ts +++ b/packages/taro-cli/src/mini/index.ts @@ -3,12 +3,17 @@ import * as path from 'path' import chalk from 'chalk' import * as _ from 'lodash' +import * as ora from 'ora' +import * as shelljs from 'shelljs' import { printLog, getInstalledNpmPkgVersion, getPkgVersion, - copyFiles + copyFiles, + unzip, + shouldUseYarn, + shouldUseCnpm } from '../util' import { processTypeEnum, BUILD_TYPES } from '../util/constants' import { IMiniAppBuildConfig } from '../util/types' @@ -22,25 +27,10 @@ import { import { buildEntry } from './entry' import { buildPages } from './page' import { watchFiles } from './watch' +import { downloadGithubRepoLatestRelease } from '../util/dowload' const appPath = process.cwd() -// async function checkCliAndFrameworkVersion () { -// const { buildAdapter, nodeModulesPath } = getBuildData() -// const frameworkName = `@tarojs/taro-${buildAdapter}` -// const frameworkVersion = getInstalledNpmPkgVersion(frameworkName, nodeModulesPath) -// if (frameworkVersion) { -// if (frameworkVersion !== getPkgVersion()) { -// printLog(processTypeEnum.ERROR, '版本问题', `Taro CLI 与本地安装的小程序框架 ${frameworkName} 版本不一致,请确保一致`) -// console.log(`Taro CLI: ${getPkgVersion()}`) -// console.log(`${frameworkName}: ${frameworkVersion}`) -// process.exit(1) -// } -// } else { -// printLog(processTypeEnum.WARNING, '依赖安装', chalk.red(`项目依赖 ${frameworkName} 未安装,或安装有误!`)) -// } -// } - function buildProjectConfig () { const { buildAdapter, sourceDir, outputDir, outputDirName } = getBuildData() let projectConfigFileName = `project.${buildAdapter}.json` @@ -97,20 +87,146 @@ async function buildFrameworkInfo () { } } +function generateQuickAppManifest () { + const { appConfig, pageConfigs, appPath, outputDir } = getBuildData() + // 生成 router + const pages = appConfig.pages as string[] + const routerPages = {} + pages.forEach(element => { + routerPages[path.dirname(element)] = { + component: path.basename(element), + filter: { + view: { + uri: 'https?://.*' + } + } + } + }) + const routerEntry = pages.shift() + const router = { + entry: path.dirname(routerEntry as string), + pages: routerPages + } + // 生成 display + const display = JSON.parse(JSON.stringify(appConfig.window || {})) + display.pages = {} + pageConfigs.forEach((item, page) => { + if (item) { + display.pages[path.dirname(page)] = item + } + }) + // 读取 project.quickapp.json + const quickappJSONPath = path.join(appPath, 'project.quickapp.json') + let quickappJSON + if (fs.existsSync(quickappJSONPath)) { + quickappJSON = fs.readJSONSync(quickappJSONPath) + } else { + quickappJSON = fs.readJSONSync('../config/manifest.default.json') + } + quickappJSON.router = router + quickappJSON.display = display + fs.writeFileSync(path.join(outputDir, 'manifest.json'), JSON.stringify(quickappJSON, null, 2)) +} + +async function prepareQuickAppEnvironment (isWatch, buildData) { + let isReady = false + let needDownload = false + let needInstall = false + const originalOutputDir = buildData.originalOutputDir + console.log() + if (isWatch) { + if (fs.existsSync(path.join(buildData.originalOutputDir, 'sign'))) { + needDownload = false + } else { + needDownload = true + } + } else { + needDownload = true + } + if (needDownload) { + const getSpinner = ora('开始下载快应用运行容器...').start() + await downloadGithubRepoLatestRelease('NervJS/quickapp-container', originalOutputDir) + await unzip(path.join(originalOutputDir, 'download_temp.zip')) + getSpinner.succeed('快应用运行容器下载完成') + } else { + console.log(`${chalk.green('✔ ')} 快应用容器已经准备好`) + } + + console.log() + process.chdir(originalOutputDir) + if (isWatch) { + if (fs.existsSync(path.join(originalOutputDir, 'node_modules'))) { + needInstall = false + } else { + needInstall = true + } + } else { + needInstall = true + } + if (needInstall) { + let command + if (shouldUseYarn) { + command = 'yarn install' + } else if (shouldUseCnpm()) { + command = 'cnpm install' + } else { + command = 'npm install' + } + const installSpinner = ora(`安装快应用依赖环境, 需要一会儿...`).start() + const install = shelljs.exec(command, { silent: true }) + if (install.code === 0) { + installSpinner.color = 'green' + installSpinner.succeed('安装成功') + console.log(`${install.stderr}${install.stdout}`) + isReady = true + } else { + installSpinner.color = 'red' + installSpinner.fail(chalk.red(`快应用依赖环境安装失败,请进入 ${path.basename(originalOutputDir)} 重新安装!`)) + console.log(`${install.stderr}${install.stdout}`) + isReady = false + } + } else { + console.log(`${chalk.green('✔ ')} 快应用依赖已经安装好`) + isReady = true + } + return isReady +} + +async function runQuickApp (isWatch) { + if (isWatch) { + shelljs.exec('npm run server -- --port 12306', { silent: false }) + // shelljs.exec('npm run watch', { silent: false }) + } +} + export async function build ({ watch, adapter = BUILD_TYPES.WEAPP, envHasBeenSet = false }: IMiniAppBuildConfig) { - const { projectConfig } = getBuildData() + const buildData = getBuildData() + const isQuickApp = adapter === BUILD_TYPES.QUICKAPP process.env.TARO_ENV = adapter if (!envHasBeenSet) { setIsProduction(process.env.NODE_ENV === 'production' || !watch) } setBuildAdapter(adapter) - // await checkCliAndFrameworkVersion() - buildProjectConfig() - await buildFrameworkInfo() - copyFiles(appPath, projectConfig.copy) + fs.ensureDirSync(buildData.outputDir) + if (!isQuickApp) { + buildProjectConfig() + await buildFrameworkInfo() + } + copyFiles(appPath, buildData.projectConfig.copy) const appConfig = await buildEntry() setAppConfig(appConfig) await buildPages() + if (isQuickApp) { + generateQuickAppManifest() + const isReady = await prepareQuickAppEnvironment(watch, buildData) + if (!isReady) { + console.log() + console.log(chalk.red('快应用环境准备失败,请重试!')) + process.exit(0) + return + } + await runQuickApp(watch) + } // if (watch) { // watchFiles() // } diff --git a/packages/taro-cli/src/mini/page.ts b/packages/taro-cli/src/mini/page.ts index 65f062f94fa9..3183824545e2 100644 --- a/packages/taro-cli/src/mini/page.ts +++ b/packages/taro-cli/src/mini/page.ts @@ -55,7 +55,8 @@ export async function buildSinglePage (page: string) { outputFilesTypes, nodeModulesPath, npmOutputDir, - jsxAttributeNameReplace + jsxAttributeNameReplace, + pageConfigs } = getBuildData() const pagePath = path.join(sourceDir, `${page}`) const pageJs = resolveScriptPath(pagePath) @@ -107,6 +108,7 @@ export async function buildSinglePage (page: string) { const res = parseAst(PARSE_AST_TYPE.PAGE, transformResult.ast, pageDepComponents, pageJs, outputPageJSPath) let resCode = res.code fs.ensureDirSync(outputPagePath) + pageConfigs.set(page, res.configObj) // 解析原生组件 const { usingComponents = {} }: IConfig = res.configObj if (usingComponents && !isEmptyObject(usingComponents)) { @@ -180,6 +182,7 @@ export async function buildSinglePage (page: string) { } }) } + const fileDep = dependencyTree.get(pageJs) || {} if (!isQuickApp) { fs.writeFileSync(outputPageJSONPath, JSON.stringify(_.merge({}, buildUsingComponents(pageJs, pageDepComponents), res.configObj), null, 2)) diff --git a/packages/taro-cli/src/util/dowload.ts b/packages/taro-cli/src/util/dowload.ts new file mode 100644 index 000000000000..a52a5b982595 --- /dev/null +++ b/packages/taro-cli/src/util/dowload.ts @@ -0,0 +1,48 @@ +import * as fs from 'fs-extra' +import * as path from 'path' +import * as request from 'request' + +const GITHUB_API = 'https://api.github.com/' +const GITHUB = 'https://github.com/' + +export function getGithubRepoLatestReleaseVersion (repoName) { + const latestReleaseApi = `${GITHUB_API}repos/${repoName}/releases/latest` + const p = new Promise((resolve, reject) => { + request({ + url: latestReleaseApi, + headers: { + 'User-Agent': 'Awesome-Octocat-App' + } + }, (err, response, body) => { + if (err) { + throw new Error('快应用容器版本请求失败,请重试!') + } + const res = JSON.parse(body) + resolve(res.tag_name) + }) + }) + return p +} + +export async function downloadGithubRepoLatestRelease (repoName, dest) { + const latestTagName = await getGithubRepoLatestReleaseVersion(repoName) + return new Promise((resolve, reject) => { + const downloadUrl = `${GITHUB}${repoName}/archive/${latestTagName}.zip` + const downloadTemp = 'download_temp.zip' + request({ + url: downloadUrl, + headers: { + 'User-Agent': 'Awesome-Octocat-App' + } + }) + .on('error', reject) + .on('complete', () => { + const downloadTempPath = path.join(process.cwd(), downloadTemp) + if (fs.existsSync(downloadTempPath)) { + fs.moveSync(downloadTempPath, path.join(dest, downloadTemp)) + resolve() + } + }) + .pipe(fs.createWriteStream(downloadTemp)) + }) +} diff --git a/packages/taro-cli/src/util/index.ts b/packages/taro-cli/src/util/index.ts index 7d079dd529b3..9273db8ee059 100644 --- a/packages/taro-cli/src/util/index.ts +++ b/packages/taro-cli/src/util/index.ts @@ -7,6 +7,8 @@ import * as chalk from 'chalk' import * as _ from 'lodash' import * as minimatch from 'minimatch' import * as t from 'babel-types' +import * as yauzl from 'yauzl' +import { Transform } from 'stream' import { TS_EXT, @@ -545,3 +547,49 @@ export function generateQuickAppUx ({ } return uxTxt } + + +export function unzip (zipPath) { + return new Promise((resolve, reject) => { + yauzl.open(zipPath, { lazyEntries: true }, (err, zipfile) => { + if (err) throw err + zipfile.on('close', () => { + fs.removeSync(zipPath) + resolve() + }) + zipfile.readEntry() + zipfile.on('error', (err) => { + reject(err) + }) + zipfile.on('entry', entry => { + if (/\/$/.test(entry.fileName)) { + const fileNameArr = entry.fileName.replace(/\\/g, '/').split('/') + fileNameArr.shift() + const fileName = fileNameArr.join('/') + fs.ensureDirSync(path.join(path.dirname(zipPath), fileName)) + zipfile.readEntry() + } else { + zipfile.openReadStream(entry, (err, readStream) => { + if (err) throw err + const filter = new Transform() + filter._transform = function (chunk, encoding, cb) { + cb(undefined, chunk) + } + filter._flush = function (cb) { + cb() + zipfile.readEntry() + } + const fileNameArr = entry.fileName.replace(/\\/g, '/').split('/') + fileNameArr.shift() + const fileName = fileNameArr.join('/') + const writeStream = fs.createWriteStream(path.join(path.dirname(zipPath), fileName)) + writeStream.on('close', () => {}) + readStream + .pipe(filter) + .pipe(writeStream) + }) + } + }) + }) + }) +} diff --git a/packages/taro-cli/src/util/resolve_npm_files.ts b/packages/taro-cli/src/util/resolve_npm_files.ts index e57325a2ef47..170d7efdd653 100644 --- a/packages/taro-cli/src/util/resolve_npm_files.ts +++ b/packages/taro-cli/src/util/resolve_npm_files.ts @@ -194,7 +194,7 @@ async function recursiveRequire ( filePath.slice(0, filePath.search('node_modules')), process.cwd() ) - outputNpmPath = filePath.replace('node_modules', path.join(cwdRelate2Npm, outputDirName, npmConfig.name)) + outputNpmPath = filePath.replace('node_modules', path.join(cwdRelate2Npm, buildAdapter !== BUILD_TYPES.QUICKAPP ? outputDirName : `${outputDirName}/src`, npmConfig.name)) outputNpmPath = outputNpmPath.replace(/node_modules/g, npmConfig.name) } else { const matches = filePath.match(/(?=(node_modules)).*/) diff --git a/packages/taro-cli/yarn.lock b/packages/taro-cli/yarn.lock index fa661ca428a4..332a932618c2 100644 --- a/packages/taro-cli/yarn.lock +++ b/packages/taro-cli/yarn.lock @@ -4,7 +4,7 @@ "@babel/code-frame@7.0.0-beta.44": version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9" dependencies: "@babel/highlight" "7.0.0-beta.44" @@ -14,16 +14,16 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@>=7.1.0": - version "7.4.0" - resolved "http://registry.npm.taobao.org/@babel/core/download/@babel/core-7.4.0.tgz#248fd6874b7d755010bfe61f557461d4f446d9e9" +"@babel/core@>=7.1.0", "@babel/core@^7.0.0-beta": + version "7.4.3" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.4.3.tgz#198d6d3af4567be3989550d97e068de94503074f" dependencies: "@babel/code-frame" "^7.0.0" "@babel/generator" "^7.4.0" - "@babel/helpers" "^7.4.0" - "@babel/parser" "^7.4.0" + "@babel/helpers" "^7.4.3" + "@babel/parser" "^7.4.3" "@babel/template" "^7.4.0" - "@babel/traverse" "^7.4.0" + "@babel/traverse" "^7.4.3" "@babel/types" "^7.4.0" convert-source-map "^1.1.0" debug "^4.1.0" @@ -33,28 +33,9 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.0.0-beta": - version "7.2.2" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.2.2.tgz#07adba6dde27bb5ad8d8672f15fde3e08184a687" - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.2.2" - "@babel/helpers" "^7.2.0" - "@babel/parser" "^7.2.2" - "@babel/template" "^7.2.2" - "@babel/traverse" "^7.2.2" - "@babel/types" "^7.2.2" - convert-source-map "^1.1.0" - debug "^4.1.0" - json5 "^2.1.0" - lodash "^4.17.10" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - "@babel/generator@7.0.0-beta.44": version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42" dependencies: "@babel/types" "7.0.0-beta.44" jsesc "^2.5.1" @@ -62,19 +43,9 @@ source-map "^0.5.0" trim-right "^1.0.1" -"@babel/generator@^7.0.0-beta", "@babel/generator@^7.2.2": - version "7.2.2" - resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.2.2.tgz#18c816c70962640eab42fe8cae5f3947a5c65ccc" - dependencies: - "@babel/types" "^7.2.2" - jsesc "^2.5.1" - lodash "^4.17.10" - source-map "^0.5.0" - trim-right "^1.0.1" - -"@babel/generator@^7.4.0": +"@babel/generator@^7.0.0-beta", "@babel/generator@^7.4.0": version "7.4.0" - resolved "http://registry.npm.taobao.org/@babel/generator/download/@babel/generator-7.4.0.tgz#c230e79589ae7a729fd4631b9ded4dc220418196" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.4.0.tgz#c230e79589ae7a729fd4631b9ded4dc220418196" dependencies: "@babel/types" "^7.4.0" jsesc "^2.5.1" @@ -95,38 +66,39 @@ "@babel/helper-explode-assignable-expression" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helper-builder-react-jsx@^7.0.0": - version "7.0.0" - resolved "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0.tgz#fa154cb53eb918cf2a9a7ce928e29eb649c5acdb" +"@babel/helper-builder-react-jsx@^7.3.0": + version "7.3.0" + resolved "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz#a1ac95a5d2b3e88ae5e54846bf462eeb81b318a4" dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.3.0" esutils "^2.0.0" -"@babel/helper-call-delegate@^7.1.0": - version "7.1.0" - resolved "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz#6a957f105f37755e8645343d3038a22e1449cc4a" +"@babel/helper-call-delegate@^7.4.0": + version "7.4.0" + resolved "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.0.tgz#f308eabe0d44f451217853aedf4dea5f6fe3294f" dependencies: - "@babel/helper-hoist-variables" "^7.0.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/helper-hoist-variables" "^7.4.0" + "@babel/traverse" "^7.4.0" + "@babel/types" "^7.4.0" -"@babel/helper-create-class-features-plugin@^7.2.3": - version "7.2.3" - resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.2.3.tgz#f6e719abb90cb7f4a69591e35fd5eb89047c4a7c" +"@babel/helper-create-class-features-plugin@^7.4.0": + version "7.4.3" + resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.4.3.tgz#5bbd279c6c3ac6a60266b89bbfe7f8021080a1ef" dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/helper-member-expression-to-functions" "^7.0.0" "@babel/helper-optimise-call-expression" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.2.3" + "@babel/helper-replace-supers" "^7.4.0" + "@babel/helper-split-export-declaration" "^7.4.0" -"@babel/helper-define-map@^7.1.0": - version "7.1.0" - resolved "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz#3b74caec329b3c80c116290887c0dd9ae468c20c" +"@babel/helper-define-map@^7.4.0": + version "7.4.0" + resolved "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.0.tgz#cbfd8c1b2f12708e262c26f600cd16ed6a3bc6c9" dependencies: "@babel/helper-function-name" "^7.1.0" - "@babel/types" "^7.0.0" - lodash "^4.17.10" + "@babel/types" "^7.4.0" + lodash "^4.17.11" "@babel/helper-explode-assignable-expression@^7.1.0": version "7.1.0" @@ -137,7 +109,7 @@ "@babel/helper-function-name@7.0.0-beta.44": version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz#e18552aaae2231100a6e485e03854bc3532d44dd" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz#e18552aaae2231100a6e485e03854bc3532d44dd" dependencies: "@babel/helper-get-function-arity" "7.0.0-beta.44" "@babel/template" "7.0.0-beta.44" @@ -153,7 +125,7 @@ "@babel/helper-get-function-arity@7.0.0-beta.44": version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz#d03ca6dd2b9f7b0b1e6b32c56c72836140db3a15" + resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz#d03ca6dd2b9f7b0b1e6b32c56c72836140db3a15" dependencies: "@babel/types" "7.0.0-beta.44" @@ -163,11 +135,11 @@ dependencies: "@babel/types" "^7.0.0" -"@babel/helper-hoist-variables@^7.0.0": - version "7.0.0" - resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz#46adc4c5e758645ae7a45deb92bab0918c23bb88" +"@babel/helper-hoist-variables@^7.4.0": + version "7.4.0" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.0.tgz#25b621399ae229869329730a62015bbeb0a6fbd6" dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.4.0" "@babel/helper-member-expression-to-functions@^7.0.0": version "7.0.0" @@ -181,16 +153,16 @@ dependencies: "@babel/types" "^7.0.0" -"@babel/helper-module-transforms@^7.1.0": - version "7.2.2" - resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz#ab2f8e8d231409f8370c883d20c335190284b963" +"@babel/helper-module-transforms@^7.4.3": + version "7.4.3" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.3.tgz#b1e357a1c49e58a47211a6853abb8e2aaefeb064" dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" "@babel/helper-split-export-declaration" "^7.0.0" "@babel/template" "^7.2.2" "@babel/types" "^7.2.2" - lodash "^4.17.10" + lodash "^4.17.11" "@babel/helper-optimise-call-expression@^7.0.0": version "7.0.0" @@ -212,14 +184,14 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helper-replace-supers@^7.1.0", "@babel/helper-replace-supers@^7.2.3": - version "7.2.3" - resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.2.3.tgz#19970020cf22677d62b3a689561dbd9644d8c5e5" +"@babel/helper-replace-supers@^7.4.0": + version "7.4.0" + resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.0.tgz#4f56adb6aedcd449d2da9399c2dcf0545463b64c" dependencies: "@babel/helper-member-expression-to-functions" "^7.0.0" "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/traverse" "^7.2.3" - "@babel/types" "^7.0.0" + "@babel/traverse" "^7.4.0" + "@babel/types" "^7.4.0" "@babel/helper-simple-access@^7.1.0": version "7.1.0" @@ -230,19 +202,13 @@ "@babel/helper-split-export-declaration@7.0.0-beta.44": version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz#c0b351735e0fbcb3822c8ad8db4e583b05ebd9dc" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz#c0b351735e0fbcb3822c8ad8db4e583b05ebd9dc" dependencies: "@babel/types" "7.0.0-beta.44" -"@babel/helper-split-export-declaration@^7.0.0": - version "7.0.0" - resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813" - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-split-export-declaration@^7.4.0": +"@babel/helper-split-export-declaration@^7.0.0", "@babel/helper-split-export-declaration@^7.4.0": version "7.4.0" - resolved "http://registry.npm.taobao.org/@babel/helper-split-export-declaration/download/@babel/helper-split-export-declaration-7.4.0.tgz#571bfd52701f492920d63b7f735030e9a3e10b55" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz#571bfd52701f492920d63b7f735030e9a3e10b55" dependencies: "@babel/types" "^7.4.0" @@ -255,25 +221,17 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.2.0" -"@babel/helpers@^7.2.0": - version "7.2.0" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.2.0.tgz#8335f3140f3144270dc63c4732a4f8b0a50b7a21" - dependencies: - "@babel/template" "^7.1.2" - "@babel/traverse" "^7.1.5" - "@babel/types" "^7.2.0" - -"@babel/helpers@^7.4.0": - version "7.4.2" - resolved "http://registry.npm.taobao.org/@babel/helpers/download/@babel/helpers-7.4.2.tgz#3bdfa46a552ca77ef5a0f8551be5f0845ae989be" +"@babel/helpers@^7.4.3": + version "7.4.3" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.3.tgz#7b1d354363494b31cb9a2417ae86af32b7853a3b" dependencies: "@babel/template" "^7.4.0" - "@babel/traverse" "^7.4.0" + "@babel/traverse" "^7.4.3" "@babel/types" "^7.4.0" "@babel/highlight@7.0.0-beta.44": version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5" dependencies: chalk "^2.0.0" esutils "^2.0.2" @@ -287,13 +245,9 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.2.2", "@babel/parser@^7.2.3": - version "7.2.3" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.2.3.tgz#32f5df65744b70888d17872ec106b02434ba1489" - -"@babel/parser@^7.4.0": - version "7.4.2" - resolved "http://registry.npm.taobao.org/@babel/parser/download/@babel/parser-7.4.2.tgz#b4521a400cb5a871eab3890787b4bc1326d38d91" +"@babel/parser@^7.4.0", "@babel/parser@^7.4.3": + version "7.4.3" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.4.3.tgz#eb3ac80f64aa101c907d4ce5406360fe75b7895b" "@babel/plugin-external-helpers@^7.0.0-beta": version "7.2.0" @@ -302,15 +256,15 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-class-properties@^7.0.0-beta": - version "7.2.3" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.2.3.tgz#c9e1294363b346cff333007a92080f3203698461" + version "7.4.0" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.4.0.tgz#d70db61a2f1fd79de927eea91f6411c964e084b8" dependencies: - "@babel/helper-create-class-features-plugin" "^7.2.3" + "@babel/helper-create-class-features-plugin" "^7.4.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-object-rest-spread@^7.0.0-beta": - version "7.2.0" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.2.0.tgz#88f5fec3e7ad019014c97f7ee3c992f0adbf7fb8" + version "7.4.3" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.3.tgz#be27cd416eceeba84141305b93c282f5de23bbb4" dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0" @@ -346,23 +300,23 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-block-scoping@^7.0.0-beta": - version "7.2.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.2.0.tgz#f17c49d91eedbcdf5dd50597d16f5f2f770132d4" + version "7.4.0" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.0.tgz#164df3bb41e3deb954c4ca32ffa9fcaa56d30bcb" dependencies: "@babel/helper-plugin-utils" "^7.0.0" - lodash "^4.17.10" + lodash "^4.17.11" "@babel/plugin-transform-classes@^7.0.0-beta": - version "7.2.2" - resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.2.2.tgz#6c90542f210ee975aa2aa8c8b5af7fa73a126953" + version "7.4.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.3.tgz#adc7a1137ab4287a555d429cc56ecde8f40c062c" dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-define-map" "^7.1.0" + "@babel/helper-define-map" "^7.4.0" "@babel/helper-function-name" "^7.1.0" "@babel/helper-optimise-call-expression" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/helper-replace-supers" "^7.4.0" + "@babel/helper-split-export-declaration" "^7.4.0" globals "^11.1.0" "@babel/plugin-transform-computed-properties@^7.0.0-beta": @@ -372,8 +326,8 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-destructuring@^7.0.0-beta": - version "7.2.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.2.0.tgz#e75269b4b7889ec3a332cd0d0c8cff8fed0dc6f3" + version "7.4.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.3.tgz#1a95f5ca2bf2f91ef0648d5de38a8d472da4350f" dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -385,21 +339,21 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-flow-strip-types@^7.0.0-beta": - version "7.2.3" - resolved "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.2.3.tgz#e3ac2a594948454e7431c7db33e1d02d51b5cd69" + version "7.4.0" + resolved "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.4.0.tgz#f3c59eecff68c99b9c96eaafe4fe9d1fa8947138" dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-flow" "^7.2.0" "@babel/plugin-transform-for-of@^7.0.0-beta": - version "7.2.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz#ab7468befa80f764bb03d3cb5eef8cc998e1cad9" + version "7.4.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.3.tgz#c36ff40d893f2b8352202a2558824f70cd75e9fe" dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-function-name@^7.0.0-beta": - version "7.2.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz#f7930362829ff99a3174c39f0afcc024ef59731a" + version "7.4.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.3.tgz#130c27ec7fb4f0cba30e958989449e5ec8d22bbd" dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -411,10 +365,10 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-modules-commonjs@^7.0.0-beta": - version "7.2.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz#c4f1933f5991d5145e9cfad1dfd848ea1727f404" + version "7.4.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.3.tgz#3917f260463ac08f8896aa5bd54403f6e1fed165" dependencies: - "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-module-transforms" "^7.4.3" "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" @@ -425,10 +379,10 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-parameters@^7.0.0-beta": - version "7.2.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.2.0.tgz#0d5ad15dc805e2ea866df4dd6682bfe76d1408c2" + version "7.4.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.3.tgz#e5ff62929fdf4cf93e58badb5e2430303003800d" dependencies: - "@babel/helper-call-delegate" "^7.1.0" + "@babel/helper-call-delegate" "^7.4.0" "@babel/helper-get-function-arity" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" @@ -446,18 +400,18 @@ "@babel/plugin-syntax-jsx" "^7.2.0" "@babel/plugin-transform-react-jsx@^7.0.0-beta": - version "7.2.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.2.0.tgz#ca36b6561c4d3b45524f8efb6f0fbc9a0d1d622f" + version "7.3.0" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz#f2cab99026631c767e2745a5368b331cfe8f5290" dependencies: - "@babel/helper-builder-react-jsx" "^7.0.0" + "@babel/helper-builder-react-jsx" "^7.3.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-jsx" "^7.2.0" "@babel/plugin-transform-regenerator@^7.0.0-beta": - version "7.0.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz#5b41686b4ed40bef874d7ed6a84bdd849c13e0c1" + version "7.4.3" + resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.3.tgz#2a697af96887e2bbf5d303ab0221d139de5e739c" dependencies: - regenerator-transform "^0.13.3" + regenerator-transform "^0.13.4" "@babel/plugin-transform-shorthand-properties@^7.0.0-beta": version "7.2.0" @@ -479,37 +433,28 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/register@^7.0.0-beta": - version "7.0.0" - resolved "https://registry.npmjs.org/@babel/register/-/register-7.0.0.tgz#fa634bae1bfa429f60615b754fc1f1d745edd827" + version "7.4.0" + resolved "https://registry.npmjs.org/@babel/register/-/register-7.4.0.tgz#d9d0a621db268fb14200f2685a4f8924c822404c" dependencies: - core-js "^2.5.7" - find-cache-dir "^1.0.0" - home-or-tmp "^3.0.0" - lodash "^4.17.10" + core-js "^3.0.0" + find-cache-dir "^2.0.0" + lodash "^4.17.11" mkdirp "^0.5.1" pirates "^4.0.0" source-map-support "^0.5.9" "@babel/template@7.0.0-beta.44": version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f" dependencies: "@babel/code-frame" "7.0.0-beta.44" "@babel/types" "7.0.0-beta.44" babylon "7.0.0-beta.44" lodash "^4.2.0" -"@babel/template@^7.0.0-beta", "@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2": - version "7.2.2" - resolved "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907" - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.2.2" - "@babel/types" "^7.2.2" - -"@babel/template@^7.4.0": +"@babel/template@^7.0.0-beta", "@babel/template@^7.1.0", "@babel/template@^7.2.2", "@babel/template@^7.4.0": version "7.4.0" - resolved "http://registry.npm.taobao.org/@babel/template/download/@babel/template-7.4.0.tgz#12474e9c077bae585c5d835a95c0b0b790c25c8b" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.4.0.tgz#12474e9c077bae585c5d835a95c0b0b790c25c8b" dependencies: "@babel/code-frame" "^7.0.0" "@babel/parser" "^7.4.0" @@ -517,7 +462,7 @@ "@babel/traverse@7.0.0-beta.44": version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966" dependencies: "@babel/code-frame" "7.0.0-beta.44" "@babel/generator" "7.0.0-beta.44" @@ -530,29 +475,15 @@ invariant "^2.2.0" lodash "^4.2.0" -"@babel/traverse@^7.0.0-beta", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.2.2", "@babel/traverse@^7.2.3": - version "7.2.3" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz#7ff50cefa9c7c0bd2d81231fdac122f3957748d8" - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.2.2" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.0.0" - "@babel/parser" "^7.2.3" - "@babel/types" "^7.2.2" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.10" - -"@babel/traverse@^7.4.0": - version "7.4.0" - resolved "http://registry.npm.taobao.org/@babel/traverse/download/@babel/traverse-7.4.0.tgz#14006967dd1d2b3494cdd650c686db9daf0ddada" +"@babel/traverse@^7.0.0-beta", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.0", "@babel/traverse@^7.4.3": + version "7.4.3" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.3.tgz#1a01f078fc575d589ff30c0f71bf3c3d9ccbad84" dependencies: "@babel/code-frame" "^7.0.0" "@babel/generator" "^7.4.0" "@babel/helper-function-name" "^7.1.0" "@babel/helper-split-export-declaration" "^7.4.0" - "@babel/parser" "^7.4.0" + "@babel/parser" "^7.4.3" "@babel/types" "^7.4.0" debug "^4.1.0" globals "^11.1.0" @@ -560,23 +491,15 @@ "@babel/types@7.0.0-beta.44": version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757" dependencies: esutils "^2.0.2" lodash "^4.2.0" to-fast-properties "^2.0.0" -"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta", "@babel/types@^7.2.0", "@babel/types@^7.2.2": - version "7.2.2" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.2.2.tgz#44e10fc24e33af524488b716cdaee5360ea8ed1e" - dependencies: - esutils "^2.0.2" - lodash "^4.17.10" - to-fast-properties "^2.0.0" - -"@babel/types@^7.4.0": +"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.3.0", "@babel/types@^7.4.0": version "7.4.0" - resolved "http://registry.npm.taobao.org/@babel/types/download/@babel/types-7.4.0.tgz#670724f77d24cce6cc7d8cf64599d511d164894c" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.4.0.tgz#670724f77d24cce6cc7d8cf64599d511d164894c" dependencies: esutils "^2.0.2" lodash "^4.17.11" @@ -584,14 +507,14 @@ "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" - resolved "http://registry.npm.taobao.org/@mrmlnc/readdir-enhanced/download/@mrmlnc/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + resolved "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" dependencies: call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" "@nodelib/fs.stat@^1.1.2": version "1.1.3" - resolved "http://registry.npm.taobao.org/@nodelib/fs.stat/download/@nodelib/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" "@sindresorhus/is@^0.7.0": version "0.7.0" @@ -601,9 +524,9 @@ version "1.2.26" resolved "https://registry.npmjs.org/@tarojs/taro/-/taro-1.2.26.tgz#486c9acce62751e2e3110421a06c0e1bb7174034" -"@tarojs/taroize@1.2.27-beta.0": - version "1.2.27-beta.0" - resolved "https://registry.npmjs.org/@tarojs/taroize/-/taroize-1.2.27-beta.0.tgz#572b668e3b8fd6083c1c5c95cefc35657084d7b4" +"@tarojs/taroize@1.2.13": + version "1.2.13" + resolved "https://registry.npmjs.org/@tarojs/taroize/-/taroize-1.2.13.tgz#8f63dab0a7e9dc0f8ca5ef687573559a90532a8b" dependencies: "@babel/code-frame" "^7.0.0" babel-core "^6.26.3" @@ -616,9 +539,9 @@ lodash "^4.17.5" typescript "^3.0.1" -"@tarojs/transformer-wx@1.2.27-beta.0": - version "1.2.27-beta.0" - resolved "https://registry.npmjs.org/@tarojs/transformer-wx/-/transformer-wx-1.2.27-beta.0.tgz#3d639e8f236d8144a6184dff14a2f3e48dc80dc3" +"@tarojs/transformer-wx@1.2.13": + version "1.2.13" + resolved "https://registry.npmjs.org/@tarojs/transformer-wx/-/transformer-wx-1.2.13.tgz#a0d7f1754acd7d296f182db4c2fbc456bde277da" dependencies: "@babel/code-frame" "^7.0.0-beta.44" babel-core "^6.26.3" @@ -632,15 +555,12 @@ babel-plugin-syntax-dynamic-import "^6.18.0" babel-plugin-transform-class-properties "^6.24.1" babel-plugin-transform-define "^1.3.0" - babel-plugin-transform-do-expressions "^6.22.0" babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-export-extensions "^6.22.0" babel-plugin-transform-flow-strip-types "^6.22.0" babel-traverse "^6.26.0" babel-types "^6.26.0" eslint "^4.15.0" - eslint-plugin-react "7.10.0" - eslint-plugin-taro "1.2.27-beta.0" + eslint-plugin-taro "1.2.13" html "^1.0.0" lodash "^4.17.5" prettier "^1.14.2" @@ -695,13 +615,23 @@ dependencies: "@types/babel-types" "*" +"@types/caseless@*": + version "0.12.2" + resolved "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8" + "@types/ejs@^2.6.3": version "2.6.3" resolved "https://registry.npmjs.org/@types/ejs/-/ejs-2.6.3.tgz#b6509e9925d7eb5e95c8c73b6492e5baae7c1e6a" "@types/events@*": version "3.0.0" - resolved "http://registry.npm.taobao.org/@types/events/download/@types/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" + resolved "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" + +"@types/form-data@*": + version "2.2.1" + resolved "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz#ee2b3b8eaa11c0938289953606b745b738c54b1e" + dependencies: + "@types/node" "*" "@types/fs-extra@^5.0.4": version "5.0.5" @@ -711,7 +641,7 @@ "@types/glob@*", "@types/glob@^7.1.1": version "7.1.1" - resolved "http://registry.npm.taobao.org/@types/glob/download/@types/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" + resolved "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" dependencies: "@types/events" "*" "@types/minimatch" "*" @@ -733,16 +663,25 @@ "@types/minimatch@*": version "3.0.3" - resolved "http://registry.npm.taobao.org/@types/minimatch/download/@types/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" "@types/node@*": - version "11.12.2" - resolved "http://registry.npm.taobao.org/@types/node/download/@types/node-11.12.2.tgz#d7f302e74b10e9801d52852137f652d9ee235da8" + version "11.13.7" + resolved "https://registry.npmjs.org/@types/node/-/node-11.13.7.tgz#85dbb71c510442d00c0631f99dae957ce44fd104" "@types/node@^10.12.18": version "10.14.5" resolved "https://registry.npmjs.org/@types/node/-/node-10.14.5.tgz#27733a949f5d9972d87109297cffb62207ace70f" +"@types/request@^2.48.1": + version "2.48.1" + resolved "https://registry.npmjs.org/@types/request/-/request-2.48.1.tgz#e402d691aa6670fbbff1957b15f1270230ab42fa" + dependencies: + "@types/caseless" "*" + "@types/form-data" "*" + "@types/node" "*" + "@types/tough-cookie" "*" + "@types/shelljs@^0.8.5": version "0.8.5" resolved "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.5.tgz#1e507b2f6d1f893269bd3e851ec24419ef9beeea" @@ -750,20 +689,24 @@ "@types/glob" "*" "@types/node" "*" +"@types/tough-cookie@*": + version "2.3.5" + resolved "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz#9da44ed75571999b65c37b60c9b2b88db54c585d" + "@types/unist@*", "@types/unist@^2.0.0": version "2.0.3" - resolved "http://registry.npm.taobao.org/@types/unist/download/@types/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" + resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" "@types/vfile-message@*": version "1.0.1" - resolved "http://registry.npm.taobao.org/@types/vfile-message/download/@types/vfile-message-1.0.1.tgz#e1e9895cc6b36c462d4244e64e6d0b6eaf65355a" + resolved "https://registry.npmjs.org/@types/vfile-message/-/vfile-message-1.0.1.tgz#e1e9895cc6b36c462d4244e64e6d0b6eaf65355a" dependencies: "@types/node" "*" "@types/unist" "*" "@types/vfile@^3.0.0": version "3.0.2" - resolved "http://registry.npm.taobao.org/@types/vfile/download/@types/vfile-3.0.2.tgz#19c18cd232df11ce6fa6ad80259bc86c366b09b9" + resolved "https://registry.npmjs.org/@types/vfile/-/vfile-3.0.2.tgz#19c18cd232df11ce6fa6ad80259bc86c366b09b9" dependencies: "@types/node" "*" "@types/unist" "*" @@ -789,15 +732,15 @@ accepts@~1.3.3, accepts@~1.3.5: negotiator "0.6.1" acorn-globals@^4.1.0: - version "4.3.0" - resolved "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.0.tgz#e3b6f8da3c1552a95ae627571f7dd6923bb54103" + version "4.3.2" + resolved "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.2.tgz#4e2c2313a597fd589720395f6354b41cd5ec8006" dependencies: acorn "^6.0.1" acorn-walk "^6.0.1" acorn-jsx@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" dependencies: acorn "^3.0.4" @@ -807,41 +750,32 @@ acorn-walk@^6.0.1: acorn@^3.0.4: version "3.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + resolved "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" acorn@^5.5.0, acorn@^5.5.3: version "5.7.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + resolved "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" acorn@^6.0.1: - version "6.0.5" - resolved "https://registry.npmjs.org/acorn/-/acorn-6.0.5.tgz#81730c0815f3f3b34d8efa95cb7430965f4d887a" + version "6.1.1" + resolved "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" ajv-keywords@^2.1.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" ajv@^5.2.3, ajv@^5.3.0: version "5.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + resolved "https://registry.npmjs.org/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" -ajv@^6.5.5: - version "6.6.2" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz#caceccf474bf3fc3ce3b147443711a24063cc30d" - dependencies: - fast-deep-equal "^2.0.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^6.9.1: +ajv@^6.5.5, ajv@^6.9.1: version "6.10.0" - resolved "http://registry.npm.taobao.org/ajv/download/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" @@ -871,8 +805,8 @@ ansi-escapes@^1.1.0: resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" ansi-escapes@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + version "3.2.0" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" ansi-gray@^0.1.1: version "0.1.1" @@ -896,7 +830,7 @@ ansi-regex@^3.0.0: ansi-regex@^4.1.0: version "4.1.0" - resolved "http://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" ansi-styles@^2.2.1: version "2.2.1" @@ -999,7 +933,7 @@ array-filter@~0.0.0: array-find-index@^1.0.1: version "1.0.2" - resolved "http://registry.npm.taobao.org/array-find-index/download/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + resolved "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" array-includes@^3.0.3: version "3.0.3" @@ -1068,19 +1002,19 @@ astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" -async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" async-limiter@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" -async@^2.1.4, async@^2.4.0, async@^2.5.0: - version "2.6.1" - resolved "https://registry.npmjs.org/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" +async@^2.1.4, async@^2.4.0: + version "2.6.2" + resolved "https://registry.npmjs.org/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" dependencies: - lodash "^4.17.10" + lodash "^4.17.11" asynckit@^0.4.0: version "0.4.0" @@ -1102,11 +1036,11 @@ autoprefixer@^8.4.1: postcss-value-parser "^3.2.3" autoprefixer@^9.0.0: - version "9.5.0" - resolved "http://registry.npm.taobao.org/autoprefixer/download/autoprefixer-9.5.0.tgz#7e51d0355c11596e6cf9a0afc9a44e86d1596c70" + version "9.5.1" + resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.5.1.tgz#243b1267b67e7e947f28919d786b50d3bb0fb357" dependencies: - browserslist "^4.4.2" - caniuse-lite "^1.0.30000947" + browserslist "^4.5.4" + caniuse-lite "^1.0.30000957" normalize-range "^0.1.2" num2fraction "^1.2.2" postcss "^7.0.14" @@ -1130,7 +1064,7 @@ babel-code-frame@^6.22.0, babel-code-frame@^6.26.0, babel-code-frame@^6.8.0: babel-core@6.10.4: version "6.10.4" - resolved "http://registry.npmjs.org/babel-core/-/babel-core-6.10.4.tgz#283f2212bb03d4e5cd7498b9886efbf6fc2e238e" + resolved "https://registry.npmjs.org/babel-core/-/babel-core-6.10.4.tgz#283f2212bb03d4e5cd7498b9886efbf6fc2e238e" dependencies: babel-code-frame "^6.8.0" babel-generator "^6.9.0" @@ -1180,7 +1114,7 @@ babel-core@^6.0.0, babel-core@^6.24.1, babel-core@^6.26.0, babel-core@^6.26.3, b babel-eslint@^8.2.3: version "8.2.6" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.6.tgz#6270d0c73205628067c0f7ae1693a9e797acefd9" + resolved "https://registry.npmjs.org/babel-eslint/-/babel-eslint-8.2.6.tgz#6270d0c73205628067c0f7ae1693a9e797acefd9" dependencies: "@babel/code-frame" "7.0.0-beta.44" "@babel/traverse" "7.0.0-beta.44" @@ -1372,8 +1306,8 @@ babel-plugin-check-es2015-constants@^6.22.0, babel-plugin-check-es2015-constants babel-runtime "^6.22.0" babel-plugin-danger-remove-unused-import@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/babel-plugin-danger-remove-unused-import/-/babel-plugin-danger-remove-unused-import-1.1.1.tgz#312b59bea8bb59ebfe97d2cfab56c23a73c363b1" + version "1.1.2" + resolved "https://registry.npmjs.org/babel-plugin-danger-remove-unused-import/-/babel-plugin-danger-remove-unused-import-1.1.2.tgz#ac39c30edfe524ef8cfc411fec5edc479d19e132" babel-plugin-external-helpers@^6.22.0: version "6.22.0" @@ -1429,11 +1363,11 @@ babel-plugin-syntax-class-constructor-call@^6.18.0: babel-plugin-syntax-class-properties@^6.5.0, babel-plugin-syntax-class-properties@^6.8.0: version "6.13.0" - resolved "http://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + resolved "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" babel-plugin-syntax-decorators@^6.1.18, babel-plugin-syntax-decorators@^6.13.0: version "6.13.0" - resolved "http://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" + resolved "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" babel-plugin-syntax-do-expressions@^6.8.0: version "6.13.0" @@ -1441,7 +1375,7 @@ babel-plugin-syntax-do-expressions@^6.8.0: babel-plugin-syntax-dynamic-import@^6.18.0: version "6.18.0" - resolved "http://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + resolved "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" @@ -1453,7 +1387,7 @@ babel-plugin-syntax-export-extensions@^6.8.0: babel-plugin-syntax-flow@^6.18.0, babel-plugin-syntax-flow@^6.5.0, babel-plugin-syntax-flow@^6.8.0: version "6.18.0" - resolved "http://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" + resolved "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" babel-plugin-syntax-function-bind@^6.8.0: version "6.13.0" @@ -1461,7 +1395,7 @@ babel-plugin-syntax-function-bind@^6.8.0: babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.5.0, babel-plugin-syntax-jsx@^6.8.0: version "6.18.0" - resolved "http://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + resolved "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" babel-plugin-syntax-object-rest-spread@^6.13.0, babel-plugin-syntax-object-rest-spread@^6.8.0: version "6.13.0" @@ -1531,10 +1465,10 @@ babel-plugin-transform-decorators@^6.24.1: babel-types "^6.24.1" babel-plugin-transform-define@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/babel-plugin-transform-define/-/babel-plugin-transform-define-1.3.0.tgz#94c5f9459c810c738cc7c50cbd44a31829d6f319" + version "1.3.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-define/-/babel-plugin-transform-define-1.3.1.tgz#b21b7bad3b84cf8e3f07cdc8c660b99cbbc01213" dependencies: - lodash "4.17.4" + lodash "^4.17.11" traverse "0.6.6" babel-plugin-transform-do-expressions@^6.22.0: @@ -2043,7 +1977,7 @@ babel-types@^6.0.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24. babylon@7.0.0-beta.44: version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d" + resolved "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d" babylon@^6.1.21, babylon@^6.18.0, babylon@^6.7.0: version "6.18.0" @@ -2055,7 +1989,7 @@ babylon@^7.0.0-beta: bail@^1.0.0: version "1.0.3" - resolved "http://registry.npm.taobao.org/bail/download/bail-1.0.3.tgz#63cfb9ddbac829b02a3128cd53224be78e6c21a3" + resolved "https://registry.npmjs.org/bail/-/bail-1.0.3.tgz#63cfb9ddbac829b02a3128cd53224be78e6c21a3" balanced-match@^1.0.0: version "1.0.0" @@ -2111,16 +2045,16 @@ better-babel-generator@^6.26.1: trim-right "^1.0.1" big-integer@^1.6.7: - version "1.6.40" - resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.40.tgz#02e4cd4d6e266c4d9ece2469c05cb6439149fc78" + version "1.6.43" + resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.43.tgz#8ac15bf13e93e509500859061233e19d8d0d99d1" big.js@^5.2.2: version "5.2.2" resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" binary-extensions@^1.0.0: - version "1.12.0" - resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" + version "1.13.1" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" boxen@^1.2.1: version "1.3.0" @@ -2161,7 +2095,7 @@ braces@^1.8.2: preserve "^0.2.0" repeat-element "^1.1.2" -braces@^2.3.0, braces@^2.3.1: +braces@^2.3.1, braces@^2.3.2: version "2.3.2" resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" dependencies: @@ -2193,13 +2127,13 @@ browserslist@^3.2.6, browserslist@^3.2.8: caniuse-lite "^1.0.30000844" electron-to-chromium "^1.3.47" -browserslist@^4.4.2: - version "4.5.3" - resolved "http://registry.npm.taobao.org/browserslist/download/browserslist-4.5.3.tgz#969495c410314bc89f14e748505e58be968080f1" +browserslist@^4.5.4: + version "4.5.5" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.5.5.tgz#fe1a352330d2490d5735574c149a85bc18ef9b82" dependencies: - caniuse-lite "^1.0.30000955" - electron-to-chromium "^1.3.122" - node-releases "^1.1.12" + caniuse-lite "^1.0.30000960" + electron-to-chromium "^1.3.124" + node-releases "^1.1.14" bser@^2.0.0: version "2.0.0" @@ -2218,6 +2152,10 @@ buffer-alloc@^1.2.0: buffer-alloc-unsafe "^1.1.0" buffer-fill "^1.0.0" +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + buffer-equal@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" @@ -2230,7 +2168,7 @@ buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" -builtin-modules@^1.0.0, builtin-modules@^1.1.1: +builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -2266,23 +2204,23 @@ cacheable-request@^2.1.1: call-me-maybe@^1.0.1: version "1.0.1" - resolved "http://registry.npm.taobao.org/call-me-maybe/download/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + resolved "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" caller-callsite@^2.0.0: version "2.0.0" - resolved "http://registry.npm.taobao.org/caller-callsite/download/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + resolved "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" dependencies: callsites "^2.0.0" caller-path@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + resolved "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" dependencies: callsites "^0.2.0" caller-path@^2.0.0: version "2.0.0" - resolved "http://registry.npm.taobao.org/caller-path/download/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + resolved "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" dependencies: caller-callsite "^2.0.0" @@ -2303,7 +2241,7 @@ callsite@^1.0.0: callsites@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + resolved "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" callsites@^2.0.0: version "2.0.0" @@ -2318,7 +2256,7 @@ camelcase-keys@^2.0.0: camelcase-keys@^4.0.0: version "4.2.0" - resolved "http://registry.npm.taobao.org/camelcase-keys/download/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" + resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" dependencies: camelcase "^4.1.0" map-obj "^2.0.0" @@ -2332,13 +2270,13 @@ camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" -caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000864: - version "1.0.30000887" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000887.tgz#1769458c27bbdcf61b0cb6b5072bb6cd11fd9c23" +camelize@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" -caniuse-lite@^1.0.30000947, caniuse-lite@^1.0.30000955: - version "1.0.30000955" - resolved "http://registry.npm.taobao.org/caniuse-lite/download/caniuse-lite-1.0.30000955.tgz#360fdb9a1e41d6dd996130411334e44a39e4446d" +caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000864, caniuse-lite@^1.0.30000957, caniuse-lite@^1.0.30000960: + version "1.0.30000962" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000962.tgz#6c10c3ab304b89bea905e66adf98c0905088ee44" capture-exit@^1.2.0: version "1.2.0" @@ -2356,9 +2294,9 @@ caseless@~0.12.0: ccount@^1.0.0: version "1.0.3" - resolved "http://registry.npm.taobao.org/ccount/download/ccount-1.0.3.tgz#f1cec43f332e2ea5a569fd46f9f5bde4e6102aff" + resolved "https://registry.npmjs.org/ccount/-/ccount-1.0.3.tgz#f1cec43f332e2ea5a569fd46f9f5bde4e6102aff" -chalk@2.4.2, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.0, chalk@^2.4.2: +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" dependencies: @@ -2368,7 +2306,7 @@ chalk@2.4.2, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.0, chalk@^2.4.2: chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" - resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: ansi-styles "^2.2.1" escape-string-regexp "^1.0.2" @@ -2376,54 +2314,45 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.1, chalk@^2.4.1: - version "2.4.1" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - character-entities-html4@^1.0.0: version "1.1.2" - resolved "http://registry.npm.taobao.org/character-entities-html4/download/character-entities-html4-1.1.2.tgz#c44fdde3ce66b52e8d321d6c1bf46101f0150610" + resolved "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.2.tgz#c44fdde3ce66b52e8d321d6c1bf46101f0150610" character-entities-legacy@^1.0.0: version "1.1.2" - resolved "http://registry.npm.taobao.org/character-entities-legacy/download/character-entities-legacy-1.1.2.tgz#7c6defb81648498222c9855309953d05f4d63a9c" + resolved "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.2.tgz#7c6defb81648498222c9855309953d05f4d63a9c" character-entities@^1.0.0: version "1.2.2" - resolved "http://registry.npm.taobao.org/character-entities/download/character-entities-1.2.2.tgz#58c8f371c0774ef0ba9b2aca5f00d8f100e6e363" + resolved "https://registry.npmjs.org/character-entities/-/character-entities-1.2.2.tgz#58c8f371c0774ef0ba9b2aca5f00d8f100e6e363" character-reference-invalid@^1.0.0: version "1.1.2" - resolved "http://registry.npm.taobao.org/character-reference-invalid/download/character-reference-invalid-1.1.2.tgz#21e421ad3d84055952dab4a43a04e73cd425d3ed" + resolved "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.2.tgz#21e421ad3d84055952dab4a43a04e73cd425d3ed" chardet@^0.4.0: version "0.4.2" resolved "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" chokidar@^2.0.3: - version "2.0.4" - resolved "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + version "2.1.5" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-2.1.5.tgz#0ae8434d962281a5f56c72869e79cb6d9d86ad4d" dependencies: anymatch "^2.0.0" - async-each "^1.0.0" - braces "^2.3.0" + async-each "^1.0.1" + braces "^2.3.2" glob-parent "^3.1.0" - inherits "^2.0.1" + inherits "^2.0.3" is-binary-path "^1.0.0" is-glob "^4.0.0" - lodash.debounce "^4.0.8" - normalize-path "^2.1.1" + normalize-path "^3.0.0" path-is-absolute "^1.0.0" - readdirp "^2.0.0" - upath "^1.0.5" + readdirp "^2.2.1" + upath "^1.1.1" optionalDependencies: - fsevents "^1.2.2" + fsevents "^1.2.7" -chownr@^1.0.1: +chownr@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" @@ -2501,7 +2430,7 @@ clone-buffer@^1.0.0: clone-regexp@^1.0.0: version "1.0.1" - resolved "http://registry.npm.taobao.org/clone-regexp/download/clone-regexp-1.0.1.tgz#051805cd33173375d82118fc0918606da39fd60f" + resolved "https://registry.npmjs.org/clone-regexp/-/clone-regexp-1.0.1.tgz#051805cd33173375d82118fc0918606da39fd60f" dependencies: is-regexp "^1.0.0" is-supported-regexp-flag "^1.0.0" @@ -2546,7 +2475,7 @@ code-point-at@^1.0.0: collapse-white-space@^1.0.2: version "1.0.4" - resolved "http://registry.npm.taobao.org/collapse-white-space/download/collapse-white-space-1.0.4.tgz#ce05cf49e54c3277ae573036a26851ba430a0091" + resolved "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.4.tgz#ce05cf49e54c3277ae573036a26851ba430a0091" collection-visit@^1.0.0: version "1.0.0" @@ -2575,45 +2504,37 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.12.1: +commander@^2.12.1, commander@^2.19.0, commander@^2.9.0, commander@~2.20.0: version "2.20.0" resolved "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" -commander@^2.19.0, commander@^2.9.0: - version "2.19.0" - resolved "http://registry.npm.taobao.org/commander/download/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - commander@~2.13.0: version "2.13.0" resolved "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" -commander@~2.17.1: - version "2.17.1" - resolved "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" - commondir@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" component-emitter@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + version "1.3.0" + resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" -compressible@~2.0.14: - version "2.0.15" - resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz#857a9ab0a7e5a07d8d837ed43fe2defff64fe212" +compressible@~2.0.16: + version "2.0.16" + resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.16.tgz#a49bf9858f3821b64ce1be0296afc7380466a77f" dependencies: - mime-db ">= 1.36.0 < 2" + mime-db ">= 1.38.0 < 2" compression@^1.7.1: - version "1.7.3" - resolved "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz#27e0e176aaf260f7f2c2813c3e440adb9f1993db" + version "1.7.4" + resolved "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" dependencies: accepts "~1.3.5" bytes "3.0.0" - compressible "~2.0.14" + compressible "~2.0.16" debug "2.6.9" - on-headers "~1.0.1" + on-headers "~1.0.2" safe-buffer "5.1.2" vary "~1.1.2" @@ -2672,13 +2593,13 @@ core-js@^1.0.0: version "1.2.7" resolved "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" -core-js@^2.2.2, core-js@^2.4.1, core-js@^2.5.7: - version "2.6.2" - resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.2.tgz#267988d7268323b349e20b4588211655f0e83944" +core-js@^2.2.2, core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0: + version "2.6.5" + resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz#44bc8d249e7fb2ff5d00e0341a7ffb94fbf67895" -core-js@^2.4.0, core-js@^2.5.0: - version "2.5.7" - resolved "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" +core-js@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/core-js/-/core-js-3.0.1.tgz#1343182634298f7f38622f95e73f54e48ddf4738" core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -2686,7 +2607,7 @@ core-util-is@1.0.2, core-util-is@~1.0.0: cosmiconfig@^5.0.0: version "5.2.0" - resolved "http://registry.npm.taobao.org/cosmiconfig/download/cosmiconfig-5.2.0.tgz#45038e4d28a7fe787203aede9c25bca4a08b12c8" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.0.tgz#45038e4d28a7fe787203aede9c25bca4a08b12c8" dependencies: import-fresh "^2.0.0" is-directory "^0.3.1" @@ -2753,22 +2674,22 @@ css-selector-tokenizer@^0.7.0: regexpu-core "^1.0.0" css-to-react-native-transform@^1.4.0: - version "1.7.0" - resolved "https://registry.npmjs.org/css-to-react-native-transform/-/css-to-react-native-transform-1.7.0.tgz#1e12deb806644be88583ac3751fad68b0e321437" + version "1.9.0" + resolved "https://registry.npmjs.org/css-to-react-native-transform/-/css-to-react-native-transform-1.9.0.tgz#63369f479048ab7662f5320f8010840ad91344e7" dependencies: - css "^2.2.3" + css "^2.2.4" css-mediaquery "^0.1.2" - css-to-react-native "^2.2.1" + css-to-react-native "^2.3.0" -css-to-react-native@^2.2.1: - version "2.2.1" - resolved "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.2.1.tgz#7f3f4c95de65501b8720c87bf0caf1f39073b88e" +css-to-react-native@^2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.0.tgz#bf80d24ec4a08e430306ef429c0586e6ed5485f7" dependencies: + camelize "^1.0.0" css-color-keywords "^1.0.0" - fbjs "^0.8.5" postcss-value-parser "^3.3.0" -css@^2.2.3: +css@^2.2.4: version "2.2.4" resolved "https://registry.npmjs.org/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" dependencies: @@ -2782,12 +2703,12 @@ cssesc@^0.1.0: resolved "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": - version "0.3.4" - resolved "https://registry.npmjs.org/cssom/-/cssom-0.3.4.tgz#8cd52e8a3acfd68d3aed38ee0a640177d2f9d797" + version "0.3.6" + resolved "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz#f85206cee04efa841f3c5982a74ba96ab20d65ad" cssstyle@^1.0.0: - version "1.1.1" - resolved "https://registry.npmjs.org/cssstyle/-/cssstyle-1.1.1.tgz#18b038a9c44d65f7a8e428a653b9f6fe42faf5fb" + version "1.2.2" + resolved "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.2.tgz#427ea4d585b18624f6fdbf9de7a2a1a3ba713077" dependencies: cssom "0.3.x" @@ -2797,7 +2718,7 @@ cuint@^0.2.2: currently-unhandled@^0.4.1: version "0.4.1" - resolved "http://registry.npm.taobao.org/currently-unhandled/download/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + resolved "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" dependencies: array-find-index "^1.0.1" @@ -2815,7 +2736,7 @@ data-urls@^1.0.0: whatwg-mimetype "^2.2.0" whatwg-url "^7.0.0" -debug@2.6.9, debug@^2.1.1, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: +debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: @@ -2829,13 +2750,13 @@ debug@^3.1.0: debug@^4.0.0, debug@^4.1.0: version "4.1.1" - resolved "http://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + resolved "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" dependencies: ms "^2.1.1" decamelize-keys@^1.0.0: version "1.1.0" - resolved "http://registry.npm.taobao.org/decamelize-keys/download/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" + resolved "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" dependencies: decamelize "^1.1.0" map-obj "^1.0.0" @@ -2961,16 +2882,9 @@ diff@^3.2.0: version "3.5.0" resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" -dir-glob@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" - dependencies: - arrify "^1.0.1" - path-type "^3.0.0" - -dir-glob@^2.2.1: +dir-glob@^2.0.0, dir-glob@^2.2.2: version "2.2.2" - resolved "http://registry.npm.taobao.org/dir-glob/download/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" dependencies: path-type "^3.0.0" @@ -2996,7 +2910,7 @@ doctrine@^2.1.0: dom-serializer@0: version "0.1.1" - resolved "http://registry.npm.taobao.org/dom-serializer/download/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" + resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" dependencies: domelementtype "^1.3.0" entities "^1.1.1" @@ -3007,7 +2921,7 @@ dom-walk@^0.1.0: domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: version "1.3.1" - resolved "http://registry.npm.taobao.org/domelementtype/download/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" domexception@^1.0.1: version "1.0.1" @@ -3017,13 +2931,13 @@ domexception@^1.0.1: domhandler@^2.3.0: version "2.4.2" - resolved "http://registry.npm.taobao.org/domhandler/download/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + resolved "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" dependencies: domelementtype "1" domutils@^1.5.1: version "1.7.0" - resolved "http://registry.npm.taobao.org/domutils/download/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + resolved "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" dependencies: dom-serializer "0" domelementtype "1" @@ -3039,8 +2953,8 @@ duplexer3@^0.1.4: resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" duplexify@^3.6.0: - version "3.6.0" - resolved "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz#592903f5d80b38d037220541264d69a198fb3410" + version "3.7.1" + resolved "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" dependencies: end-of-stream "^1.0.0" inherits "^2.0.1" @@ -3062,17 +2976,13 @@ ejs@^2.5.9, ejs@^2.6.1: version "2.6.1" resolved "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" -electron-to-chromium@^1.3.122: - version "1.3.122" - resolved "http://registry.npm.taobao.org/electron-to-chromium/download/electron-to-chromium-1.3.122.tgz#b32a0805f48557bd3c3b8104eadc7fa511b14a9a" - -electron-to-chromium@^1.3.47: - version "1.3.71" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.71.tgz#baecb282e8b27247bbfcf2f3e0254d6fe9a76789" +electron-to-chromium@^1.3.124, electron-to-chromium@^1.3.47: + version "1.3.125" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.125.tgz#dbde0e95e64ebe322db0eca764d951f885a5aff2" emoji-regex@^7.0.1: version "7.0.3" - resolved "http://registry.npm.taobao.org/emoji-regex/download/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" emojis-list@^2.0.0: version "2.1.0" @@ -3096,7 +3006,7 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: entities@^1.1.1: version "1.1.2" - resolved "http://registry.npm.taobao.org/entities/download/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + resolved "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" envinfo@^3.0.0: version "3.11.1" @@ -3114,7 +3024,7 @@ envinfo@^6.0.1: error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.2" - resolved "http://registry.npm.taobao.org/error-ex/download/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" dependencies: is-arrayish "^0.2.1" @@ -3159,8 +3069,8 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" escodegen@^1.9.1: - version "1.11.0" - resolved "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589" + version "1.11.1" + resolved "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz#c485ff8d6b4cdb89e27f4a856e91f118401ca510" dependencies: esprima "^3.1.3" estraverse "^4.2.0" @@ -3215,15 +3125,6 @@ eslint-plugin-react-native@^3.2.1: dependencies: eslint-plugin-react-native-globals "^0.1.1" -eslint-plugin-react@7.10.0: - version "7.10.0" - resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.10.0.tgz#af5c1fef31c4704db02098f9be18202993828b50" - dependencies: - doctrine "^2.1.0" - has "^1.0.3" - jsx-ast-utils "^2.0.1" - prop-types "^15.6.2" - eslint-plugin-react@^7.4.0: version "7.12.4" resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz#b1ecf26479d61aee650da612e425c53a99f48c8c" @@ -3236,15 +3137,15 @@ eslint-plugin-react@^7.4.0: prop-types "^15.6.2" resolve "^1.9.0" -eslint-plugin-taro@1.2.26, eslint-plugin-taro@^1.1.4: - version "1.2.26" - resolved "https://registry.npmjs.org/eslint-plugin-taro/-/eslint-plugin-taro-1.2.26.tgz#19bcbe9838ee744dc33925d4d9b9690c8606c0d5" +eslint-plugin-taro@1.2.13: + version "1.2.13" + resolved "https://registry.npmjs.org/eslint-plugin-taro/-/eslint-plugin-taro-1.2.13.tgz#e6a90a50fa0f3fef495e36e9135fab6db8bcc785" dependencies: has "^1.0.1" -eslint-plugin-taro@1.2.27-beta.0: - version "1.2.27-beta.0" - resolved "https://registry.npmjs.org/eslint-plugin-taro/-/eslint-plugin-taro-1.2.27-beta.0.tgz#cc1bef2d8310408a665981eb7fc466af7c96a16c" +eslint-plugin-taro@1.2.26, eslint-plugin-taro@^1.1.4: + version "1.2.26" + resolved "https://registry.npmjs.org/eslint-plugin-taro/-/eslint-plugin-taro-1.2.26.tgz#19bcbe9838ee744dc33925d4d9b9690c8606c0d5" dependencies: has "^1.0.1" @@ -3263,7 +3164,7 @@ eslint-scope@3.7.1: eslint-scope@^3.7.1: version "3.7.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.3.tgz#bb507200d3d17f60247636160b4826284b108535" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz#bb507200d3d17f60247636160b4826284b108535" dependencies: esrecurse "^4.1.0" estraverse "^4.1.1" @@ -3274,7 +3175,7 @@ eslint-visitor-keys@^1.0.0: eslint@^4.15.0: version "4.19.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" + resolved "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" dependencies: ajv "^5.3.0" babel-code-frame "^6.22.0" @@ -3317,7 +3218,7 @@ eslint@^4.15.0: espree@^3.5.4: version "3.5.4" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + resolved "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" dependencies: acorn "^5.5.0" acorn-jsx "^3.0.0" @@ -3332,7 +3233,7 @@ esprima@^4.0.0: esquery@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" dependencies: estraverse "^4.0.0" @@ -3408,7 +3309,7 @@ execa@^0.8.0: execall@^1.0.0: version "1.0.0" - resolved "http://registry.npm.taobao.org/execall/download/execall-1.0.0.tgz#73d0904e395b3cab0658b08d09ec25307f29bb73" + resolved "https://registry.npmjs.org/execall/-/execall-1.0.0.tgz#73d0904e395b3cab0658b08d09ec25307f29bb73" dependencies: clone-regexp "^1.0.0" @@ -3486,7 +3387,7 @@ extend@^3.0.0, extend@~3.0.2: external-editor@^2.0.4, external-editor@^2.1.0: version "2.2.0" - resolved "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + resolved "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" dependencies: chardet "^0.4.0" iconv-lite "^0.4.17" @@ -3530,7 +3431,7 @@ fancy-log@^1.3.2: fast-deep-equal@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" fast-deep-equal@^2.0.1: version "2.0.1" @@ -3538,7 +3439,7 @@ fast-deep-equal@^2.0.1: fast-glob@^2.2.6: version "2.2.6" - resolved "http://registry.npm.taobao.org/fast-glob/download/fast-glob-2.2.6.tgz#a5d5b697ec8deda468d85a74035290a025a95295" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.6.tgz#a5d5b697ec8deda468d85a74035290a025a95295" dependencies: "@mrmlnc/readdir-enhanced" "^2.2.1" "@nodelib/fs.stat" "^1.1.2" @@ -3567,7 +3468,7 @@ fb-watchman@^2.0.0: fbjs-css-vars@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" + resolved "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" fbjs-scripts@^0.8.1: version "0.8.3" @@ -3584,7 +3485,7 @@ fbjs-scripts@^0.8.1: semver "^5.1.0" through2 "^2.0.0" -fbjs@^0.8.14, fbjs@^0.8.5, fbjs@^0.8.9: +fbjs@^0.8.14, fbjs@^0.8.9: version "0.8.17" resolved "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" dependencies: @@ -3598,7 +3499,7 @@ fbjs@^0.8.14, fbjs@^0.8.5, fbjs@^0.8.9: fbjs@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-1.0.0.tgz#52c215e0883a3c86af2a7a776ed51525ae8e0a5a" + resolved "https://registry.npmjs.org/fbjs/-/fbjs-1.0.0.tgz#52c215e0883a3c86af2a7a776ed51525ae8e0a5a" dependencies: core-js "^2.4.1" fbjs-css-vars "^1.0.0" @@ -3609,6 +3510,12 @@ fbjs@^1.0.0: setimmediate "^1.0.5" ua-parser-js "^0.7.18" +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + dependencies: + pend "~1.2.0" + figures@^1.3.5: version "1.7.0" resolved "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" @@ -3631,7 +3538,7 @@ file-entry-cache@^2.0.0: file-entry-cache@^4.0.0: version "4.0.0" - resolved "http://registry.npm.taobao.org/file-entry-cache/download/file-entry-cache-4.0.0.tgz#633567d15364aefe0b299e1e217735e8f3a9f6e8" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-4.0.0.tgz#633567d15364aefe0b299e1e217735e8f3a9f6e8" dependencies: flat-cache "^2.0.1" @@ -3677,13 +3584,13 @@ finalhandler@1.1.0: statuses "~1.3.1" unpipe "~1.0.0" -find-cache-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" +find-cache-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" dependencies: commondir "^1.0.1" - make-dir "^1.0.0" - pkg-dir "^2.0.0" + make-dir "^2.0.0" + pkg-dir "^3.0.0" find-up@^1.0.0: version "1.1.2" @@ -3698,6 +3605,12 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + dependencies: + locate-path "^3.0.0" + first-chunk-stream@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz#1bdecdb8e083c0664b91945581577a43a9f31d70" @@ -3715,7 +3628,7 @@ flat-cache@^1.2.1: flat-cache@^2.0.1: version "2.0.1" - resolved "http://registry.npm.taobao.org/flat-cache/download/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" dependencies: flatted "^2.0.0" rimraf "2.6.3" @@ -3723,14 +3636,14 @@ flat-cache@^2.0.1: flatted@^2.0.0: version "2.0.0" - resolved "http://registry.npm.taobao.org/flatted/download/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" + resolved "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" flush-write-stream@^1.0.2: - version "1.0.3" - resolved "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" + version "1.1.1" + resolved "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" dependencies: - inherits "^2.0.1" - readable-stream "^2.0.4" + inherits "^2.0.3" + readable-stream "^2.3.6" for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" @@ -3804,12 +3717,12 @@ fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" -fsevents@^1.2.2, fsevents@^1.2.3: - version "1.2.4" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" +fsevents@^1.2.3, fsevents@^1.2.7: + version "1.2.8" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-1.2.8.tgz#57ea5320f762cd4696e5e8e87120eccc8b11cacf" dependencies: - nan "^2.9.2" - node-pre-gyp "^0.10.0" + nan "^2.12.1" + node-pre-gyp "^0.12.0" function-bind@^1.0.2, function-bind@^1.1.1: version "1.1.1" @@ -3858,7 +3771,7 @@ get-stdin@^4.0.1: get-stdin@^6.0.0: version "6.0.0" - resolved "http://registry.npm.taobao.org/get-stdin/download/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" get-stream@3.0.0, get-stream@^3.0.0: version "3.0.0" @@ -3915,7 +3828,7 @@ glob-stream@^6.1.0: glob-to-regexp@^0.3.0: version "0.3.0" - resolved "http://registry.npm.taobao.org/glob-to-regexp/download/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" glob@^6.0.1: version "6.0.4" @@ -3927,7 +3840,7 @@ glob@^6.0.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: +glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: version "7.1.3" resolved "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" dependencies: @@ -3954,7 +3867,7 @@ global-modules@^1.0.0: global-modules@^2.0.0: version "2.0.0" - resolved "http://registry.npm.taobao.org/global-modules/download/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + resolved "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" dependencies: global-prefix "^3.0.0" @@ -3970,7 +3883,7 @@ global-prefix@^1.0.1: global-prefix@^3.0.0: version "3.0.0" - resolved "http://registry.npm.taobao.org/global-prefix/download/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" dependencies: ini "^1.3.5" kind-of "^6.0.2" @@ -3983,13 +3896,9 @@ global@^4.3.0: min-document "^2.19.0" process "~0.5.1" -globals@^11.0.1: +globals@^11.0.1, globals@^11.1.0: version "11.11.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.11.0.tgz#dcf93757fa2de5486fbeed7118538adf789e9c2e" - -globals@^11.1.0: - version "11.10.0" - resolved "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz#1e09776dffda5e01816b3bb4077c8b59c24eaa50" + resolved "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz#dcf93757fa2de5486fbeed7118538adf789e9c2e" globals@^9.18.0: version "9.18.0" @@ -4018,12 +3927,12 @@ globby@^7.1.1: slash "^1.0.0" globby@^9.0.0: - version "9.1.0" - resolved "http://registry.npm.taobao.org/globby/download/globby-9.1.0.tgz#e90f4d5134109e6d855abdd31bdb1b085428592e" + version "9.2.0" + resolved "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" dependencies: "@types/glob" "^7.1.1" array-union "^1.0.2" - dir-glob "^2.2.1" + dir-glob "^2.2.2" fast-glob "^2.2.6" glob "^7.1.3" ignore "^4.0.3" @@ -4032,11 +3941,11 @@ globby@^9.0.0: globjoin@^0.1.4: version "0.1.4" - resolved "http://registry.npm.taobao.org/globjoin/download/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43" + resolved "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43" gonzales-pe@^4.2.3: version "4.2.4" - resolved "http://registry.npm.taobao.org/gonzales-pe/download/gonzales-pe-4.2.4.tgz#356ae36a312c46fe0f1026dd6cb539039f8500d2" + resolved "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.2.4.tgz#356ae36a312c46fe0f1026dd6cb539039f8500d2" dependencies: minimist "1.1.x" @@ -4078,11 +3987,7 @@ got@^8.3.1: url-parse-lax "^3.0.0" url-to-options "^1.0.1" -graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: - version "4.1.11" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - -graceful-fs@^4.1.3, graceful-fs@^4.1.5: +graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.5, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.15" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" @@ -4091,10 +3996,10 @@ growly@^1.3.0: resolved "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" handlebars@^4.0.3: - version "4.0.12" - resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" + version "4.1.2" + resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67" dependencies: - async "^2.5.0" + neo-async "^2.6.0" optimist "^0.6.1" source-map "^0.6.1" optionalDependencies: @@ -4199,10 +4104,6 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" -home-or-tmp@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-3.0.0.tgz#57a8fe24cf33cdd524860a15821ddc25c86671fb" - homedir-polyfill@^1.0.1: version "1.0.3" resolved "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" @@ -4221,7 +4122,7 @@ html-encoding-sniffer@^1.0.2: html-tags@^2.0.0: version "2.0.0" - resolved "http://registry.npm.taobao.org/html-tags/download/html-tags-2.0.0.tgz#10b30a386085f43cede353cc8fa7cb0deeea668b" + resolved "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz#10b30a386085f43cede353cc8fa7cb0deeea668b" html@^1.0.0: version "1.0.0" @@ -4231,7 +4132,7 @@ html@^1.0.0: htmlparser2@^3.10.0: version "3.10.1" - resolved "http://registry.npm.taobao.org/htmlparser2/download/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" dependencies: domelementtype "^1.3.1" domhandler "^2.3.0" @@ -4285,15 +4186,15 @@ ignore-walk@^3.0.1: ignore@^3.3.3, ignore@^3.3.5: version "3.3.10" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + resolved "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" ignore@^4.0.3: version "4.0.6" - resolved "http://registry.npm.taobao.org/ignore/download/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" ignore@^5.0.4: - version "5.0.6" - resolved "http://registry.npm.taobao.org/ignore/download/ignore-5.0.6.tgz#562dacc7ec27d672dde433aa683c543b24c17694" + version "5.1.1" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.1.1.tgz#2fc6b8f518aff48fef65a7f348ed85632448e4a5" image-size@^0.6.0: version "0.6.3" @@ -4301,7 +4202,7 @@ image-size@^0.6.0: import-fresh@^2.0.0: version "2.0.0" - resolved "http://registry.npm.taobao.org/import-fresh/download/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" dependencies: caller-path "^2.0.0" resolve-from "^3.0.0" @@ -4312,7 +4213,7 @@ import-lazy@^2.1.0: import-lazy@^3.1.0: version "3.1.0" - resolved "http://registry.npm.taobao.org/import-lazy/download/import-lazy-3.1.0.tgz#891279202c8a2280fdbd6674dbd8da1a1dfc67cc" + resolved "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz#891279202c8a2280fdbd6674dbd8da1a1dfc67cc" import-local@^1.0.0: version "1.0.0" @@ -4333,11 +4234,11 @@ indent-string@^2.1.0: indent-string@^3.0.0: version "3.2.0" - resolved "http://registry.npm.taobao.org/indent-string/download/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" indexes-of@^1.0.1: version "1.0.1" - resolved "http://registry.npm.taobao.org/indexes-of/download/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + resolved "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" inflight@^1.0.4: version "1.0.6" @@ -4393,7 +4294,7 @@ inquirer@^3.0.6: inquirer@^5.2.0: version "5.2.0" - resolved "http://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz#db350c2b73daca77ff1243962e9f22f099685726" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz#db350c2b73daca77ff1243962e9f22f099685726" dependencies: ansi-escapes "^3.0.0" chalk "^2.0.0" @@ -4410,8 +4311,8 @@ inquirer@^5.2.0: through "^2.3.6" interpret@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + version "1.2.0" + resolved "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" into-stream@^3.1.0: version "3.1.0" @@ -4430,10 +4331,6 @@ invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" -ip-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/ip-regex/-/ip-regex-3.0.0.tgz#0a934694b4066558c46294244a23cc33116bf732" - is-absolute@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" @@ -4455,15 +4352,15 @@ is-accessor-descriptor@^1.0.0: is-alphabetical@^1.0.0: version "1.0.2" - resolved "http://registry.npm.taobao.org/is-alphabetical/download/is-alphabetical-1.0.2.tgz#1fa6e49213cb7885b75d15862fb3f3d96c884f41" + resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.2.tgz#1fa6e49213cb7885b75d15862fb3f3d96c884f41" is-alphanumeric@^1.0.0: version "1.0.0" - resolved "http://registry.npm.taobao.org/is-alphanumeric/download/is-alphanumeric-1.0.0.tgz#4a9cef71daf4c001c1d81d63d140cf53fd6889f4" + resolved "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz#4a9cef71daf4c001c1d81d63d140cf53fd6889f4" is-alphanumerical@^1.0.0: version "1.0.2" - resolved "http://registry.npm.taobao.org/is-alphanumerical/download/is-alphanumerical-1.0.2.tgz#1138e9ae5040158dc6ff76b820acd6b7a181fd40" + resolved "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.2.tgz#1138e9ae5040158dc6ff76b820acd6b7a181fd40" dependencies: is-alphabetical "^1.0.0" is-decimal "^1.0.0" @@ -4484,13 +4381,7 @@ is-buffer@^1.1.5: is-buffer@^2.0.0: version "2.0.3" - resolved "http://registry.npm.taobao.org/is-buffer/download/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" - -is-builtin-module@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - dependencies: - builtin-modules "^1.0.0" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" is-callable@^1.1.4: version "1.1.4" @@ -4520,7 +4411,7 @@ is-date-object@^1.0.1: is-decimal@^1.0.0: version "1.0.2" - resolved "http://registry.npm.taobao.org/is-decimal/download/is-decimal-1.0.2.tgz#894662d6a8709d307f3a276ca4339c8fa5dff0ff" + resolved "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.2.tgz#894662d6a8709d307f3a276ca4339c8fa5dff0ff" is-descriptor@^0.1.0: version "0.1.6" @@ -4540,7 +4431,7 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-directory@^0.3.1: version "0.3.1" - resolved "http://registry.npm.taobao.org/is-directory/download/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + resolved "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" is-dotfile@^1.0.0: version "1.0.3" @@ -4607,14 +4498,14 @@ is-glob@^3.1.0: is-extglob "^2.1.0" is-glob@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + version "4.0.1" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" dependencies: is-extglob "^2.1.1" is-hexadecimal@^1.0.0: version "1.0.2" - resolved "http://registry.npm.taobao.org/is-hexadecimal/download/is-hexadecimal-1.0.2.tgz#b6e710d7d07bb66b98cb8cece5c9b4921deeb835" + resolved "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.2.tgz#b6e710d7d07bb66b98cb8cece5c9b4921deeb835" is-installed-globally@^0.1.0: version "0.1.0" @@ -4649,7 +4540,7 @@ is-number@^4.0.0: is-obj@^1.0.0: version "1.0.1" - resolved "http://registry.npm.taobao.org/is-obj/download/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" is-object@^1.0.1: version "1.0.1" @@ -4695,7 +4586,7 @@ is-regex@^1.0.4: is-regexp@^1.0.0: version "1.0.0" - resolved "http://registry.npm.taobao.org/is-regexp/download/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" is-relative@^1.0.0: version "1.0.0" @@ -4705,7 +4596,7 @@ is-relative@^1.0.0: is-resolvable@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + resolved "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: version "1.1.0" @@ -4717,7 +4608,7 @@ is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: is-supported-regexp-flag@^1.0.0: version "1.0.1" - resolved "http://registry.npm.taobao.org/is-supported-regexp-flag/download/is-supported-regexp-flag-1.0.1.tgz#21ee16518d2c1dd3edd3e9a0d57e50207ac364ca" + resolved "https://registry.npmjs.org/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.1.tgz#21ee16518d2c1dd3edd3e9a0d57e50207ac364ca" is-symbol@^1.0.2: version "1.0.2" @@ -4745,7 +4636,7 @@ is-valid-glob@^1.0.0: is-whitespace-character@^1.0.0: version "1.0.2" - resolved "http://registry.npm.taobao.org/is-whitespace-character/download/is-whitespace-character-1.0.2.tgz#ede53b4c6f6fb3874533751ec9280d01928d03ed" + resolved "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.2.tgz#ede53b4c6f6fb3874533751ec9280d01928d03ed" is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" @@ -4753,7 +4644,11 @@ is-windows@^1.0.1, is-windows@^1.0.2: is-word-character@^1.0.0: version "1.0.2" - resolved "http://registry.npm.taobao.org/is-word-character/download/is-word-character-1.0.2.tgz#46a5dac3f2a1840898b91e576cd40d493f3ae553" + resolved "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.2.tgz#46a5dac3f2a1840898b91e576cd40d493f3ae553" + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" isarray@0.0.1: version "0.0.1" @@ -5213,8 +5108,8 @@ joi@^14.0.6: topo "3.x.x" js-base64@^2.1.9: - version "2.4.9" - resolved "https://registry.npmjs.org/js-base64/-/js-base64-2.4.9.tgz#748911fb04f48a60c4771b375cac45a80df11c03" + version "2.5.1" + resolved "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121" js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" @@ -5224,34 +5119,13 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: version "4.0.0" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" -js-yaml@^3.13.0: - version "3.13.0" - resolved "http://registry.npm.taobao.org/js-yaml/download/js-yaml-3.13.0.tgz#38ee7178ac0eea2c97ff6d96fff4b18c7d8cf98e" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^3.4.2: +js-yaml@^3.13.0, js-yaml@^3.4.2, js-yaml@^3.7.0, js-yaml@^3.9.1: version "3.13.1" resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" dependencies: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^3.7.0: - version "3.12.1" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^3.9.1: - version "3.12.2" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.2.tgz#ef1d067c5a9d9cb65bd72f285b5d8105c77f14fc" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - jsbn@~0.1.0: version "0.1.1" resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -5305,11 +5179,11 @@ json-buffer@3.0.0: json-parse-better-errors@^1.0.1: version "1.0.2" - resolved "http://registry.npm.taobao.org/json-parse-better-errors/download/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + resolved "https://registry.npmjs.org/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" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" json-schema-traverse@^0.4.1: version "0.4.1" @@ -5323,7 +5197,7 @@ json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" -json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: +json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" dependencies: @@ -5432,7 +5306,7 @@ kleur@^2.0.1: known-css-properties@^0.11.0: version "0.11.0" - resolved "http://registry.npm.taobao.org/known-css-properties/download/known-css-properties-0.11.0.tgz#0da784f115ea77c76b81536d7052e90ee6c86a8a" + resolved "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.11.0.tgz#0da784f115ea77c76b81536d7052e90ee6c86a8a" latest-version@^3.0.0: version "3.1.0" @@ -5500,7 +5374,7 @@ load-json-file@^2.0.0: load-json-file@^4.0.0: version "4.0.0" - resolved "http://registry.npm.taobao.org/load-json-file/download/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" dependencies: graceful-fs "^4.1.2" parse-json "^4.0.0" @@ -5531,9 +5405,12 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" lodash.pad@^4.1.0: version "4.5.1" @@ -5563,11 +5440,7 @@ lodash.toarray@^4.4.0: version "4.4.0" resolved "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" -lodash@4.17.4: - version "4.17.4" - resolved "http://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" - -"lodash@4.6.1 || ^4.16.1", lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.5.1, lodash@^4.6.1, lodash@^4.7.0: +"lodash@4.6.1 || ^4.16.1", lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.5.1, lodash@^4.6.1, lodash@^4.7.0: version "4.17.11" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" @@ -5583,7 +5456,7 @@ log-symbols@^2.0.0, log-symbols@^2.2.0: longest-streak@^2.0.1: version "2.0.2" - resolved "http://registry.npm.taobao.org/longest-streak/download/longest-streak-2.0.2.tgz#2421b6ba939a443bb9ffebf596585a50b4c38e2e" + resolved "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.2.tgz#2421b6ba939a443bb9ffebf596585a50b4c38e2e" loose-envify@^1.0.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" @@ -5593,7 +5466,7 @@ loose-envify@^1.0.0, loose-envify@^1.3.1, loose-envify@^1.4.0: loud-rejection@^1.0.0: version "1.6.0" - resolved "http://registry.npm.taobao.org/loud-rejection/download/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + resolved "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" dependencies: currently-unhandled "^0.4.1" signal-exit "^3.0.0" @@ -5623,6 +5496,13 @@ make-dir@^1.0.0: dependencies: pify "^3.0.0" +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + dependencies: + pify "^4.0.1" + semver "^5.6.0" + makeerror@1.0.x: version "1.0.11" resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" @@ -5635,11 +5515,11 @@ map-cache@^0.2.2: map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" - resolved "http://registry.npm.taobao.org/map-obj/download/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" map-obj@^2.0.0: version "2.0.0" - resolved "http://registry.npm.taobao.org/map-obj/download/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" + resolved "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" map-visit@^1.0.0: version "1.0.0" @@ -5649,23 +5529,23 @@ map-visit@^1.0.0: markdown-escapes@^1.0.0: version "1.0.2" - resolved "http://registry.npm.taobao.org/markdown-escapes/download/markdown-escapes-1.0.2.tgz#e639cbde7b99c841c0bacc8a07982873b46d2122" + resolved "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.2.tgz#e639cbde7b99c841c0bacc8a07982873b46d2122" markdown-table@^1.1.0: version "1.1.2" - resolved "http://registry.npm.taobao.org/markdown-table/download/markdown-table-1.1.2.tgz#c78db948fa879903a41bce522e3b96f801c63786" + resolved "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.2.tgz#c78db948fa879903a41bce522e3b96f801c63786" math-random@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/math-random/-/math-random-1.0.2.tgz#8ab7f026363816c1e00b774d87dee67f61e37ad6" + version "1.0.4" + resolved "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" mathml-tag-names@^2.0.1: version "2.1.0" - resolved "http://registry.npm.taobao.org/mathml-tag-names/download/mathml-tag-names-2.1.0.tgz#490b70e062ee24636536e3d9481e333733d00f2c" + resolved "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.0.tgz#490b70e062ee24636536e3d9481e333733d00f2c" mdast-util-compact@^1.0.0: version "1.0.2" - resolved "http://registry.npm.taobao.org/mdast-util-compact/download/mdast-util-compact-1.0.2.tgz#c12ebe16fffc84573d3e19767726de226e95f649" + resolved "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.2.tgz#c12ebe16fffc84573d3e19767726de226e95f649" dependencies: unist-util-visit "^1.1.0" @@ -5720,7 +5600,7 @@ meow@^3.7.0: meow@^5.0.0: version "5.0.0" - resolved "http://registry.npm.taobao.org/meow/download/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" + resolved "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" dependencies: camelcase-keys "^4.0.0" decamelize-keys "^1.0.0" @@ -5740,7 +5620,7 @@ merge-stream@^1.0.1: merge2@^1.2.3: version "1.2.3" - resolved "http://registry.npm.taobao.org/merge2/download/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" merge@^1.2.0: version "1.2.1" @@ -5908,9 +5788,9 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -"mime-db@>= 1.36.0 < 2", mime-db@~1.37.0: - version "1.37.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" +mime-db@1.40.0, "mime-db@>= 1.38.0 < 2": + version "1.40.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" mime-db@~1.23.0: version "1.23.0" @@ -5923,10 +5803,10 @@ mime-types@2.1.11: mime-db "~1.23.0" mime-types@^2.1.12, mime-types@~2.1.18, mime-types@~2.1.19: - version "2.1.21" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" + version "2.1.24" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" dependencies: - mime-db "~1.37.0" + mime-db "1.40.0" mime@1.4.1: version "1.4.1" @@ -5958,37 +5838,37 @@ min-document@^2.19.0: minimist-options@^3.0.1: version "3.0.2" - resolved "http://registry.npm.taobao.org/minimist-options/download/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" + resolved "https://registry.npmjs.org/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 "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + resolved "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" minimist@1.1.x: version "1.1.3" - resolved "http://registry.npm.taobao.org/minimist/download/minimist-1.1.3.tgz#3bedfd91a92d39016fcfaa1c681e8faa1a1efda8" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.1.3.tgz#3bedfd91a92d39016fcfaa1c681e8faa1a1efda8" minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" - resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" minimist@~0.0.1: version "0.0.10" resolved "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" -minipass@^2.2.1, minipass@^2.3.3: - version "2.3.4" - resolved "https://registry.npmjs.org/minipass/-/minipass-2.3.4.tgz#4768d7605ed6194d6d576169b9e12ef71e9d9957" +minipass@^2.2.1, minipass@^2.3.4: + version "2.3.5" + resolved "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" -minizlib@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" +minizlib@^1.1.1: + version "1.2.1" + resolved "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" dependencies: minipass "^2.2.1" @@ -6001,7 +5881,7 @@ mixin-deep@^1.2.0: mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" - resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" @@ -6040,9 +5920,9 @@ mute-stream@0.0.7: version "0.0.7" resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" -nan@^2.9.2: - version "2.11.0" - resolved "https://registry.npmjs.org/nan/-/nan-2.11.0.tgz#574e360e4d954ab16966ec102c0c049fd961a099" +nan@^2.12.1: + version "2.13.2" + resolved "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" nanomatch@^1.2.9: version "1.2.13" @@ -6065,10 +5945,10 @@ natural-compare@^1.4.0: resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" needle@^2.2.1: - version "2.2.4" - resolved "https://registry.npmjs.org/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" + version "2.3.0" + resolved "https://registry.npmjs.org/needle/-/needle-2.3.0.tgz#ce3fea21197267bacb310705a7bbe24f2a3a3492" dependencies: - debug "^2.1.2" + debug "^4.1.0" iconv-lite "^0.4.4" sax "^1.2.4" @@ -6076,6 +5956,10 @@ negotiator@0.6.1: version "0.6.1" resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" +neo-async@^2.6.0: + version "2.6.0" + resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz#b9d15e4d71c6762908654b5183ed38b753340835" + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -6102,17 +5986,18 @@ node-modules-regexp@^1.0.0: resolved "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" node-notifier@^5.2.1: - version "5.3.0" - resolved "https://registry.npmjs.org/node-notifier/-/node-notifier-5.3.0.tgz#c77a4a7b84038733d5fb351aafd8a268bfe19a01" + version "5.4.0" + resolved "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.0.tgz#7b455fdce9f7de0c63538297354f3db468426e6a" dependencies: growly "^1.3.0" + is-wsl "^1.1.0" semver "^5.5.0" shellwords "^0.1.1" which "^1.3.0" -node-pre-gyp@^0.10.0: - version "0.10.3" - resolved "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" +node-pre-gyp@^0.12.0: + version "0.12.0" + resolved "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" dependencies: detect-libc "^1.0.2" mkdirp "^0.5.1" @@ -6125,9 +6010,9 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" -node-releases@^1.1.12: - version "1.1.12" - resolved "http://registry.npm.taobao.org/node-releases/download/node-releases-1.1.12.tgz#1d6baf544316b5422fcd35efe18708370a4e7637" +node-releases@^1.1.14: + version "1.1.16" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-1.1.16.tgz#efcb6615b0e8dc454bfb03bc025aad406ea6dddf" dependencies: semver "^5.3.0" @@ -6138,18 +6023,9 @@ nopt@^4.0.1: abbrev "1" osenv "^0.1.4" -normalize-package-data@^2.3.2: - version "2.4.0" - resolved "https://registry.npmjs.org/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-package-data@^2.3.4: +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: version "2.5.0" - resolved "http://registry.npm.taobao.org/normalize-package-data/download/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" dependencies: hosted-git-info "^2.1.4" resolve "^1.10.0" @@ -6162,13 +6038,17 @@ normalize-path@^2.0.1, normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + normalize-range@^0.1.2: version "0.1.2" resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" normalize-selector@^0.2.0: version "0.2.0" - resolved "http://registry.npm.taobao.org/normalize-selector/download/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03" + resolved "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03" normalize-url@2.0.1: version "2.0.1" @@ -6179,14 +6059,14 @@ normalize-url@2.0.1: sort-keys "^2.0.0" now-and-later@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.0.tgz#bc61cbb456d79cb32207ce47ca05136ff2e7d6ee" + version "2.0.1" + resolved "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz#8e579c8685764a7cc02cb680380e94f43ccb1f7c" dependencies: once "^1.3.2" npm-bundled@^1.0.1: - version "1.0.5" - resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" + version "1.0.6" + resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" npm-check@^5.9.0: version "5.9.0" @@ -6220,8 +6100,8 @@ npm-check@^5.9.0: xtend "^4.0.1" npm-packlist@^1.1.6: - version "1.1.11" - resolved "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.11.tgz#84e8c683cbe7867d34b1d357d893ce29e28a02de" + version "1.4.1" + resolved "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz#19064cdf988da80ea3cee45533879d90192bbfbc" dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" @@ -6278,8 +6158,8 @@ number-is-nan@^1.0.0: resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" nwsapi@^2.0.7: - version "2.0.9" - resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.0.9.tgz#77ac0cdfdcad52b6a1151a84e73254edc33ed016" + version "2.1.3" + resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.3.tgz#25f3a5cec26c654f7376df6659cdf84b99df9558" oauth-sign@~0.9.0: version "0.9.0" @@ -6298,8 +6178,8 @@ object-copy@^0.1.0: kind-of "^3.0.3" object-keys@^1.0.11, object-keys@^1.0.12: - version "1.0.12" - resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + version "1.1.1" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" object-visit@^1.0.0: version "1.0.1" @@ -6351,9 +6231,9 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -on-headers@~1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" +on-headers@~1.0.1, on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: version "1.4.0" @@ -6457,7 +6337,7 @@ osenv@^0.1.4: p-cancelable@^0.4.0: version "0.4.1" - resolved "http://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" p-finally@^1.0.0: version "1.0.0" @@ -6465,7 +6345,7 @@ p-finally@^1.0.0: p-is-promise@^1.1.0: version "1.1.0" - resolved "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + resolved "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" p-limit@^1.1.0: version "1.3.0" @@ -6473,12 +6353,24 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" +p-limit@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" + dependencies: + p-try "^2.0.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" dependencies: p-limit "^1.1.0" +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + dependencies: + p-limit "^2.0.0" + p-timeout@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" @@ -6489,6 +6381,10 @@ p-try@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + package-json@^4.0.0, package-json@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" @@ -6509,7 +6405,7 @@ package-json@^5.0.0: parse-entities@^1.0.2, parse-entities@^1.1.0: version "1.2.1" - resolved "http://registry.npm.taobao.org/parse-entities/download/parse-entities-1.2.1.tgz#2c761ced065ba7dc68148580b5a225e4918cdd69" + resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.1.tgz#2c761ced065ba7dc68148580b5a225e4918cdd69" dependencies: character-entities "^1.0.0" character-entities-legacy "^1.0.0" @@ -6535,14 +6431,14 @@ parse-json@^2.2.0: parse-json@^4.0.0: version "4.0.0" - resolved "http://registry.npm.taobao.org/parse-json/download/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" dependencies: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" parse-node-version@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.0.tgz#33d9aa8920dcc3c0d33658ec18ce237009a56d53" + version "1.0.1" + resolved "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" parse-passwd@^1.0.0: version "1.0.0" @@ -6553,8 +6449,8 @@ parse5@4.0.0: resolved "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" parseurl@~1.3.2: - version "1.3.2" - resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + version "1.3.3" + resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" pascalcase@^0.1.1: version "0.1.1" @@ -6622,6 +6518,10 @@ pegjs@^0.10.0: version "0.10.0" resolved "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz#cf8bafae6eddff4b5a7efb185269eaaf4610ddbd" +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -6640,7 +6540,7 @@ pify@^3.0.0: pify@^4.0.0, pify@^4.0.1: version "4.0.1" - resolved "http://registry.npm.taobao.org/pify/download/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" pinkie-promise@^2.0.0: version "2.0.1" @@ -6653,17 +6553,29 @@ pinkie@^2.0.0: resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" pirates@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.0.tgz#850b18781b4ac6ec58a43c9ed9ec5fe6796addbd" + version "4.0.1" + resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" dependencies: node-modules-regexp "^1.0.0" +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + dependencies: + find-up "^1.0.0" + pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" dependencies: find-up "^2.1.0" +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + dependencies: + find-up "^3.0.0" + plist@2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/plist/-/plist-2.0.1.tgz#0a32ca9481b1c364e92e18dc55c876de9d01da8b" @@ -6705,32 +6617,32 @@ posix-character-classes@^0.1.0: postcss-html@^0.36.0: version "0.36.0" - resolved "http://registry.npm.taobao.org/postcss-html/download/postcss-html-0.36.0.tgz#b40913f94eaacc2453fd30a1327ad6ee1f88b204" + resolved "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz#b40913f94eaacc2453fd30a1327ad6ee1f88b204" dependencies: htmlparser2 "^3.10.0" postcss-jsx@^0.36.0: version "0.36.0" - resolved "http://registry.npm.taobao.org/postcss-jsx/download/postcss-jsx-0.36.0.tgz#b7685ed3d070a175ef0aa48f83d9015bd772c82d" + resolved "https://registry.npmjs.org/postcss-jsx/-/postcss-jsx-0.36.0.tgz#b7685ed3d070a175ef0aa48f83d9015bd772c82d" dependencies: "@babel/core" ">=7.1.0" postcss-less@^3.1.0: version "3.1.4" - resolved "http://registry.npm.taobao.org/postcss-less/download/postcss-less-3.1.4.tgz#369f58642b5928ef898ffbc1a6e93c958304c5ad" + resolved "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz#369f58642b5928ef898ffbc1a6e93c958304c5ad" dependencies: postcss "^7.0.14" postcss-markdown@^0.36.0: version "0.36.0" - resolved "http://registry.npm.taobao.org/postcss-markdown/download/postcss-markdown-0.36.0.tgz#7f22849ae0e3db18820b7b0d5e7833f13a447560" + resolved "https://registry.npmjs.org/postcss-markdown/-/postcss-markdown-0.36.0.tgz#7f22849ae0e3db18820b7b0d5e7833f13a447560" dependencies: remark "^10.0.1" unist-util-find-all-after "^1.0.2" postcss-media-query-parser@^0.2.3: version "0.2.3" - resolved "http://registry.npm.taobao.org/postcss-media-query-parser/download/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244" + resolved "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244" postcss-modules-extract-imports@^1.1.0: version "1.2.1" @@ -6783,7 +6695,7 @@ postcss-pxtransform@1.2.27-beta.0: postcss-reporter@^6.0.0, postcss-reporter@^6.0.1: version "6.0.1" - resolved "http://registry.npm.taobao.org/postcss-reporter/download/postcss-reporter-6.0.1.tgz#7c055120060a97c8837b4e48215661aafb74245f" + resolved "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-6.0.1.tgz#7c055120060a97c8837b4e48215661aafb74245f" dependencies: chalk "^2.4.1" lodash "^4.17.11" @@ -6792,30 +6704,30 @@ postcss-reporter@^6.0.0, postcss-reporter@^6.0.1: postcss-resolve-nested-selector@^0.1.1: version "0.1.1" - resolved "http://registry.npm.taobao.org/postcss-resolve-nested-selector/download/postcss-resolve-nested-selector-0.1.1.tgz#29ccbc7c37dedfac304e9fff0bf1596b3f6a0e4e" + resolved "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz#29ccbc7c37dedfac304e9fff0bf1596b3f6a0e4e" postcss-safe-parser@^4.0.0: version "4.0.1" - resolved "http://registry.npm.taobao.org/postcss-safe-parser/download/postcss-safe-parser-4.0.1.tgz#8756d9e4c36fdce2c72b091bbc8ca176ab1fcdea" + resolved "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.1.tgz#8756d9e4c36fdce2c72b091bbc8ca176ab1fcdea" dependencies: postcss "^7.0.0" postcss-sass@^0.3.5: version "0.3.5" - resolved "http://registry.npm.taobao.org/postcss-sass/download/postcss-sass-0.3.5.tgz#6d3e39f101a53d2efa091f953493116d32beb68c" + resolved "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.3.5.tgz#6d3e39f101a53d2efa091f953493116d32beb68c" dependencies: gonzales-pe "^4.2.3" postcss "^7.0.1" postcss-scss@^2.0.0: version "2.0.0" - resolved "http://registry.npm.taobao.org/postcss-scss/download/postcss-scss-2.0.0.tgz#248b0a28af77ea7b32b1011aba0f738bda27dea1" + resolved "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.0.0.tgz#248b0a28af77ea7b32b1011aba0f738bda27dea1" dependencies: postcss "^7.0.0" postcss-selector-parser@^3.1.0: version "3.1.1" - resolved "http://registry.npm.taobao.org/postcss-selector-parser/download/postcss-selector-parser-3.1.1.tgz#4f875f4afb0c96573d5cf4d74011aee250a7e865" + resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz#4f875f4afb0c96573d5cf4d74011aee250a7e865" dependencies: dot-prop "^4.1.1" indexes-of "^1.0.1" @@ -6823,11 +6735,11 @@ postcss-selector-parser@^3.1.0: postcss-syntax@^0.36.2: version "0.36.2" - resolved "http://registry.npm.taobao.org/postcss-syntax/download/postcss-syntax-0.36.2.tgz#f08578c7d95834574e5593a82dfbfa8afae3b51c" + resolved "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz#f08578c7d95834574e5593a82dfbfa8afae3b51c" postcss-taro-unit-transform@1.2.15: version "1.2.15" - resolved "https://registry.yarnpkg.com/postcss-taro-unit-transform/-/postcss-taro-unit-transform-1.2.15.tgz#bfb3f327c7a529995ccf6bfecca6d606b2fb9f45" + resolved "https://registry.npmjs.org/postcss-taro-unit-transform/-/postcss-taro-unit-transform-1.2.15.tgz#bfb3f327c7a529995ccf6bfecca6d606b2fb9f45" dependencies: postcss "^6.0.21" @@ -6841,17 +6753,13 @@ postcss-url@^7.3.2: postcss "^6.0.1" xxhashjs "^0.2.1" -postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz#87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15" - -postcss-value-parser@^3.3.1: +postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1: version "3.3.1" - resolved "http://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" postcss@7.x.x, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.7: version "7.0.14" - resolved "http://registry.npm.taobao.org/postcss/download/postcss-7.0.14.tgz#4527ed6b1ca0d82c53ce5ec1a2041c2346bbd6e5" + resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz#4527ed6b1ca0d82c53ce5ec1a2041c2346bbd6e5" dependencies: chalk "^2.4.2" source-map "^0.6.1" @@ -6897,11 +6805,7 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -prettier@^1.14.2: - version "1.14.3" - resolved "https://registry.npmjs.org/prettier/-/prettier-1.14.3.tgz#90238dd4c0684b7edce5f83b0fb7328e48bd0895" - -prettier@^1.15.3: +prettier@^1.14.2, prettier@^1.16.4: version "1.17.0" resolved "https://registry.npmjs.org/prettier/-/prettier-1.17.0.tgz#53b303676eed22cc14a9f0cec09b477b3026c008" @@ -6945,14 +6849,7 @@ prompts@^0.1.9: kleur "^2.0.1" sisteransi "^0.1.1" -prop-types@^15.5.8: - version "15.6.2" - resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" - dependencies: - loose-envify "^1.3.1" - object-assign "^4.1.1" - -prop-types@^15.6.2: +prop-types@^15.5.8, prop-types@^15.6.2: version "15.7.2" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" dependencies: @@ -7005,7 +6902,7 @@ query-string@^5.0.1: quick-lru@^1.0.0: version "1.1.0" - resolved "http://registry.npm.taobao.org/quick-lru/download/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" + resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" randomatic@^3.0.0: version "3.1.1" @@ -7045,11 +6942,11 @@ react-devtools-core@3.1.0: react-is@^16.8.1: version "16.8.6" - resolved "http://registry.npm.taobao.org/react-is/download/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" + resolved "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" react-native-known-styling-properties@^1.0.4: version "1.0.5" - resolved "http://registry.npm.taobao.org/react-native-known-styling-properties/download/react-native-known-styling-properties-1.0.5.tgz#dd99690d579c5136541e1df836e75088af6e7356" + resolved "https://registry.npmjs.org/react-native-known-styling-properties/-/react-native-known-styling-properties-1.0.5.tgz#dd99690d579c5136541e1df836e75088af6e7356" react-native@^0.55.4: version "0.55.4" @@ -7149,7 +7046,7 @@ read-pkg-up@^2.0.0: read-pkg-up@^3.0.0: version "3.0.0" - resolved "http://registry.npm.taobao.org/read-pkg-up/download/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" dependencies: find-up "^2.0.0" read-pkg "^3.0.0" @@ -7172,15 +7069,15 @@ read-pkg@^2.0.0: read-pkg@^3.0.0: version "3.0.0" - resolved "http://registry.npm.taobao.org/read-pkg/download/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + resolved "https://registry.npmjs.org/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.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5: +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.6" - resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -7192,13 +7089,13 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable readable-stream@^3.1.1: version "3.3.0" - resolved "http://registry.npm.taobao.org/readable-stream/download/readable-stream-3.3.0.tgz#cb8011aad002eb717bf040291feba8569c986fb9" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.3.0.tgz#cb8011aad002eb717bf040291feba8569c986fb9" dependencies: inherits "^2.0.3" string_decoder "^1.1.1" util-deprecate "^1.0.1" -readdirp@^2.0.0: +readdirp@^2.2.1: version "2.2.1" resolved "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" dependencies: @@ -7215,8 +7112,8 @@ readline2@^1.0.1: mute-stream "0.0.5" realpath-native@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/realpath-native/-/realpath-native-1.0.2.tgz#cd51ce089b513b45cf9b1516c82989b51ccc6560" + version "1.1.0" + resolved "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" dependencies: util.promisify "^1.0.0" @@ -7235,7 +7132,7 @@ redent@^1.0.0: redent@^2.0.0: version "2.0.0" - resolved "http://registry.npm.taobao.org/redent/download/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" + resolved "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" dependencies: indent-string "^3.0.0" strip-indent "^2.0.0" @@ -7256,9 +7153,9 @@ regenerator-transform@^0.10.0: babel-types "^6.19.0" private "^0.1.6" -regenerator-transform@^0.13.3: - version "0.13.3" - resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.3.tgz#264bd9ff38a8ce24b06e0636496b2c856b57bcbb" +regenerator-transform@^0.13.4: + version "0.13.4" + resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.4.tgz#18f6763cf1382c69c36df76c6ce122cc694284fb" dependencies: private "^0.1.6" @@ -7277,7 +7174,7 @@ regex-not@^1.0.0, regex-not@^1.0.2: regexpp@^1.0.1: version "1.1.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" + resolved "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" regexpu-core@^1.0.0: version "1.0.0" @@ -7295,20 +7192,13 @@ regexpu-core@^2.0.0: regjsgen "^0.2.0" regjsparser "^0.1.4" -registry-auth-token@^3.0.1: +registry-auth-token@^3.0.1, registry-auth-token@^3.3.2: version "3.4.0" resolved "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" dependencies: rc "^1.1.6" safe-buffer "^5.0.1" -registry-auth-token@^3.3.2: - version "3.3.2" - resolved "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" - dependencies: - rc "^1.1.6" - safe-buffer "^5.0.1" - registry-url@^3.0.3, registry-url@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" @@ -7327,7 +7217,7 @@ regjsparser@^0.1.4: remark-parse@^6.0.0: version "6.0.3" - resolved "http://registry.npm.taobao.org/remark-parse/download/remark-parse-6.0.3.tgz#c99131052809da482108413f87b0ee7f52180a3a" + resolved "https://registry.npmjs.org/remark-parse/-/remark-parse-6.0.3.tgz#c99131052809da482108413f87b0ee7f52180a3a" dependencies: collapse-white-space "^1.0.2" is-alphabetical "^1.0.0" @@ -7347,7 +7237,7 @@ remark-parse@^6.0.0: remark-stringify@^6.0.0: version "6.0.4" - resolved "http://registry.npm.taobao.org/remark-stringify/download/remark-stringify-6.0.4.tgz#16ac229d4d1593249018663c7bddf28aafc4e088" + resolved "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz#16ac229d4d1593249018663c7bddf28aafc4e088" dependencies: ccount "^1.0.0" is-alphanumeric "^1.0.0" @@ -7366,7 +7256,7 @@ remark-stringify@^6.0.0: remark@^10.0.1: version "10.0.1" - resolved "http://registry.npm.taobao.org/remark/download/remark-10.0.1.tgz#3058076dc41781bf505d8978c291485fe47667df" + resolved "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz#3058076dc41781bf505d8978c291485fe47667df" dependencies: remark-parse "^6.0.0" remark-stringify "^6.0.0" @@ -7413,21 +7303,21 @@ replace-ext@1.0.0, replace-ext@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" -request-promise-core@1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" +request-promise-core@1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz#339f6aababcafdb31c799ff158700336301d3346" dependencies: - lodash "^4.13.1" + lodash "^4.17.11" request-promise-native@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" + version "1.0.7" + resolved "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz#a49868a624bdea5069f1251d0a836e0d89aa2c59" dependencies: - request-promise-core "1.1.1" - stealthy-require "^1.1.0" - tough-cookie ">=2.3.3" + request-promise-core "1.1.2" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" -request@^2.87.0: +request@^2.87.0, request@^2.88.0: version "2.88.0" resolved "https://registry.npmjs.org/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" dependencies: @@ -7466,7 +7356,7 @@ require-package-name@^2.0.1: require-uncached@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + resolved "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" dependencies: caller-path "^0.1.0" resolve-from "^1.0.0" @@ -7490,7 +7380,7 @@ resolve-dir@^1.0.0: resolve-from@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" resolve-from@^3.0.0: version "3.0.0" @@ -7498,7 +7388,7 @@ resolve-from@^3.0.0: resolve-from@^4.0.0: version "4.0.0" - resolved "http://registry.npm.taobao.org/resolve-from/download/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" resolve-options@^1.1.0: version "1.1.0" @@ -7514,21 +7404,9 @@ resolve@1.1.7: version "1.1.7" resolved "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" -resolve@^1.1.6, resolve@^1.6.0: - version "1.8.1" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" - dependencies: - path-parse "^1.0.5" - -resolve@^1.10.0, resolve@^1.9.0: +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.9.0: version "1.10.0" - resolved "http://registry.npm.taobao.org/resolve/download/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" - dependencies: - path-parse "^1.0.6" - -resolve@^1.3.2, resolve@^1.5.0: - version "1.9.0" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" dependencies: path-parse "^1.0.6" @@ -7556,18 +7434,12 @@ ret@~0.1.10: version "0.1.15" resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" -rimraf@2.6.3, rimraf@^2.5.4, rimraf@~2.6.2: +rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@~2.6.2: version "2.6.3" resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" dependencies: glob "^7.1.3" -rimraf@^2.2.8, rimraf@^2.6.1: - version "2.6.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - dependencies: - glob "^7.0.5" - rimraf@~2.2.6: version "2.2.8" resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" @@ -7655,13 +7527,9 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" -"semver@2 || 3 || 4 || 5", semver@5.x, semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.4.1: - version "5.6.0" - resolved "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" - -semver@^5.3.0, semver@^5.5.0: - version "5.5.1" - resolved "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" +"semver@2 || 3 || 4 || 5", semver@5.x, semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: + version "5.7.0" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" send@0.16.2: version "0.16.2" @@ -7744,8 +7612,8 @@ shell-quote@1.6.1, shell-quote@^1.6.1: jsonify "~0.0.0" shelljs@^0.8.1: - version "0.8.2" - resolved "https://registry.npmjs.org/shelljs/-/shelljs-0.8.2.tgz#345b7df7763f4c2340d584abb532c5f752ca9e35" + version "0.8.3" + resolved "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz#a7f3319520ebf09ee81275b2368adb286659b097" dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -7777,17 +7645,17 @@ slash@^1.0.0: slash@^2.0.0: version "2.0.0" - resolved "http://registry.npm.taobao.org/slash/download/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + resolved "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" slice-ansi@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" dependencies: is-fullwidth-code-point "^2.0.0" slice-ansi@^2.1.0: version "2.1.0" - resolved "http://registry.npm.taobao.org/slice-ansi/download/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" dependencies: ansi-styles "^3.2.0" astral-regex "^1.0.0" @@ -7847,8 +7715,8 @@ source-map-support@^0.4.15: source-map "^0.5.6" source-map-support@^0.5.6, source-map-support@^0.5.9: - version "0.5.10" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz#2214080bc9d51832511ee2bab96e3c2f9353120c" + version "0.5.12" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -7884,12 +7752,12 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.3" - resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e" + version "3.0.4" + resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz#75ecd1a88de8c184ef015eafb51b5b48bfd11bb1" specificity@^0.4.1: version "0.4.1" - resolved "http://registry.npm.taobao.org/specificity/download/specificity-0.4.1.tgz#aab5e645012db08ba182e151165738d00887b019" + resolved "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz#aab5e645012db08ba182e151165738d00887b019" split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" @@ -7902,8 +7770,8 @@ sprintf-js@~1.0.2: resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" sshpk@^1.7.0: - version "1.16.0" - resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.16.0.tgz#1d4963a2fbffe58050aa9084ca20be81741c07de" + version "1.16.1" + resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -7924,12 +7792,14 @@ stackframe@^0.3.1: resolved "https://registry.npmjs.org/stackframe/-/stackframe-0.3.1.tgz#33aa84f1177a5548c8935533cbfeb3420975f5a4" stacktrace-parser@^0.1.3: - version "0.1.4" - resolved "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.4.tgz#01397922e5f62ecf30845522c95c4fe1d25e7d4e" + version "0.1.5" + resolved "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.5.tgz#b6784545b9bf70b4f1325671d024c71269c4bc2a" + dependencies: + type-fest "^0.3.0" state-toggle@^1.0.0: version "1.0.1" - resolved "http://registry.npm.taobao.org/state-toggle/download/state-toggle-1.0.1.tgz#c3cb0974f40a6a0f8e905b96789eb41afa1cde3a" + resolved "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.1.tgz#c3cb0974f40a6a0f8e905b96789eb41afa1cde3a" static-extend@^0.1.1: version "0.1.2" @@ -7950,7 +7820,7 @@ statuses@~1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" -stealthy-require@^1.1.0: +stealthy-require@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" @@ -7990,7 +7860,7 @@ string-width@^1.0.1: string-width@^3.0.0: version "3.1.0" - resolved "http://registry.npm.taobao.org/string-width/download/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + resolved "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" dependencies: emoji-regex "^7.0.1" is-fullwidth-code-point "^2.0.0" @@ -8006,7 +7876,7 @@ string.prototype.padend@^3.0.0: string_decoder@^1.1.1: version "1.2.0" - resolved "http://registry.npm.taobao.org/string_decoder/download/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" dependencies: safe-buffer "~5.1.0" @@ -8018,7 +7888,7 @@ string_decoder@~1.1.1: stringify-entities@^1.0.1: version "1.3.2" - resolved "http://registry.npm.taobao.org/stringify-entities/download/stringify-entities-1.3.2.tgz#a98417e5471fd227b3e45d3db1861c11caf668f7" + resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz#a98417e5471fd227b3e45d3db1861c11caf668f7" dependencies: character-entities-html4 "^1.0.0" character-entities-legacy "^1.0.0" @@ -8039,7 +7909,7 @@ strip-ansi@^4.0.0: strip-ansi@^5.1.0: version "5.2.0" - resolved "http://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" dependencies: ansi-regex "^4.1.0" @@ -8072,7 +7942,7 @@ strip-indent@^1.0.1: strip-indent@^2.0.0: version "2.0.0" - resolved "http://registry.npm.taobao.org/strip-indent/download/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" strip-json-comments@~2.0.1: version "2.0.1" @@ -8080,7 +7950,7 @@ strip-json-comments@~2.0.1: style-search@^0.1.0: version "0.1.0" - resolved "http://registry.npm.taobao.org/style-search/download/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902" + resolved "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902" stylelint-config-taro-rn@1.2.27-beta.0: version "1.2.27-beta.0" @@ -8094,7 +7964,7 @@ stylelint-taro-rn@1.2.27-beta.0: stylelint@^9.10.1: version "9.10.1" - resolved "http://registry.npm.taobao.org/stylelint/download/stylelint-9.10.1.tgz#5f0ee3701461dff1d68284e1386efe8f0677a75d" + resolved "https://registry.npmjs.org/stylelint/-/stylelint-9.10.1.tgz#5f0ee3701461dff1d68284e1386efe8f0677a75d" dependencies: autoprefixer "^9.0.0" balanced-match "^1.0.0" @@ -8146,7 +8016,7 @@ stylelint@^9.10.1: sugarss@^2.0.0: version "2.0.0" - resolved "http://registry.npm.taobao.org/sugarss/download/sugarss-2.0.0.tgz#ddd76e0124b297d40bf3cca31c8b22ecb43bc61d" + resolved "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz#ddd76e0124b297d40bf3cca31c8b22ecb43bc61d" dependencies: postcss "^7.0.2" @@ -8168,13 +8038,13 @@ supports-color@^5.3.0, supports-color@^5.4.0: supports-color@^6.1.0: version "6.1.0" - resolved "http://registry.npm.taobao.org/supports-color/download/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" dependencies: has-flag "^3.0.0" svg-tags@^1.0.0: version "1.0.0" - resolved "http://registry.npm.taobao.org/svg-tags/download/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" + resolved "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" symbol-observable@1.0.1: version "1.0.1" @@ -8186,7 +8056,7 @@ symbol-tree@^3.2.2: table@4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" + resolved "https://registry.npmjs.org/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" dependencies: ajv "^5.2.3" ajv-keywords "^2.1.0" @@ -8197,7 +8067,7 @@ table@4.0.2: table@^5.0.0: version "5.2.3" - resolved "http://registry.npm.taobao.org/table/download/table-5.2.3.tgz#cde0cc6eb06751c009efab27e8c820ca5b67b7f2" + resolved "https://registry.npmjs.org/table/-/table-5.2.3.tgz#cde0cc6eb06751c009efab27e8c820ca5b67b7f2" dependencies: ajv "^6.9.1" lodash "^4.17.11" @@ -8205,13 +8075,13 @@ table@^5.0.0: string-width "^3.0.0" tar@^4: - version "4.4.6" - resolved "https://registry.npmjs.org/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" + version "4.4.8" + resolved "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" dependencies: - chownr "^1.0.1" + chownr "^1.1.1" fs-minipass "^1.2.5" - minipass "^2.3.3" - minizlib "^1.1.0" + minipass "^2.3.4" + minizlib "^1.1.1" mkdirp "^0.5.0" safe-buffer "^5.1.2" yallist "^3.0.2" @@ -8241,7 +8111,7 @@ test-exclude@^4.2.1: text-table@^0.2.0, text-table@~0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" throat@^2.0.2: version "2.0.2" @@ -8251,29 +8121,29 @@ throat@^4.0.0, throat@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" -through2-filter@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec" +through2-filter@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254" dependencies: through2 "~2.0.0" xtend "~4.0.0" through2@^2.0.0, through2@^2.0.3, through2@~2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + version "2.0.5" + resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" dependencies: - readable-stream "^2.1.5" + readable-stream "~2.3.6" xtend "~4.0.1" through@^2.3.6: version "2.3.8" - resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" time-stamp@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" -timed-out@^4.0.1: +timed-out@^4.0.0, timed-out@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" @@ -8336,15 +8206,7 @@ topo@3.x.x: dependencies: hoek "6.x.x" -tough-cookie@>=2.3.3: - version "3.0.0" - resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.0.tgz#d2bceddebde633153ff20a52fa844a0dc71dacef" - dependencies: - ip-regex "^3.0.0" - psl "^1.1.28" - punycode "^2.1.1" - -tough-cookie@^2.3.4: +tough-cookie@^2.3.3, tough-cookie@^2.3.4: version "2.5.0" resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" dependencies: @@ -8374,7 +8236,7 @@ trim-newlines@^1.0.0: trim-newlines@^2.0.0: version "2.0.0" - resolved "http://registry.npm.taobao.org/trim-newlines/download/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" + resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" trim-right@^1.0.1: version "1.0.1" @@ -8382,15 +8244,15 @@ trim-right@^1.0.1: trim-trailing-lines@^1.0.0: version "1.1.1" - resolved "http://registry.npm.taobao.org/trim-trailing-lines/download/trim-trailing-lines-1.1.1.tgz#e0ec0810fd3c3f1730516b45f49083caaf2774d9" + resolved "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.1.tgz#e0ec0810fd3c3f1730516b45f49083caaf2774d9" trim@0.0.1: version "0.0.1" - resolved "http://registry.npm.taobao.org/trim/download/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" + resolved "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" trough@^1.0.0: version "1.0.3" - resolved "http://registry.npm.taobao.org/trough/download/trough-1.0.3.tgz#e29bd1614c6458d44869fc28b255ab7857ef7c24" + resolved "https://registry.npmjs.org/trough/-/trough-1.0.3.tgz#e29bd1614c6458d44869fc28b255ab7857ef7c24" tslib@1.9.0: version "1.9.0" @@ -8464,21 +8326,21 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-fest@^0.3.0: + version "0.3.1" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -typescript@^3.0.1: - version "3.0.3" - resolved "https://registry.npmjs.org/typescript/-/typescript-3.0.3.tgz#4853b3e275ecdaa27f78fda46dc273a7eb7fc1c8" - -typescript@^3.2.2: - version "3.3.3" - resolved "https://registry.npmjs.org/typescript/-/typescript-3.3.3.tgz#f1657fc7daa27e1a8930758ace9ae8da31403221" +typescript@^3.0.1, typescript@^3.2.2: + version "3.4.4" + resolved "https://registry.npmjs.org/typescript/-/typescript-3.4.4.tgz#aac4a08abecab8091a75f10842ffa0631818f785" ua-parser-js@^0.7.18: - version "0.7.18" - resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.18.tgz#a7bfd92f56edfb117083b69e31d2aa8882d4b1ed" + version "0.7.19" + resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz#94151be4c0a7fb1d001af7022fdaca4642659e4b" uglify-es@^3.1.9: version "3.3.9" @@ -8488,10 +8350,10 @@ uglify-es@^3.1.9: source-map "~0.6.1" uglify-js@^3.1.4: - version "3.4.9" - resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" + version "3.5.6" + resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.6.tgz#8a5f8a06ee7415ac1fa302f4623bc7344b553da4" dependencies: - commander "~2.17.1" + commander "~2.20.0" source-map "~0.6.1" ultron@1.0.x: @@ -8508,14 +8370,14 @@ unc-path-regex@^0.1.2: unherit@^1.0.4: version "1.1.1" - resolved "http://registry.npm.taobao.org/unherit/download/unherit-1.1.1.tgz#132748da3e88eab767e08fabfbb89c5e9d28628c" + resolved "https://registry.npmjs.org/unherit/-/unherit-1.1.1.tgz#132748da3e88eab767e08fabfbb89c5e9d28628c" dependencies: inherits "^2.0.1" xtend "^4.0.1" unified@^7.0.0: version "7.1.0" - resolved "http://registry.npm.taobao.org/unified/download/unified-7.1.0.tgz#5032f1c1ee3364bd09da12e27fdd4a7553c7be13" + resolved "https://registry.npmjs.org/unified/-/unified-7.1.0.tgz#5032f1c1ee3364bd09da12e27fdd4a7553c7be13" dependencies: "@types/unist" "^2.0.0" "@types/vfile" "^3.0.0" @@ -8537,14 +8399,14 @@ union-value@^1.0.0: uniq@^1.0.1: version "1.0.1" - resolved "http://registry.npm.taobao.org/uniq/download/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + resolved "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" unique-stream@^2.0.2: - version "2.2.1" - resolved "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369" + version "2.3.1" + resolved "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" dependencies: - json-stable-stringify "^1.0.0" - through2-filter "^2.0.0" + json-stable-stringify-without-jsonify "^1.0.1" + through2-filter "^3.0.0" unique-string@^1.0.0: version "1.0.0" @@ -8554,33 +8416,33 @@ unique-string@^1.0.0: unist-util-find-all-after@^1.0.2: version "1.0.2" - resolved "http://registry.npm.taobao.org/unist-util-find-all-after/download/unist-util-find-all-after-1.0.2.tgz#9be49cfbae5ca1566b27536670a92836bf2f8d6d" + resolved "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-1.0.2.tgz#9be49cfbae5ca1566b27536670a92836bf2f8d6d" dependencies: unist-util-is "^2.0.0" unist-util-is@^2.0.0, unist-util-is@^2.1.2: version "2.1.2" - resolved "http://registry.npm.taobao.org/unist-util-is/download/unist-util-is-2.1.2.tgz#1193fa8f2bfbbb82150633f3a8d2eb9a1c1d55db" + resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.2.tgz#1193fa8f2bfbbb82150633f3a8d2eb9a1c1d55db" unist-util-remove-position@^1.0.0: version "1.1.2" - resolved "http://registry.npm.taobao.org/unist-util-remove-position/download/unist-util-remove-position-1.1.2.tgz#86b5dad104d0bbfbeb1db5f5c92f3570575c12cb" + resolved "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.2.tgz#86b5dad104d0bbfbeb1db5f5c92f3570575c12cb" dependencies: unist-util-visit "^1.1.0" unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1: version "1.1.2" - resolved "http://registry.npm.taobao.org/unist-util-stringify-position/download/unist-util-stringify-position-1.1.2.tgz#3f37fcf351279dcbca7480ab5889bb8a832ee1c6" + resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz#3f37fcf351279dcbca7480ab5889bb8a832ee1c6" unist-util-visit-parents@^2.0.0: version "2.0.1" - resolved "http://registry.npm.taobao.org/unist-util-visit-parents/download/unist-util-visit-parents-2.0.1.tgz#63fffc8929027bee04bfef7d2cce474f71cb6217" + resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.0.1.tgz#63fffc8929027bee04bfef7d2cce474f71cb6217" dependencies: unist-util-is "^2.1.2" unist-util-visit@^1.1.0: version "1.4.0" - resolved "http://registry.npm.taobao.org/unist-util-visit/download/unist-util-visit-1.4.0.tgz#1cb763647186dc26f5e1df5db6bd1e48b3cc2fb1" + resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.0.tgz#1cb763647186dc26f5e1df5db6bd1e48b3cc2fb1" dependencies: unist-util-visit-parents "^2.0.0" @@ -8603,9 +8465,9 @@ unzip-response@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" -upath@^1.0.5: - version "1.1.0" - resolved "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" +upath@^1.1.1: + version "1.1.2" + resolved "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" update-notifier@^2.1.0: version "2.5.0" @@ -8700,17 +8562,17 @@ verror@1.10.0: vfile-location@^2.0.0: version "2.0.4" - resolved "http://registry.npm.taobao.org/vfile-location/download/vfile-location-2.0.4.tgz#2a5e7297dd0d9e2da4381464d04acc6b834d3e55" + resolved "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.4.tgz#2a5e7297dd0d9e2da4381464d04acc6b834d3e55" vfile-message@^1.0.0: version "1.1.1" - resolved "http://registry.npm.taobao.org/vfile-message/download/vfile-message-1.1.1.tgz#5833ae078a1dfa2d96e9647886cd32993ab313e1" + resolved "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz#5833ae078a1dfa2d96e9647886cd32993ab313e1" dependencies: unist-util-stringify-position "^1.1.1" vfile@^3.0.0: version "3.0.1" - resolved "http://registry.npm.taobao.org/vfile/download/vfile-3.0.1.tgz#47331d2abe3282424f4a4bb6acd20a44c4121803" + resolved "https://registry.npmjs.org/vfile/-/vfile-3.0.1.tgz#47331d2abe3282424f4a4bb6acd20a44c4121803" dependencies: is-buffer "^2.0.0" replace-ext "1.0.0" @@ -8910,7 +8772,7 @@ write-file-atomic@^1.2.0: imurmurhash "^0.1.4" slide "^1.1.5" -write-file-atomic@^2.0.0: +write-file-atomic@^2.0.0, write-file-atomic@^2.1.0: version "2.4.2" resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz#a7181706dfba17855d221140a9c06e15fcdd87b9" dependencies: @@ -8918,17 +8780,9 @@ write-file-atomic@^2.0.0: imurmurhash "^0.1.4" signal-exit "^3.0.2" -write-file-atomic@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/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" - write@1.0.3: version "1.0.3" - resolved "http://registry.npm.taobao.org/write/download/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + resolved "https://registry.npmjs.org/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" dependencies: mkdirp "^0.5.1" @@ -8960,7 +8814,7 @@ ws@^5.2.0: x-is-string@^0.1.0: version "0.1.0" - resolved "http://registry.npm.taobao.org/x-is-string/download/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" + resolved "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" xcode@^0.9.1: version "0.9.3" @@ -9002,7 +8856,7 @@ xpipe@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/xpipe/-/xpipe-1.0.5.tgz#8dd8bf45fc3f7f55f0e054b878f43a62614dafdf" -xtend@~4.0.0, xtend@~4.0.1: +xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" @@ -9021,12 +8875,12 @@ yallist@^2.1.2: resolved "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" yallist@^3.0.0, yallist@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + version "3.0.3" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" yargs-parser@^10.0.0: version "10.1.0" - resolved "http://registry.npm.taobao.org/yargs-parser/download/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" dependencies: camelcase "^4.1.0" @@ -9094,3 +8948,10 @@ yargs@^9.0.0: which-module "^2.0.0" y18n "^3.2.1" yargs-parser "^7.0.0" + +yauzl@2.10.0: + version "2.10.0" + resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" From ad8cd9ae82d2379e80d518aaebdb3d5297504133 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Wed, 27 Mar 2019 20:45:16 +0800 Subject: [PATCH 050/126] =?UTF-8?q?feat(cli):=20=E5=BF=AB=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E6=A0=B7=E5=BC=8F=E5=B0=BA=E5=AF=B8=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/mini/compileStyle.ts | 4 ++-- packages/taro-cli/src/mini/index.ts | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/taro-cli/src/mini/compileStyle.ts b/packages/taro-cli/src/mini/compileStyle.ts index 4f83384d4f6a..64a42e563e76 100644 --- a/packages/taro-cli/src/mini/compileStyle.ts +++ b/packages/taro-cli/src/mini/compileStyle.ts @@ -18,7 +18,7 @@ import { processStyleImports, promoteRelativePath } from '../util' -import { CSS_EXT, FILE_PROCESSOR_MAP, DEVICE_RATIO_NAME } from '../util/constants' +import { CSS_EXT, FILE_PROCESSOR_MAP, DEVICE_RATIO_NAME, BUILD_TYPES } from '../util/constants' import { IMiniAppConfig } from '../util/types' import { @@ -146,7 +146,7 @@ async function processStyleWithPostCSS (styleObj: IStyleObj): Promise { if (customAutoprefixerConf.enable) { processors.push(autoprefixer(customAutoprefixerConf.config)) } - if (customPxtransformConf.enable) { + if (customPxtransformConf.enable && buildAdapter !== BUILD_TYPES.QUICKAPP) { processors.push(pxtransform(postcssPxtransformConf)) } if (cssUrlConf.enable) { diff --git a/packages/taro-cli/src/mini/index.ts b/packages/taro-cli/src/mini/index.ts index c4abbdb1d091..27574b2e3bc0 100644 --- a/packages/taro-cli/src/mini/index.ts +++ b/packages/taro-cli/src/mini/index.ts @@ -88,7 +88,7 @@ async function buildFrameworkInfo () { } function generateQuickAppManifest () { - const { appConfig, pageConfigs, appPath, outputDir } = getBuildData() + const { appConfig, pageConfigs, appPath, outputDir, projectConfig } = getBuildData() // 生成 router const pages = appConfig.pages as string[] const routerPages = {} @@ -125,6 +125,9 @@ function generateQuickAppManifest () { } quickappJSON.router = router quickappJSON.display = display + quickappJSON.config = Object.assign({}, quickappJSON.config, { + designWidth: projectConfig.designWidth || 750 + }) fs.writeFileSync(path.join(outputDir, 'manifest.json'), JSON.stringify(quickappJSON, null, 2)) } @@ -194,8 +197,7 @@ async function prepareQuickAppEnvironment (isWatch, buildData) { async function runQuickApp (isWatch) { if (isWatch) { - shelljs.exec('npm run server -- --port 12306', { silent: false }) - // shelljs.exec('npm run watch', { silent: false }) + shelljs.exec('npm run watch & npm run server -- --port 12310', { silent: false }) } } From 73761fe7799807cc3e19ab919c99e813e754f28a Mon Sep 17 00:00:00 2001 From: luckyadam Date: Wed, 27 Mar 2019 20:45:16 +0800 Subject: [PATCH 051/126] =?UTF-8?q?feat(cli|quickapp):=20=E5=BF=AB?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E6=A0=B7=E5=BC=8F=E5=B0=BA=E5=AF=B8=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-quickapp/src/native-api.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/taro-quickapp/src/native-api.js b/packages/taro-quickapp/src/native-api.js index 6299f209cd64..a42f35639031 100644 --- a/packages/taro-quickapp/src/native-api.js +++ b/packages/taro-quickapp/src/native-api.js @@ -1,4 +1,9 @@ -import { onAndSyncApis, noPromiseApis, otherApis } from '@tarojs/taro' +import { + onAndSyncApis, + noPromiseApis, + otherApis, + initPxTransform +} from '@tarojs/taro' import request from './api/request' import storage from './api/storage' @@ -15,9 +20,15 @@ function canIUseWebp () { return true } +function pxTransform (size) { + return size + 'px' +} + export default function initNativeApi (taro) { processApis(taro) taro.request = request taro.canIUseWebp = canIUseWebp + taro.initPxTransform = initPxTransform.bind(taro) + taro.pxTransform = pxTransform.bind(taro) Object.assign(taro, storage) } From e0f6fbcf43092b636c6686928a89601ba3d086bb Mon Sep 17 00:00:00 2001 From: yuche Date: Wed, 27 Mar 2019 19:59:40 +0800 Subject: [PATCH 052/126] =?UTF-8?q?feat(weapp):=20=E5=AE=9E=E7=8E=B0=20rea?= =?UTF-8?q?ct=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/mini/index.ts | 2 +- packages/taro-weapp/src/component.js | 6 + packages/taro-weapp/src/create-component.js | 13 +- packages/taro-weapp/src/current-owner.js | 4 + packages/taro-weapp/src/hooks.js | 166 ++++++++++++++++++++ packages/taro-weapp/src/index.js | 4 +- packages/taro-weapp/src/lifecycle.js | 35 +++-- packages/taro-weapp/src/util.js | 8 + 8 files changed, 223 insertions(+), 15 deletions(-) create mode 100644 packages/taro-weapp/src/current-owner.js create mode 100644 packages/taro-weapp/src/hooks.js diff --git a/packages/taro-cli/src/mini/index.ts b/packages/taro-cli/src/mini/index.ts index 27574b2e3bc0..5bfc9767e00b 100644 --- a/packages/taro-cli/src/mini/index.ts +++ b/packages/taro-cli/src/mini/index.ts @@ -26,7 +26,7 @@ import { } from './helper' import { buildEntry } from './entry' import { buildPages } from './page' -import { watchFiles } from './watch' +// import { watchFiles } from './watch' import { downloadGithubRepoLatestRelease } from '../util/dowload' const appPath = process.cwd() diff --git a/packages/taro-weapp/src/component.js b/packages/taro-weapp/src/component.js index da767bb920e8..bb18d600792d 100644 --- a/packages/taro-weapp/src/component.js +++ b/packages/taro-weapp/src/component.js @@ -33,6 +33,12 @@ class BaseComponent { path: '' } + _afterScheduleEffect = false + _disableEffect = false + hooks = [] + effects = [] + layoutEffects = [] + constructor (props = {}, isPage) { this.state = {} this.props = props diff --git a/packages/taro-weapp/src/create-component.js b/packages/taro-weapp/src/create-component.js index 2fd3d6969e0c..66c02fe8b5da 100644 --- a/packages/taro-weapp/src/create-component.js +++ b/packages/taro-weapp/src/create-component.js @@ -1,9 +1,10 @@ import { getCurrentPageUrl } from '@tarojs/utils' -import { isEmptyObject } from './util' +import { isEmptyObject, noop, isFunction } from './util' import { updateComponent } from './lifecycle' import { cacheDataSet, cacheDataGet, cacheDataHas } from './data-cache' import propsManager from './propsManager' +import { Current } from './current-owner' const anonymousFnNamePreffix = 'funPrivate' const routerParamsPrivateKey = '__key_' @@ -275,6 +276,8 @@ function createComponent (ComponentClass, isPage) { const componentInstance = new ComponentClass(componentProps) componentInstance._constructor && componentInstance._constructor(componentProps) try { + Current.current = componentInstance + Current.index = 0 componentInstance.state = componentInstance._createData() || componentInstance.state } catch (err) { if (isPage) { @@ -334,7 +337,13 @@ function createComponent (ComponentClass, isPage) { } }, detached () { - componentTrigger(this.$component, 'componentWillUnmount') + const component = this.$component + componentTrigger(component, 'componentWillUnmount') + component.hooks.forEach((hook) => { + if (isFunction(hook.cleanup)) { + hook.cleanup() + } + }) } } if (isPage) { diff --git a/packages/taro-weapp/src/current-owner.js b/packages/taro-weapp/src/current-owner.js new file mode 100644 index 000000000000..dfaf7aa3d1dc --- /dev/null +++ b/packages/taro-weapp/src/current-owner.js @@ -0,0 +1,4 @@ +export const Current = { + current: null, + index: 0 +} diff --git a/packages/taro-weapp/src/hooks.js b/packages/taro-weapp/src/hooks.js new file mode 100644 index 000000000000..6b1d00e6e2e5 --- /dev/null +++ b/packages/taro-weapp/src/hooks.js @@ -0,0 +1,166 @@ +import { isFunction, isUndefined, isArray, isNullOrUndef } from './util' +import { Current } from './current-owner' +import nextTick from './next-tick' + +function getHooks (index) { + if (Current.current === null) { + throw new Error(`invalid hooks call: hooks can only be called in a stateless component.`) + } + const hooks = Current.current.hooks + if (index >= hooks.length) { + hooks.push({}) + } + return hooks[index] +} + +export function useState (initialState) { + if (isFunction(initialState)) { + initialState = initialState() + } + const hook = getHooks(Current.index++) + if (!hook.state) { + hook.component = Current.current + hook.state = [ + initialState, + (action) => { + hook.state[0] = isFunction(action) ? action(hook.state[0]) : action + hook.component._disable = false + hook.component.setState({}) + } + ] + } + return hook.state +} + +export function useReducer ( + reducer, + initialState, + initializer +) { + if (isFunction(initialState)) { + initialState = initialState() + } + const hook = getHooks(Current.index++) + if (!hook.state) { + hook.component = Current.current + hook.state = [ + isUndefined(initializer) ? initialState : initializer(initialState), + (action) => { + hook.state[0] = reducer(hook.state[0], action) + hook.component._disable = false + hook.component.setState({}) + } + ] + } + return hook.state +} + +function areDepsChanged (prevDeps, deps) { + if (isNullOrUndef(prevDeps) || isNullOrUndef(deps)) { + return true + } + return deps.some((a, i) => a !== prevDeps[i]) +} + +export function invokeEffects (component, delay) { + const effects = delay ? component.effects : component.layoutEffects + effects.forEach((hook) => { + if (isFunction(hook.cleanup)) { + hook.cleanup() + } + const result = hook.effect() + if (isFunction(result)) { + hook.cleanup = result + } + }) + + if (delay) { + component.effects = [] + } else { + component.layoutEffects = [] + } +} + +let scheduleEffectComponents = [] + +function invokeScheduleEffects (component) { + if (!component._afterScheduleEffect) { + component._afterScheduleEffect = true + scheduleEffectComponents.push(component) + if (scheduleEffectComponents.length === 1) { + nextTick(() => { + setTimeout(() => { + scheduleEffectComponents.forEach((c) => { + c._afterScheduleEffect = false + invokeEffects(c, true) + }) + scheduleEffectComponents = [] + }, 0) + }) + } + } +} + +function useEffectImpl (effect, deps, delay) { + const hook = getHooks(Current.index++) + if (Current.current._disableHooks || !Current.current.__isReady) { + return + } + if (areDepsChanged(hook.deps, deps)) { + hook.effect = effect + hook.deps = deps + + if (delay) { + Current.current.effects = Current.current.effects.concat(hook) + invokeScheduleEffects(Current.current) + } else { + Current.current.layoutEffects = Current.current.layoutEffects.concat(hook) + } + } +} + +export function useEffect (effect, deps) { + useEffectImpl(effect, deps, true) +} + +export function useLayoutEffect (effect, deps) { + useEffectImpl(effect, deps) +} + +export function useRef (initialValue) { + const hook = getHooks(Current.index++) + if (!hook.ref) { + hook.ref = { + current: initialValue + } + } + return hook.ref +} + +export function useMemo (factory, deps) { + const hook = getHooks(Current.index++) + if (areDepsChanged(hook.deps, deps)) { + hook.deps = deps + hook.callback = factory + hook.value = factory() + } + return hook.value +} + +export function useCallback (callback, deps) { + return useMemo(() => callback, deps) +} + +export function useImperativeHandle (ref, init, deps) { + useLayoutEffect(() => { + if (isFunction(ref)) { + ref(init()) + return () => ref(null) + } else if (!isUndefined(ref)) { + ref.current = init() + return () => { + delete ref.current + } + } + }, isArray(deps) ? deps.concat([ref]) : undefined) +} diff --git a/packages/taro-weapp/src/index.js b/packages/taro-weapp/src/index.js index 148b4bc322db..7cc4a6361ec9 100644 --- a/packages/taro-weapp/src/index.js +++ b/packages/taro-weapp/src/index.js @@ -19,6 +19,7 @@ import createComponent from './create-component' import initNativeApi from './native-api' import propsManager from './propsManager' import { getElementById, genCompid, genLoopCompid } from './util' +import { useEffect, useLayoutEffect, useReducer, useState, useRef, useCallback, useMemo, useImperativeHandle } from './hooks' export const Taro = { Component, @@ -39,7 +40,8 @@ export const Taro = { propsManager, interceptors, genCompid, - genLoopCompid + genLoopCompid, + useEffect, useLayoutEffect, useReducer, useState, useRef, useCallback, useMemo, useImperativeHandle } export default Taro diff --git a/packages/taro-weapp/src/lifecycle.js b/packages/taro-weapp/src/lifecycle.js index 5c4cd9bc6b3c..5330761a9292 100644 --- a/packages/taro-weapp/src/lifecycle.js +++ b/packages/taro-weapp/src/lifecycle.js @@ -2,20 +2,22 @@ import { internal_safe_get as safeGet, internal_safe_set as safeSet } from '@tarojs/taro' -import PropTypes from 'prop-types' +// import PropTypes from 'prop-types' import { componentTrigger } from './create-component' import { shakeFnFromObject, isEmptyObject, diffObjToPath } from './util' +import { Current } from './current-owner' +import { invokeEffects } from './hooks' -const isDEV = typeof process === 'undefined' || - !process.env || - process.env.NODE_ENV !== 'production' +// const isDEV = typeof process === 'undefined' || +// !process.env || +// process.env.NODE_ENV !== 'production' export function updateComponent (component) { - const { props, __propTypes } = component - if (isDEV && __propTypes) { - const componentName = component.constructor.name || component.constructor.toString().match(/^function\s*([^\s(]+)/)[1] - PropTypes.checkPropTypes(__propTypes, props, 'prop', componentName) - } + const { props } = component + // if (isDEV && __propTypes) { + // const componentName = component.constructor.name || component.constructor.toString().match(/^function\s*([^\s(]+)/)[1] + // PropTypes.checkPropTypes(__propTypes, props, 'prop', componentName) + // } const prevProps = component.prevProps || props component.props = prevProps if (component.__mounted && component._unsafeCallUpdate === true && component.componentWillReceiveProps) { @@ -61,8 +63,16 @@ function doUpdate (component, prevProps, prevState) { let data = state || {} if (component._createData) { // 返回null或undefined则保持不变 - const isRunLoopRef = !component.__mounted - data = component._createData(state, props, isRunLoopRef) || data + const runLoopRef = !component.__mounted + if (component.__isReady) { + Current.current = component + Current.index = 0 + invokeEffects(component, true) + } + data = component._createData(state, props, runLoopRef) || data + if (component.__isReady) { + Current.current = null + } } data = Object.assign({}, props, data) @@ -99,6 +109,7 @@ function doUpdate (component, prevProps, prevState) { const cb = function () { if (__mounted) { + invokeEffects(component) if (component['$$refs'] && component['$$refs'].length > 0) { component['$$refs'].forEach(ref => { // 只有 component 类型能做判断。因为 querySelector 每次调用都一定返回 nodeRefs,无法得知 dom 类型的挂载状态。 @@ -117,7 +128,9 @@ function doUpdate (component, prevProps, prevState) { } if (component['$$hasLoopRef']) { + component._disableEffect = true component._createData(component.state, component.props, true) + component._disableEffect = false } if (typeof component.componentDidUpdate === 'function') { diff --git a/packages/taro-weapp/src/util.js b/packages/taro-weapp/src/util.js index 819f7cc10765..573938e00cd8 100644 --- a/packages/taro-weapp/src/util.js +++ b/packages/taro-weapp/src/util.js @@ -12,6 +12,14 @@ export function isEmptyObject (obj) { return true } +export function isUndefined (o) { + return o === undefined +} + +export function isNullOrUndef (o) { + return isUndefined(o) || o === null +} + /** * JSON 克隆 * @param {Object | Json} jsonObj json对象 From aed4f806cfb1d3d9e7e4911014d4108bca5e3f09 Mon Sep 17 00:00:00 2001 From: yuche Date: Thu, 28 Mar 2019 16:50:07 +0800 Subject: [PATCH 053/126] =?UTF-8?q?feat(taro):=20=E5=A2=9E=E5=8A=A0=20hook?= =?UTF-8?q?s=20=E7=9A=84=20typings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro/types/index.d.ts | 215 +++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) diff --git a/packages/taro/types/index.d.ts b/packages/taro/types/index.d.ts index 1bbeb742177f..c70198a99bbd 100644 --- a/packages/taro/types/index.d.ts +++ b/packages/taro/types/index.d.ts @@ -12083,4 +12083,219 @@ declare namespace Taro { function database(config?: ICloudConfig): DB.Database } + // + // React Hooks + // ---------------------------------------------------------------------- + + interface RefObject { + readonly current: T | null; + } + + // based on the code in https://github.com/facebook/react/pull/13968 + + // Unlike the class component setState, the updates are not allowed to be partial + type SetStateAction = S | ((prevState: S) => S); + // this technically does accept a second argument, but it's already under a deprecation warning + // and it's not even released so probably better to not define it. + type Dispatch = (value: A) => void; + // Unlike redux, the actions _can_ be anything + type Reducer = (prevState: S, action: A) => S; + // types used to try and prevent the compiler from reducing S + // to a supertype common with the second argument to useReducer() + type ReducerState> = R extends Reducer ? S : never; + type ReducerAction> = R extends Reducer ? A : never; + // The identity check is done with the SameValue algorithm (Object.is), which is stricter than === + // TODO (TypeScript 3.0): ReadonlyArray + type DependencyList = ReadonlyArray; + + // NOTE: callbacks are _only_ allowed to return either void, or a destructor. + // The destructor is itself only allowed to return void. + type EffectCallback = () => (void | (() => void | undefined)); + + interface MutableRefObject { + current: T; + } + + /** + * Returns a stateful value, and a function to update it. + * + * @version 16.8.0 + * @see https://reactjs.org/docs/hooks-reference.html#usestate + */ + function useState(initialState: S | (() => S)): [S, Dispatch>]; + // convenience overload when first argument is ommitted + /** + * Returns a stateful value, and a function to update it. + * + * @version 16.8.0 + * @see https://reactjs.org/docs/hooks-reference.html#usestate + */ + function useState(): [S | undefined, Dispatch>]; + /** + * An alternative to `useState`. + * + * `useReducer` is usually preferable to `useState` when you have complex state logic that involves + * multiple sub-values. It also lets you optimize performance for components that trigger deep + * updates because you can pass `dispatch` down instead of callbacks. + * + * @version 16.8.0 + * @see https://reactjs.org/docs/hooks-reference.html#usereducer + */ + // overload where "I" may be a subset of ReducerState; used to provide autocompletion. + // If "I" matches ReducerState exactly then the last overload will allow initializer to be ommitted. + // the last overload effectively behaves as if the identity function (x => x) is the initializer. + function useReducer, I>( + reducer: R, + initializerArg: I & ReducerState, + initializer?: (arg: I & ReducerState) => ReducerState + ): [ReducerState, Dispatch>]; + /** + * An alternative to `useState`. + * + * `useReducer` is usually preferable to `useState` when you have complex state logic that involves + * multiple sub-values. It also lets you optimize performance for components that trigger deep + * updates because you can pass `dispatch` down instead of callbacks. + * + * @version 16.8.0 + * @see https://reactjs.org/docs/hooks-reference.html#usereducer + */ + // overload for free "I"; all goes as long as initializer converts it into "ReducerState". + function useReducer, I>( + reducer: R, + initializerArg: I, + initializer: (arg: I) => ReducerState + ): [ReducerState, Dispatch>]; + /** + * An alternative to `useState`. + * + * `useReducer` is usually preferable to `useState` when you have complex state logic that involves + * multiple sub-values. It also lets you optimize performance for components that trigger deep + * updates because you can pass `dispatch` down instead of callbacks. + * + * @version 16.8.0 + * @see https://reactjs.org/docs/hooks-reference.html#usereducer + */ + + // I'm not sure if I keep this 2-ary or if I make it (2,3)-ary; it's currently (2,3)-ary. + // The Flow types do have an overload for 3-ary invocation with undefined initializer. + + // NOTE: without the ReducerState indirection, TypeScript would reduce S to be the most common + // supertype between the reducer's return type and the initialState (or the initializer's return type), + // which would prevent autocompletion from ever working. + + // TODO: double-check if this weird overload logic is necessary. It is possible it's either a bug + // in older versions, or a regression in newer versions of the typescript completion service. + function useReducer>( + reducer: R, + initialState: ReducerState, + initializer?: undefined + ): [ReducerState, Dispatch>]; + /** + * `useRef` returns a mutable ref object whose `.current` property is initialized to the passed argument + * (`initialValue`). The returned object will persist for the full lifetime of the component. + * + * Note that `useRef()` is useful for more than the `ref` attribute. It’s handy for keeping any mutable + * value around similar to how you’d use instance fields in classes. + * + * @version 16.8.0 + * @see https://reactjs.org/docs/hooks-reference.html#useref + */ + // TODO (TypeScript 3.0): + function useRef(initialValue: T): MutableRefObject; + // convenience overload for refs given as a ref prop as they typically start with a null value + /** + * `useRef` returns a mutable ref object whose `.current` property is initialized to the passed argument + * (`initialValue`). The returned object will persist for the full lifetime of the component. + * + * Note that `useRef()` is useful for more than the `ref` attribute. It’s handy for keeping any mutable + * value around similar to how you’d use instance fields in classes. + * + * Usage note: if you need the result of useRef to be directly mutable, include `| null` in the type + * of the generic argument. + * + * @version 16.8.0 + * @see https://reactjs.org/docs/hooks-reference.html#useref + */ + // TODO (TypeScript 3.0): + function useRef(initialValue: T|null): RefObject; + // convenience overload for potentially undefined initialValue / call with 0 arguments + // has a default to stop it from defaulting to {} instead + /** + * `useRef` returns a mutable ref object whose `.current` property is initialized to the passed argument + * (`initialValue`). The returned object will persist for the full lifetime of the component. + * + * Note that `useRef()` is useful for more than the `ref` attribute. It’s handy for keeping any mutable + * value around similar to how you’d use instance fields in classes. + * + * @version 16.8.0 + * @see https://reactjs.org/docs/hooks-reference.html#useref + */ + // TODO (TypeScript 3.0): + function useRef(): MutableRefObject; + /** + * The signature is identical to `useEffect`, but it fires synchronously after all DOM mutations. + * Use this to read layout from the DOM and synchronously re-render. Updates scheduled inside + * `useLayoutEffect` will be flushed synchronously, before the browser has a chance to paint. + * + * Prefer the standard `useEffect` when possible to avoid blocking visual updates. + * + * If you’re migrating code from a class component, `useLayoutEffect` fires in the same phase as + * `componentDidMount` and `componentDidUpdate`. + * + * @version 16.8.0 + * @see https://reactjs.org/docs/hooks-reference.html#uselayouteffect + */ + function useLayoutEffect(effect: EffectCallback, deps?: DependencyList): void; + /** + * Accepts a function that contains imperative, possibly effectful code. + * + * @param effect Imperative function that can return a cleanup function + * @param deps If present, effect will only activate if the values in the list change. + * + * @version 16.8.0 + * @see https://reactjs.org/docs/hooks-reference.html#useeffect + */ + function useEffect(effect: EffectCallback, deps?: DependencyList): void; + // NOTE: this does not accept strings, but this will have to be fixed by removing strings from type Ref + /** + * `useImperativeHandle` customizes the instance value that is exposed to parent components when using + * `ref`. As always, imperative code using refs should be avoided in most cases. + * + * `useImperativeHandle` should be used with `React.forwardRef`. + * + * @version 16.8.0 + * @see https://reactjs.org/docs/hooks-reference.html#useimperativehandle + */ + function useImperativeHandle(ref: RefObject|undefined, init: () => R, deps?: DependencyList): void; + // I made 'inputs' required here and in useMemo as there's no point to memoizing without the memoization key + // useCallback(X) is identical to just using X, useMemo(() => Y) is identical to just using Y. + /** + * `useCallback` will return a memoized version of the callback that only changes if one of the `inputs` + * has changed. + * + * @version 16.8.0 + * @see https://reactjs.org/docs/hooks-reference.html#usecallback + */ + // TODO (TypeScript 3.0): unknown> + function useCallback any>(callback: T, deps: DependencyList): T; + /** + * `useMemo` will only recompute the memoized value when one of the `deps` has changed. + * + * Usage note: if calling `useMemo` with a referentially stable function, also give it as the input in + * the second argument. + * + * ```ts + * function expensive () { ... } + * + * function Component () { + * const expensiveResult = useMemo(expensive, [expensive]) + * return ... + * } + * ``` + * + * @version 16.8.0 + * @see https://reactjs.org/docs/hooks-reference.html#usememo + */ + // allow undefined, but don't make it optional as that is very likely a mistake + function useMemo(factory: () => T, deps: DependencyList | undefined): T; } From 577f925c513afce46c4204f37b75e8893bd03987 Mon Sep 17 00:00:00 2001 From: yuche Date: Mon, 1 Apr 2019 16:14:34 +0800 Subject: [PATCH 054/126] =?UTF-8?q?fix(transformer):=20=E7=89=B9=E6=AE=8A?= =?UTF-8?q?=E5=BF=AB=E5=BA=94=E7=94=A8=E7=BB=84=E4=BB=B6=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E5=BD=93=E6=88=90=E8=87=AA=E5=AE=9A=E4=B9=89=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/index.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/taro-transformer-wx/src/index.ts b/packages/taro-transformer-wx/src/index.ts index 64ae9b99e208..434dd8bcd106 100644 --- a/packages/taro-transformer-wx/src/index.ts +++ b/packages/taro-transformer-wx/src/index.ts @@ -167,7 +167,10 @@ interface TransformResult extends Result { export default function transform (options: Options): TransformResult { if (options.adapter) { setAdapter(options.adapter) - if (Adapter.type === Adapters.quickapp) DEFAULT_Component_SET.add('div') + if (Adapter.type === Adapters.quickapp) { + DEFAULT_Component_SET.add('div') + quickappComponentName.forEach((n) => DEFAULT_Component_SET.delete(n)) + } } if (Adapter.type === Adapters.swan) { setLoopOriginal('privateOriginal') From 8be21ee58fe679b5f4f554770c237dde3c439fc5 Mon Sep 17 00:00:00 2001 From: yuche Date: Mon, 1 Apr 2019 17:02:31 +0800 Subject: [PATCH 055/126] =?UTF-8?q?fix(transformer):=20=E5=BF=AB=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E7=89=B9=E6=AE=8A=E7=BB=84=E4=BB=B6=E4=B8=8D=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E5=8A=A0=E5=85=A5=E6=9C=80=E7=BB=88=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E7=9A=84=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/class.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/taro-transformer-wx/src/class.ts b/packages/taro-transformer-wx/src/class.ts index 4d2ad5c97b3c..1f4cb4a4c10c 100644 --- a/packages/taro-transformer-wx/src/class.ts +++ b/packages/taro-transformer-wx/src/class.ts @@ -13,7 +13,7 @@ import { incrementId, isContainStopPropagation } from './utils' -import { DEFAULT_Component_SET, ANONYMOUS_FUNC, COMPONENTS_PACKAGE_NAME } from './constant' +import { DEFAULT_Component_SET, COMPONENTS_PACKAGE_NAME, ANONYMOUS_FUNC, quickappComponentName } from './constant' import { kebabCase, uniqueId, get as safeGet, set as safeSet } from 'lodash' import { RenderParser } from './render' import { findJSXAttrByName } from './jsx' @@ -742,6 +742,9 @@ class Transformer { if (name.startsWith('Taro') && component.sourcePath === COMPONENTS_PACKAGE_NAME) { return } + if (Adapter.type === Adapters.quickapp && quickappComponentName.has(name)) { + return + } this.result.components.push({ path: pathResolver(component.sourcePath, this.sourcePath), name: kebabCase(name), From debe0867b3c8743ccf4af3378801447a071ba6d7 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Mon, 1 Apr 2019 17:23:20 +0800 Subject: [PATCH 056/126] =?UTF-8?q?feat(quickapp):=20=E5=BF=AB=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-quickapp/src/create-component.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/taro-quickapp/src/create-component.js b/packages/taro-quickapp/src/create-component.js index fe6f5fdc5714..6cde8465cb45 100644 --- a/packages/taro-quickapp/src/create-component.js +++ b/packages/taro-quickapp/src/create-component.js @@ -36,6 +36,14 @@ function filterProps (properties, defaultProps = {}, componentProps = {}, compon return newProps } +function bindEvents (componentConf, componentInstance, events) { + events.forEach(name => { + if (componentInstance[name]) { + componentConf[name] = componentInstance[name] + } + }) +} + function getPageUrlParams (url) { const queryStr = url.replace(/^.*\?&?/, '') const params = queryToJson(queryStr) @@ -148,5 +156,6 @@ export default function createComponent (ComponentClass, isPage) { } }) } + ComponentClass['$$events'] && bindEvents(componentConf, componentInstance, ComponentClass['$$events']) return componentConf } From afcc7809d3bd93000c619e11ce27d98708cedf7b Mon Sep 17 00:00:00 2001 From: yuche Date: Mon, 1 Apr 2019 17:38:33 +0800 Subject: [PATCH 057/126] =?UTF-8?q?refactor(transformer):=20=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E5=BF=AB=E5=BA=94=E7=94=A8=E7=9A=84=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89/=E5=86=85=E7=BD=AE=E7=BB=84=E4=BB=B6=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=EF=BC=9A=20*=20=E9=99=A4=E4=BA=86div=20=E4=B9=8B?= =?UTF-8?q?=E5=A4=96=E6=89=80=E6=9C=89=E7=BB=84=E4=BB=B6=E9=83=BD=E6=8C=89?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E7=BB=84=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=20*=20=E4=BB=BB=E4=BD=95=E7=BB=84=E4=BB=B6=E7=9A=84=E6=89=80?= =?UTF-8?q?=E6=9C=89=E4=BA=8B=E4=BB=B6=E5=90=8D=E9=83=BD=E4=BF=9D=E7=95=99?= =?UTF-8?q?=E5=8E=9F=E6=A0=B7=E8=BE=93=E5=87=BA=20*=20=E5=86=85=E7=BD=AE?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=94=AF=E4=B8=80=E8=B5=B7=E4=BD=9C=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E5=9C=B0=E6=96=B9=E5=9C=A8=E4=BA=8E=E4=B8=8D=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E5=8A=A0=E5=85=A5=20result.components=20*=20=E5=BF=AB?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E7=89=B9=E6=AE=8A=E7=BB=84=E4=BB=B6(quickapp?= =?UTF-8?q?ComponentName)=E4=BB=85=E4=BD=9C=E4=B8=BA=E6=9B=B4=E5=90=8D?= =?UTF-8?q?=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/class.ts | 4 ++-- packages/taro-transformer-wx/src/constant.ts | 4 ++++ packages/taro-transformer-wx/src/index.ts | 2 +- packages/taro-transformer-wx/src/jsx.ts | 6 +++--- packages/taro-transformer-wx/src/render.ts | 3 +++ 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/taro-transformer-wx/src/class.ts b/packages/taro-transformer-wx/src/class.ts index 1f4cb4a4c10c..3a8a42ec8116 100644 --- a/packages/taro-transformer-wx/src/class.ts +++ b/packages/taro-transformer-wx/src/class.ts @@ -13,7 +13,7 @@ import { incrementId, isContainStopPropagation } from './utils' -import { DEFAULT_Component_SET, COMPONENTS_PACKAGE_NAME, ANONYMOUS_FUNC, quickappComponentName } from './constant' +import { DEFAULT_Component_SET, COMPONENTS_PACKAGE_NAME, ANONYMOUS_FUNC, quickappComponentName, DEFAULT_Component_SET_COPY } from './constant' import { kebabCase, uniqueId, get as safeGet, set as safeSet } from 'lodash' import { RenderParser } from './render' import { findJSXAttrByName } from './jsx' @@ -742,7 +742,7 @@ class Transformer { if (name.startsWith('Taro') && component.sourcePath === COMPONENTS_PACKAGE_NAME) { return } - if (Adapter.type === Adapters.quickapp && quickappComponentName.has(name)) { + if (Adapter.type === Adapters.quickapp && DEFAULT_Component_SET_COPY.has(name)) { return } this.result.components.push({ diff --git a/packages/taro-transformer-wx/src/constant.ts b/packages/taro-transformer-wx/src/constant.ts index 4c4ef1bbd55f..60b540b3af2f 100644 --- a/packages/taro-transformer-wx/src/constant.ts +++ b/packages/taro-transformer-wx/src/constant.ts @@ -50,6 +50,10 @@ export const DEFAULT_Component_SET = new Set([ 'Template' ]) +// tslint:disable-next-line:variable-name +export const DEFAULT_Component_SET_COPY = new Set([]) +DEFAULT_Component_SET.forEach((c) => DEFAULT_Component_SET_COPY.add(c)) + export const INTERNAL_SAFE_GET = 'internal_safe_get' export const TARO_PACKAGE_NAME = '@tarojs/taro' diff --git a/packages/taro-transformer-wx/src/index.ts b/packages/taro-transformer-wx/src/index.ts index 434dd8bcd106..780a7392fc71 100644 --- a/packages/taro-transformer-wx/src/index.ts +++ b/packages/taro-transformer-wx/src/index.ts @@ -168,8 +168,8 @@ export default function transform (options: Options): TransformResult { if (options.adapter) { setAdapter(options.adapter) if (Adapter.type === Adapters.quickapp) { + DEFAULT_Component_SET.clear() DEFAULT_Component_SET.add('div') - quickappComponentName.forEach((n) => DEFAULT_Component_SET.delete(n)) } } if (Adapter.type === Adapters.swan) { diff --git a/packages/taro-transformer-wx/src/jsx.ts b/packages/taro-transformer-wx/src/jsx.ts index dd2e18eb9ac2..5621621f7f14 100644 --- a/packages/taro-transformer-wx/src/jsx.ts +++ b/packages/taro-transformer-wx/src/jsx.ts @@ -200,7 +200,7 @@ export function parseJSXElement (element: t.JSXElement): string { let value: string | boolean = true let attrValue = attr.value if (typeof name === 'string') { - const isAlipayEvent = Adapter.type === Adapters.alipay && /(^on[A-Z_])|(^catch[A-Z_])/.test(name) + const isAlipayOrQuickappEvent = (Adapter.type === Adapters.alipay || Adapter.type === Adapters.quickapp) && /(^on[A-Z_])|(^catch[A-Z_])/.test(name) if (t.isStringLiteral(attrValue)) { value = attrValue.value } else if (t.isJSXExpressionContainer(attrValue)) { @@ -230,7 +230,7 @@ export function parseJSXElement (element: t.JSXElement): string { value = code } } else { - value = isBindEvent || isAlipayEvent ? code : `{{${isJSXMetHod && name === 'data' ? '...' : ''}${code}}}` + value = isBindEvent || isAlipayOrQuickappEvent ? code : `{{${isJSXMetHod && name === 'data' ? '...' : ''}${code}}}` } } if (Adapter.type === Adapters.swan && name === Adapter.for) { @@ -258,7 +258,7 @@ export function parseJSXElement (element: t.JSXElement): string { } else if ( componentSpecialProps && componentSpecialProps.has(name) || name.startsWith('__fn_') || - isAlipayEvent + isAlipayOrQuickappEvent ) { obj[name] = value } else { diff --git a/packages/taro-transformer-wx/src/render.ts b/packages/taro-transformer-wx/src/render.ts index c9167262a942..3d3b9c479c94 100644 --- a/packages/taro-transformer-wx/src/render.ts +++ b/packages/taro-transformer-wx/src/render.ts @@ -1203,6 +1203,9 @@ export class RenderParser { } } path.node.name = t.jSXIdentifier(transformName) + } else if (Adapter.type === Adapters.quickapp) { + const transformName = name.name + path.node.name = t.jSXIdentifier(transformName) } else if (DEFAULT_Component_SET.has(componentName)) { let transformName = `${eventShouldBeCatched ? 'catch' : 'bind'}` + name.name.slice(2).toLowerCase() From 7e3b15813d6ca1e23befb49fd3792fb34094c9e4 Mon Sep 17 00:00:00 2001 From: yuche Date: Mon, 1 Apr 2019 21:06:37 +0800 Subject: [PATCH 058/126] =?UTF-8?q?refactor(transformer):=20=E5=BF=AB?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E4=BA=8B=E4=BB=B6=20observer=20=E6=9B=B4?= =?UTF-8?q?=E5=90=8D=EF=BC=9A=20propName:=20=5F=5FtriggerObserer=20->=20pr?= =?UTF-8?q?ivateTriggerObserer=20propValue:=20=5F=5FtriggerObserer=20->=20?= =?UTF-8?q?privateTriggerObsererKey?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/jsx.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/taro-transformer-wx/src/jsx.ts b/packages/taro-transformer-wx/src/jsx.ts index 5621621f7f14..f5348a43e6b9 100644 --- a/packages/taro-transformer-wx/src/jsx.ts +++ b/packages/taro-transformer-wx/src/jsx.ts @@ -159,7 +159,8 @@ function parseJSXChildren ( export function parseJSXElement (element: t.JSXElement): string { const children = element.children const { attributes, name } = element.openingElement - const TRIGGER_OBSERER = Adapter.type === Adapters.swan ? 'privateTriggerObserer' : '__triggerObserer' + const TRIGGER_OBSERER = Adapter.type === Adapters.swan || Adapter.type === Adapters.quickapp ? 'privateTriggerObserer' : '__triggerObserer' + const TRIGGER_OBSERER_KEY = Adapter.type === Adapters.quickapp ? 'privateTriggerObsererKey' : '_triggerObserer' if (t.isJSXMemberExpression(name)) { throw codeFrameError(name.loc, '暂不支持 JSX 成员表达式') } @@ -266,13 +267,13 @@ export function parseJSXElement (element: t.JSXElement): string { } } if (!isDefaultComponent && !specialComponentName.includes(componentName) && Adapter.type !== Adapters.weapp && Adapter.type !== Adapters.swan && Adapter.type !== Adapters.tt) { - obj[TRIGGER_OBSERER] = '{{ _triggerObserer }}' + obj[TRIGGER_OBSERER] = `{{ ${TRIGGER_OBSERER_KEY} }}` } return obj }, {}) } else if (!isDefaultComponent && !specialComponentName.includes(componentName)) { if (Adapter.type !== Adapters.weapp && Adapter.type !== Adapters.swan && Adapter.type !== Adapters.tt) { - attributesTrans[TRIGGER_OBSERER] = '{{ _triggerObserer }}' + attributesTrans[TRIGGER_OBSERER] = `{{ ${TRIGGER_OBSERER_KEY} }}` } } From 96b72b924f210fc0c712d2825d45b6788a87ab62 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Mon, 1 Apr 2019 23:09:55 +0800 Subject: [PATCH 059/126] =?UTF-8?q?fix(cli):=20=E5=BF=AB=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E6=97=B6=E8=87=AA=E5=AE=9A=E4=B9=89=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=B2=A1=E6=9C=89=E7=94=9F=E6=88=90=20import=20?= =?UTF-8?q?=E5=BC=95=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/mini/component.ts | 6 +++++- packages/taro-cli/src/mini/page.ts | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/taro-cli/src/mini/component.ts b/packages/taro-cli/src/mini/component.ts index 0ca18e39624c..65868de7c412 100644 --- a/packages/taro-cli/src/mini/component.ts +++ b/packages/taro-cli/src/mini/component.ts @@ -251,11 +251,15 @@ export async function buildSingleComponent ( } else { // 快应用编译,搜集创建组件 ux 文件 const importTaroSelfComponents = getImportTaroSelfComponents(outputComponentJSPath, res.taroSelfComponents) + const importCustomComponents = new Set(componentDepComponents.map(item => { + delete item.type + return item + })) const styleRelativePath = promoteRelativePath(path.relative(outputComponentJSPath, outputComponentWXSSPath)) const uxTxt = generateQuickAppUx({ script: resCode, style: styleRelativePath, - imports: importTaroSelfComponents, + imports: new Set([...importTaroSelfComponents, ...importCustomComponents]), template: componentWXMLContent }) fs.writeFileSync(outputComponentWXMLPath, uxTxt) diff --git a/packages/taro-cli/src/mini/page.ts b/packages/taro-cli/src/mini/page.ts index 3183824545e2..6f024ca01f85 100644 --- a/packages/taro-cli/src/mini/page.ts +++ b/packages/taro-cli/src/mini/page.ts @@ -131,12 +131,16 @@ export async function buildSinglePage (page: string) { } else { // 快应用编译,搜集创建页面 ux 文件 const importTaroSelfComponents = getImportTaroSelfComponents(outputPageJSPath, res.taroSelfComponents) + const importCustomComponents = new Set(pageDepComponents.map(item => { + delete item.type + return item + })) // 生成页面 ux 文件 const styleRelativePath = promoteRelativePath(path.relative(outputPageJSPath, outputPageWXSSPath)) const uxTxt = generateQuickAppUx({ script: resCode, style: styleRelativePath, - imports: importTaroSelfComponents, + imports: new Set([...importTaroSelfComponents, ...importCustomComponents]), template: pageWXMLContent }) fs.writeFileSync(outputPageWXMLPath, uxTxt) From efc0d74040bbde664b8f5b39204537ad80a94a35 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Mon, 1 Apr 2019 23:11:13 +0800 Subject: [PATCH 060/126] =?UTF-8?q?feat(quickapp):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E6=94=AF=E6=8C=81=20&&=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=20setState=20=E5=AE=9E=E7=8E=B0=E5=8F=8A=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E7=94=9F=E5=91=BD=E5=91=A8=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../taro-quickapp/src/create-component.js | 140 +++++++++++++++++- packages/taro-quickapp/src/lifecycle.js | 26 +++- 2 files changed, 157 insertions(+), 9 deletions(-) diff --git a/packages/taro-quickapp/src/create-component.js b/packages/taro-quickapp/src/create-component.js index 6cde8465cb45..8213f58a8629 100644 --- a/packages/taro-quickapp/src/create-component.js +++ b/packages/taro-quickapp/src/create-component.js @@ -2,7 +2,8 @@ import { isEmptyObject, queryToJson } from './util' import { cacheDataGet, cacheDataHas } from './data-cache' import { updateComponent } from './lifecycle' -const privatePropValName = '__triggerObserer' +const privatePropValName = 'privateTriggerObserer' +const anonymousFnNamePreffix = 'funPrivate' const componentFnReg = /^__fn_/ const PRELOAD_DATA_KEY = 'preload' const pageExtraFns = ['onBackPress', 'onMenuPress'] @@ -15,7 +16,7 @@ function filterProps (properties, defaultProps = {}, componentProps = {}, compon } if (typeof componentProps[propName] === 'function') { newProps[propName] = componentProps[propName] - } else if (propName in componentData) { + } else if (componentData && propName in componentData) { newProps[propName] = componentData[propName] } if (componentFnReg.test(propName)) { @@ -36,12 +37,135 @@ function filterProps (properties, defaultProps = {}, componentProps = {}, compon return newProps } -function bindEvents (componentConf, componentInstance, events) { +function processEvent (eventHandlerName, obj) { + if (obj[eventHandlerName]) return + + obj[eventHandlerName] = function (event) { + if (event) { + event.preventDefault = function () {} + event.stopPropagation = function () {} + event.currentTarget = event.currentTarget || event.target || {} + if (event.target) { + Object.assign(event.target, event.detail) + } + Object.assign(event.currentTarget, event.detail) + } + + const scope = this.$component + let callScope = scope + const isAnonymousFn = eventHandlerName.indexOf(anonymousFnNamePreffix) > -1 + let realArgs = [] + let detailArgs = [] + let datasetArgs = [] + let isScopeBinded = false + // 解析从dataset中传过来的参数 + const dataset = event.currentTarget.dataset || {} + const bindArgs = {} + const eventType = event.type.toLocaleLowerCase() + Object.keys(dataset).forEach(key => { + let keyLower = key.toLocaleLowerCase() + if (/^e/.test(keyLower)) { + // 小程序属性里中划线后跟一个下划线会解析成不同的结果 + keyLower = keyLower.replace(/^e/, '') + if (keyLower.indexOf(eventType) >= 0) { + const argName = keyLower.replace(eventType, '') + if (/^(a[a-z]|so)$/.test(argName)) { + bindArgs[argName] = dataset[key] + } + } + } + }) + // 如果是通过triggerEvent触发,并且带有参数 + if (event.__arguments && event.__arguments.length > 0) { + detailArgs = event.__arguments + } + // 普通的事件(非匿名函数),会直接call + if (!isAnonymousFn) { + if ('so' in bindArgs) { + if (bindArgs['so'] !== 'this') { + callScope = bindArgs['so'] + } + isScopeBinded = true + delete bindArgs['so'] + } + if (detailArgs.length > 0) { + !isScopeBinded && detailArgs[0] && (callScope = detailArgs[0]) + detailArgs.shift() + } + if (!isEmptyObject(bindArgs)) { + datasetArgs = Object.keys(bindArgs) + .sort() + .map(key => bindArgs[key]) + } + realArgs = [...datasetArgs, ...detailArgs, event] + } else { + // 匿名函数,会将scope作为第一个参数 + let _scope = null + if ('so' in bindArgs) { + if (bindArgs['so'] !== 'this') { + _scope = bindArgs['so'] + } + isScopeBinded = true + delete bindArgs['so'] + } + if (detailArgs.length > 0) { + !isScopeBinded && detailArgs[0] && (callScope = detailArgs[0]) + detailArgs.shift() + } + if (!isEmptyObject(bindArgs)) { + datasetArgs = Object.keys(bindArgs) + .sort() + .map(key => bindArgs[key]) + } + realArgs = [_scope, ...datasetArgs, ...detailArgs, event] + } + return scope[eventHandlerName].apply(callScope, realArgs) + } +} + +function bindEvents (componentConf, events) { events.forEach(name => { - if (componentInstance[name]) { - componentConf[name] = componentInstance[name] + processEvent(name, componentConf) + }) +} + +function bindStaticFns (componentConf, ComponentClass) { + for (const key in ComponentClass) { + typeof ComponentClass[key] === 'function' && (componentConf[key] = ComponentClass[key]) + } + // 低版本 IOS 下部分属性不能直接访问 + Object.getOwnPropertyNames(ComponentClass).forEach(key => { + const excludes = ['arguments', 'caller', 'length', 'name', 'prototype'] + if (excludes.indexOf(key) < 0) { + typeof ComponentClass[key] === 'function' && (componentConf[key] = ComponentClass[key]) + } + }) +} + +function bindProperties (componentConf, ComponentClass) { + componentConf.properties = ComponentClass.properties || {} + const defaultProps = ComponentClass.defaultProps || {} + for (const key in defaultProps) { + if (defaultProps.hasOwnProperty(key)) { + componentConf.properties[key] = { + type: null, + value: defaultProps[key] + } } + } + componentConf.props = [] + Object.keys(componentConf.properties).forEach(item => { + componentConf.props.push(item) }) + componentConf.props.push(privatePropValName) + componentConf.onPrivatePropChange = function () { + if (!this.$component || !this.$component.__isReady) return + const nextProps = filterProps(ComponentClass.properties, ComponentClass.defaultProps, this.$component.props, this) + this.$component.props = nextProps + this.$component._unsafeCallUpdate = true + updateComponent(this.$component) + this.$component._unsafeCallUpdate = false + } } function getPageUrlParams (url) { @@ -121,6 +245,8 @@ export default function createComponent (ComponentClass, isPage) { // this.$component.$router.path = getCurrentPageUrl() initComponent.apply(this, [ComponentClass, isPage]) } + // 监听数据变化 + this.$watch(privatePropValName, 'onPrivatePropChange') }, onReady () { @@ -156,6 +282,8 @@ export default function createComponent (ComponentClass, isPage) { } }) } - ComponentClass['$$events'] && bindEvents(componentConf, componentInstance, ComponentClass['$$events']) + bindStaticFns(componentConf, ComponentClass) + bindProperties(componentConf, ComponentClass) + ComponentClass['$$events'] && bindEvents(componentConf, ComponentClass['$$events']) return componentConf } diff --git a/packages/taro-quickapp/src/lifecycle.js b/packages/taro-quickapp/src/lifecycle.js index 0bb63bfebb99..386c454234d1 100644 --- a/packages/taro-quickapp/src/lifecycle.js +++ b/packages/taro-quickapp/src/lifecycle.js @@ -9,7 +9,7 @@ import { shakeFnFromObject, isEmptyObject } from './util' const isDEV = typeof process === 'undefined' || !process.env || process.env.NODE_ENV !== 'production' -const privatePropKeyName = '_triggerObserer' +const privatePropKeyName = 'privateTriggerObsererKey' export function updateComponent (component) { const { props, __propTypes } = component @@ -62,7 +62,7 @@ function doUpdate (component, prevProps, prevState) { // 返回null或undefined则保持不变 data = component._createData(state, props) || data } - let privatePropKeyVal = component.$scope[privatePropKeyName] || false + let privatePropKeyVal = component.$scope[privatePropKeyName] || 0 data = Object.assign({}, props, data) if (component.$usedState && component.$usedState.length) { @@ -85,7 +85,7 @@ function doUpdate (component, prevProps, prevState) { data = _data } // 改变这个私有的props用来触发(observer)子组件的更新 - data[privatePropKeyName] = !privatePropKeyVal + data[privatePropKeyName] = privatePropKeyVal + 1 const __mounted = component.__mounted // 每次 setData 都独立生成一个 callback 数组 @@ -94,4 +94,24 @@ function doUpdate (component, prevProps, prevState) { cbs = component._pendingCallbacks component._pendingCallbacks = [] } + + Object.keys(data).map(item => { + if (!(item in component.$scope)) { + component.$scope.$set(item, data[item]) + } else { + component.$scope[item] = data[item] + } + }) + if (__mounted) { + if (typeof component.componentDidUpdate === 'function') { + component.componentDidUpdate(prevProps, prevState) + } + } + + if (cbs.length) { + let i = cbs.length + while (--i >= 0) { + typeof cbs[i] === 'function' && cbs[i].call(component) + } + } } From fabca5a870b8dd9dd6a587a540077a0c2eaf5d5c Mon Sep 17 00:00:00 2001 From: luckyadam Date: Tue, 2 Apr 2019 10:31:25 +0800 Subject: [PATCH 061/126] =?UTF-8?q?fix(quickapp):=20=E5=BF=AB=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E5=B1=9E=E6=80=A7=E4=BC=A0=E9=80=92=E6=9C=80=E5=90=8E?= =?UTF-8?q?=E5=B0=8F=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-quickapp/src/create-component.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/taro-quickapp/src/create-component.js b/packages/taro-quickapp/src/create-component.js index 8213f58a8629..3798d79a3f2b 100644 --- a/packages/taro-quickapp/src/create-component.js +++ b/packages/taro-quickapp/src/create-component.js @@ -2,7 +2,7 @@ import { isEmptyObject, queryToJson } from './util' import { cacheDataGet, cacheDataHas } from './data-cache' import { updateComponent } from './lifecycle' -const privatePropValName = 'privateTriggerObserer' +const privatePropValName = 'privatetriggerobserer' const anonymousFnNamePreffix = 'funPrivate' const componentFnReg = /^__fn_/ const PRELOAD_DATA_KEY = 'preload' @@ -155,7 +155,7 @@ function bindProperties (componentConf, ComponentClass) { } componentConf.props = [] Object.keys(componentConf.properties).forEach(item => { - componentConf.props.push(item) + componentConf.props.push(item.toLocaleLowerCase()) }) componentConf.props.push(privatePropValName) componentConf.onPrivatePropChange = function () { From 3ce13121e5edef6ac213916fd76a6efa42063baa Mon Sep 17 00:00:00 2001 From: luckyadam Date: Wed, 3 Apr 2019 16:38:37 +0800 Subject: [PATCH 062/126] =?UTF-8?q?fix(cli):=20=E4=BF=AE=E6=AD=A3=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E6=96=87=E4=BB=B6=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/mini/page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taro-cli/src/mini/page.ts b/packages/taro-cli/src/mini/page.ts index 6f024ca01f85..e34a19ab4484 100644 --- a/packages/taro-cli/src/mini/page.ts +++ b/packages/taro-cli/src/mini/page.ts @@ -65,7 +65,7 @@ export async function buildSinglePage (page: string) { const isQuickApp = buildAdapter === BUILD_TYPES.QUICKAPP printLog(processTypeEnum.COMPILE, '页面文件', `${sourceDirName}/${page}`) - if (!fs.existsSync(pageJs)) { + if (!fs.existsSync(pageJs) || !fs.statSync(pageJs).isFile()) { printLog(processTypeEnum.ERROR, '页面文件', `${sourceDirName}/${page} 不存在!`) return } From 9aba95c95181d92c0458c1c54832054897c7696a Mon Sep 17 00:00:00 2001 From: luckyadam Date: Wed, 3 Apr 2019 16:39:41 +0800 Subject: [PATCH 063/126] =?UTF-8?q?fix(quickapp):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=BF=AB=E5=BA=94=E7=94=A8=E8=B7=AF=E7=94=B1=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=20API=20url=20=E5=A4=84=E7=90=86=E9=94=99=E8=AF=AF=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-quickapp/src/api/router/index.js | 2 +- packages/taro-quickapp/src/native-api.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/taro-quickapp/src/api/router/index.js b/packages/taro-quickapp/src/api/router/index.js index 8e91e2c89139..5882a12523cf 100644 --- a/packages/taro-quickapp/src/api/router/index.js +++ b/packages/taro-quickapp/src/api/router/index.js @@ -41,7 +41,7 @@ function qappNavigate (options = {}, method = 'push') { params = getUrlParams(url) try { router[method]({ - uri: url, + uri: url.substr(0, url.lastIndexOf('/')), params }) success && success(res) diff --git a/packages/taro-quickapp/src/native-api.js b/packages/taro-quickapp/src/native-api.js index a42f35639031..8755df237740 100644 --- a/packages/taro-quickapp/src/native-api.js +++ b/packages/taro-quickapp/src/native-api.js @@ -6,6 +6,7 @@ import { } from '@tarojs/taro' import request from './api/request' import storage from './api/storage' +import router from './api/router' function processApis (taro) { const weApis = Object.assign({}, onAndSyncApis, noPromiseApis, otherApis) @@ -30,5 +31,5 @@ export default function initNativeApi (taro) { taro.canIUseWebp = canIUseWebp taro.initPxTransform = initPxTransform.bind(taro) taro.pxTransform = pxTransform.bind(taro) - Object.assign(taro, storage) + Object.assign(taro, storage, router) } From a0ee39216c66af53b56c87ff75ec340ee2293d3e Mon Sep 17 00:00:00 2001 From: luckyadam Date: Wed, 3 Apr 2019 16:40:47 +0800 Subject: [PATCH 064/126] =?UTF-8?q?fix(quickapp):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=BF=AB=E5=BA=94=E7=94=A8=E4=BA=8B=E4=BB=B6=20bind=20?= =?UTF-8?q?=E4=BC=A0=E5=8F=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-quickapp/src/component.js | 18 +++++++++++-- .../taro-quickapp/src/create-component.js | 25 ++++++++++++++----- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/packages/taro-quickapp/src/component.js b/packages/taro-quickapp/src/component.js index 605bc98b096e..320c9f5cc095 100644 --- a/packages/taro-quickapp/src/component.js +++ b/packages/taro-quickapp/src/component.js @@ -89,10 +89,24 @@ export default class BaseComponent { } else { // 普通的 const keyLower = key.toLocaleLowerCase() - this.$scope.triggerEvent(keyLower, { + const payload = { __isCustomEvt: true, __arguments: args - }) + } + const detail = {} + if (this.$scope._externalBinding) { + const tempalateAttr = this.$scope._externalBinding.template.attr + Object.keys(tempalateAttr).forEach(item => { + if (/^data/.test(item)) { + detail[item.replace(/^data/, '')] = tempalateAttr[item] + } + }) + } + + if (Object.keys(detail).length) { + payload.__detail = detail + } + this.$scope.$emit(keyLower.replace(/^on/, ''), payload) } } } diff --git a/packages/taro-quickapp/src/create-component.js b/packages/taro-quickapp/src/create-component.js index 3798d79a3f2b..0865f48e5238 100644 --- a/packages/taro-quickapp/src/create-component.js +++ b/packages/taro-quickapp/src/create-component.js @@ -4,7 +4,7 @@ import { updateComponent } from './lifecycle' const privatePropValName = 'privatetriggerobserer' const anonymousFnNamePreffix = 'funPrivate' -const componentFnReg = /^__fn_/ +const componentFnReg = /^prv-fn-/ const PRELOAD_DATA_KEY = 'preload' const pageExtraFns = ['onBackPress', 'onMenuPress'] @@ -20,7 +20,7 @@ function filterProps (properties, defaultProps = {}, componentProps = {}, compon newProps[propName] = componentData[propName] } if (componentFnReg.test(propName)) { - if (componentData[propName] === true) { + if (componentData && componentData[propName] === true) { const fnName = propName.replace(componentFnReg, '') newProps[fnName] = noop } @@ -59,9 +59,22 @@ function processEvent (eventHandlerName, obj) { let datasetArgs = [] let isScopeBinded = false // 解析从dataset中传过来的参数 - const dataset = event.currentTarget.dataset || {} + const currentTarget = event.currentTarget + const dataset = {} + if (currentTarget._vm) { + const tempalateAttr = currentTarget._vm._externalBinding.template.attr + Object.keys(tempalateAttr).forEach(item => { + if (/^data/.test(item)) { + dataset[item.replace(/^data/, '')] = tempalateAttr[item] + } + }) + } + const bindArgs = {} - const eventType = event.type.toLocaleLowerCase() + const eventType = `on${event.type}`.toLocaleLowerCase() + + if (event.detail && event.detail.__detail) Object.assign(dataset, event.detail.__detail) + Object.keys(dataset).forEach(key => { let keyLower = key.toLocaleLowerCase() if (/^e/.test(keyLower)) { @@ -76,8 +89,8 @@ function processEvent (eventHandlerName, obj) { } }) // 如果是通过triggerEvent触发,并且带有参数 - if (event.__arguments && event.__arguments.length > 0) { - detailArgs = event.__arguments + if (event.detail && event.detail.__arguments && event.detail.__arguments.length > 0) { + detailArgs = event.detail.__arguments } // 普通的事件(非匿名函数),会直接call if (!isAnonymousFn) { From 312edd3957d62cb1090a1e0ea9bfcf40606f46a3 Mon Sep 17 00:00:00 2001 From: yuche Date: Tue, 2 Apr 2019 11:33:02 +0800 Subject: [PATCH 065/126] =?UTF-8?q?fix(transformer):=20=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=BC=8F=E7=BB=84=E4=BB=B6=E6=8F=92=E5=85=A5=20props=20?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E8=AF=AD=E5=8F=A5=E4=BD=8D=E7=BD=AE=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/functional.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/taro-transformer-wx/src/functional.ts b/packages/taro-transformer-wx/src/functional.ts index 4225ee74347b..4a2e5ca9adcd 100644 --- a/packages/taro-transformer-wx/src/functional.ts +++ b/packages/taro-transformer-wx/src/functional.ts @@ -62,9 +62,9 @@ export const functionalComponent: () => { } if (arg) { if (t.isIdentifier(arg)) { - cloneBody.body.push(buildConstVariableDeclaration(arg.name, t.memberExpression(t.thisExpression(), t.identifier('props')))) + cloneBody.body.unshift(buildConstVariableDeclaration(arg.name, t.memberExpression(t.thisExpression(), t.identifier('props')))) } else if (t.isObjectPattern(arg)) { - cloneBody.body.push( + cloneBody.body.unshift( t.variableDeclaration('const', [ t.variableDeclarator(arg, t.memberExpression(t.thisExpression(), t.identifier('props'))) ]) From f1b4cd6d8ad25e1964316ecf79f9854b0e61b33b Mon Sep 17 00:00:00 2001 From: yuche Date: Wed, 3 Apr 2019 16:50:40 +0800 Subject: [PATCH 066/126] =?UTF-8?q?refactor(transformer):=20=E5=BF=AB?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E4=BA=8B=E4=BB=B6=20`=5F=5Ffn=5F`=20?= =?UTF-8?q?=E6=9B=B4=E5=90=8D=E4=B8=BA=20`prv-fn-`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/class.ts | 10 +++++----- packages/taro-transformer-wx/src/constant.ts | 4 ++++ packages/taro-transformer-wx/src/index.ts | 2 ++ packages/taro-transformer-wx/src/jsx.ts | 5 +++-- packages/taro-transformer-wx/src/render.ts | 20 ++++++++++++++++++-- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/packages/taro-transformer-wx/src/class.ts b/packages/taro-transformer-wx/src/class.ts index 3a8a42ec8116..291018eb5b95 100644 --- a/packages/taro-transformer-wx/src/class.ts +++ b/packages/taro-transformer-wx/src/class.ts @@ -13,7 +13,7 @@ import { incrementId, isContainStopPropagation } from './utils' -import { DEFAULT_Component_SET, COMPONENTS_PACKAGE_NAME, ANONYMOUS_FUNC, quickappComponentName, DEFAULT_Component_SET_COPY } from './constant' +import { DEFAULT_Component_SET, COMPONENTS_PACKAGE_NAME, ANONYMOUS_FUNC, DEFAULT_Component_SET_COPY, FN_PREFIX } from './constant' import { kebabCase, uniqueId, get as safeGet, set as safeSet } from 'lodash' import { RenderParser } from './render' import { findJSXAttrByName } from './jsx' @@ -665,10 +665,10 @@ class Transformer { const property = callee.property if (t.isIdentifier(property)) { if (property.name.startsWith('on')) { - self.componentProperies.add(`__fn_${property.name}`) + self.componentProperies.add(`${FN_PREFIX}${property.name}`) processThisPropsFnMemberProperties(callee, path, node.arguments, false) } else if (property.name === 'call' || property.name === 'apply') { - self.componentProperies.add(`__fn_${property.name}`) + self.componentProperies.add(`${FN_PREFIX}${property.name}`) processThisPropsFnMemberProperties(callee.object, path, node.arguments, true) } } @@ -700,10 +700,10 @@ class Transformer { } const attrName = attr.node.name if (t.isJSXIdentifier(attrName) && attrName.name.startsWith('on')) { - this.componentProperies.add(`__fn_${attrName.name}`) + this.componentProperies.add(`${FN_PREFIX}${attrName.name}`) } if (methodName.startsWith('on')) { - this.componentProperies.add(`__fn_${methodName}`) + this.componentProperies.add(`${FN_PREFIX}${methodName}`) } const method = (Adapters.weapp !== Adapter.type && Adapters.swan !== Adapter.type && Adapters.tt !== Adapter.type) ? t.classMethod('method', t.identifier(funcName), [], t.blockStatement([ diff --git a/packages/taro-transformer-wx/src/constant.ts b/packages/taro-transformer-wx/src/constant.ts index 60b540b3af2f..50511cfe710c 100644 --- a/packages/taro-transformer-wx/src/constant.ts +++ b/packages/taro-transformer-wx/src/constant.ts @@ -132,6 +132,10 @@ TRANSFORM_COMPONENT_PROPS.set(Adapters.alipay, { export const lessThanSignPlacehold = '__LESS_THAN_SIGN_PLACEHOLDER__' +export let FN_PREFIX = '__fn_' + +export const setFnPrefix = (s: string) => FN_PREFIX = s + export const quickappComponentName = new Set([ 'Swiper', 'Image', diff --git a/packages/taro-transformer-wx/src/index.ts b/packages/taro-transformer-wx/src/index.ts index 780a7392fc71..83b48ffd1c35 100644 --- a/packages/taro-transformer-wx/src/index.ts +++ b/packages/taro-transformer-wx/src/index.ts @@ -29,6 +29,7 @@ import { lessThanSignPlacehold, COMPONENTS_PACKAGE_NAME, quickappComponentName, + setFnPrefix, PROPS_MANAGER, GEN_COMP_ID, GEN_LOOP_COMPID @@ -170,6 +171,7 @@ export default function transform (options: Options): TransformResult { if (Adapter.type === Adapters.quickapp) { DEFAULT_Component_SET.clear() DEFAULT_Component_SET.add('div') + setFnPrefix('prv-fn-') } } if (Adapter.type === Adapters.swan) { diff --git a/packages/taro-transformer-wx/src/jsx.ts b/packages/taro-transformer-wx/src/jsx.ts index f5348a43e6b9..d2b3a98c5701 100644 --- a/packages/taro-transformer-wx/src/jsx.ts +++ b/packages/taro-transformer-wx/src/jsx.ts @@ -8,7 +8,8 @@ import { swanSpecialAttrs, THIRD_PARTY_COMPONENTS, TRANSFORM_COMPONENT_PROPS, - lessThanSignPlacehold + lessThanSignPlacehold, + FN_PREFIX } from './constant' import { createHTMLElement } from './create-html-element' import { codeFrameError, decodeUnicode } from './utils' @@ -258,7 +259,7 @@ export function parseJSXElement (element: t.JSXElement): string { obj['maxlength'] = value } else if ( componentSpecialProps && componentSpecialProps.has(name) || - name.startsWith('__fn_') || + name.startsWith(FN_PREFIX) || isAlipayOrQuickappEvent ) { obj[name] = value diff --git a/packages/taro-transformer-wx/src/render.ts b/packages/taro-transformer-wx/src/render.ts index 3d3b9c479c94..f222e1515f98 100644 --- a/packages/taro-transformer-wx/src/render.ts +++ b/packages/taro-transformer-wx/src/render.ts @@ -50,7 +50,8 @@ import { PROPS_MANAGER, GEN_COMP_ID, GEN_LOOP_COMPID, - ALIPAY_BUBBLE_EVENTS + ALIPAY_BUBBLE_EVENTS, + FN_PREFIX } from './constant' import { Adapter, Adapters } from './adapter' import { buildBabelTransformOptions } from './options' @@ -1188,6 +1189,13 @@ export class RenderParser { } } } + if (t.isJSXIdentifier(componentName) && !DEFAULT_Component_SET.has(componentName.name)) { + const element = path.parent as t.JSXOpeningElement + if (process.env.NODE_ENV !== 'test' && Adapter.type !== Adapters.alipay) { + const fnName = `${FN_PREFIX}${name.name}` + element.attributes = element.attributes.concat([t.jSXAttribute(t.jSXIdentifier(fnName))]) + } + } } if ( t.isJSXIdentifier(jsxElementPath.node.openingElement.name) @@ -1998,7 +2006,15 @@ export class RenderParser { const componentProperies = cloneDeep(this.componentProperies) - componentProperies.clear() + componentProperies.forEach(s => { + if (s.startsWith(FN_PREFIX)) { + const eventName = s.slice(5) + if (componentProperies.has(eventName)) { + componentProperies.delete(s) + componentProperies.delete(eventName) + } + } + }) Array.from(this.reserveStateWords).forEach(this.setReserveWord) const usedState = Array.from( From b228c1f11ae4be2616e0b08944b4a8a339a0e448 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Tue, 9 Apr 2019 16:35:01 +0800 Subject: [PATCH 067/126] =?UTF-8?q?feat(taro-quickapp):=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E9=A1=B6=E9=83=A8=E5=AF=BC=E8=88=AA=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../taro-quickapp/src/api/navigation/index.js | 23 +++++++++++++++++++ packages/taro-quickapp/src/native-api.js | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 packages/taro-quickapp/src/api/navigation/index.js diff --git a/packages/taro-quickapp/src/api/navigation/index.js b/packages/taro-quickapp/src/api/navigation/index.js new file mode 100644 index 000000000000..7b1ad7f77296 --- /dev/null +++ b/packages/taro-quickapp/src/api/navigation/index.js @@ -0,0 +1,23 @@ +import { + eventCenter +} from '@tarojs/taro' + +function setNavigationBar (params) { + eventCenter.trigger('TaroEvent:setNavigationBar', params) + if (params.success) { + params.success() + } +} + +export function setNavigationBarTitle (params) { + setNavigationBar(params) +} + +export function setNavigationBarColor (params) { + setNavigationBar(params) +} + +export default { + setNavigationBarTitle, + setNavigationBarColor +} diff --git a/packages/taro-quickapp/src/native-api.js b/packages/taro-quickapp/src/native-api.js index 8755df237740..f8be87fee404 100644 --- a/packages/taro-quickapp/src/native-api.js +++ b/packages/taro-quickapp/src/native-api.js @@ -7,6 +7,7 @@ import { import request from './api/request' import storage from './api/storage' import router from './api/router' +import navigation from './api/navigation' function processApis (taro) { const weApis = Object.assign({}, onAndSyncApis, noPromiseApis, otherApis) @@ -31,5 +32,5 @@ export default function initNativeApi (taro) { taro.canIUseWebp = canIUseWebp taro.initPxTransform = initPxTransform.bind(taro) taro.pxTransform = pxTransform.bind(taro) - Object.assign(taro, storage, router) + Object.assign(taro, storage, router, navigation) } From 5e90cbcb0f587a0207e958f161a45d3b6e59627c Mon Sep 17 00:00:00 2001 From: luckyadam Date: Tue, 9 Apr 2019 16:36:44 +0800 Subject: [PATCH 068/126] =?UTF-8?q?feat(cli):=20=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=97=B6=E6=B3=A8=E5=85=A5=E5=BF=AB=E5=BA=94=E7=94=A8=E9=A1=B6?= =?UTF-8?q?=E9=83=A8=E5=AF=BC=E8=88=AA=E7=9B=B8=E5=85=B3=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BB=A5=E9=85=8D=E5=90=88=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E6=97=B6=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/mini/astProcess.ts | 115 +++++++++++++++++++---- packages/taro-cli/src/util/astConvert.ts | 6 -- 2 files changed, 97 insertions(+), 24 deletions(-) diff --git a/packages/taro-cli/src/mini/astProcess.ts b/packages/taro-cli/src/mini/astProcess.ts index 38e9400f2b8c..271e215fdcb6 100644 --- a/packages/taro-cli/src/mini/astProcess.ts +++ b/packages/taro-cli/src/mini/astProcess.ts @@ -38,7 +38,11 @@ import { traverseObjectNode, isQuickAppPkg } from '../util' -import { convertObjectToAstExpression, convertArrayToAstExpression } from '../util/astConvert' +import { + convertObjectToAstExpression, + convertArrayToAstExpression, + convertSourceStringToAstExpression +} from '../util/astConvert' import babylonConfig from '../config/babylon' import { getExactedNpmFilePath, getNotExistNpmList } from '../util/npmExact' @@ -247,6 +251,9 @@ export function parseAst ( let exportTaroReduxConnected: string | null = null const isQuickApp = buildAdapter === BUILD_TYPES.QUICKAPP const cannotRemoves = [taroJsFramework, 'react', 'nervjs'] + let hasComponentDidHide + let hasComponentDidShow + let hasComponentWillMount if (isQuickApp) { cannotRemoves.push(taroJsComponents) } @@ -366,10 +373,31 @@ export function parseAst ( } }, + ClassMethod (astPath) { + const keyName = (astPath.get('key').node as t.Identifier).name + if (keyName === 'componentWillMount') { + hasComponentWillMount = true + } else if (keyName === 'componentDidShow') { + hasComponentDidShow = true + } else if (keyName === 'componentDidHide') { + hasComponentDidHide = true + } + }, + ClassProperty (astPath) { const node = astPath.node - if (node.key.name === 'config') { + const keyName = node.key.name + const valuePath = astPath.get('value') + if (keyName === 'config') { configObj = traverseObjectNode(node, buildAdapter) + } else if (valuePath.isFunctionExpression() || valuePath.isArrowFunctionExpression()) { + if (keyName === 'componentWillMount') { + hasComponentWillMount = true + } else if (keyName === 'componentDidShow') { + hasComponentDidShow = true + } else if (keyName === 'componentDidHide') { + hasComponentDidHide = true + } } }, @@ -476,18 +504,16 @@ export function parseAst ( } if (isNpmPkg(value) && !isQuickAppPkg(value) && !notExistNpmList.has(value)) { if (value === taroJsComponents) { - if (buildAdapter === BUILD_TYPES.QUICKAPP) { - if (isQuickApp) { - if (parentNode.declarations.length === 1 && parentNode.declarations[0].init) { - const id = parentNode.declarations[0].id - if (id.type === 'ObjectPattern') { - const properties = id.properties as any - properties.forEach(p => { - if (p.type === 'ObjectProperty' && p.value.type === 'Identifier') { - taroSelfComponents.add(_.kebabCase(p.value.name)) - } - }) - } + if (isQuickApp) { + if (parentNode.declarations.length === 1 && parentNode.declarations[0].init) { + const id = parentNode.declarations[0].id + if (id.type === 'ObjectPattern') { + const properties = id.properties as any + properties.forEach(p => { + if (p.type === 'ObjectProperty' && p.value.type === 'Identifier') { + taroSelfComponents.add(_.kebabCase(p.value.name)) + } + }) } } } @@ -637,6 +663,59 @@ export function parseAst ( Program: { exit (astPath) { astPath.traverse({ + ClassBody (astPath) { + if (isQuickApp) { + const node = astPath.node + if (!hasComponentWillMount) { + node.body.push(t.classMethod( + 'method', t.identifier('hasComponentWillMount'), [], + t.blockStatement([]), false, false)) + } + if (!hasComponentDidShow) { + node.body.push(t.classMethod( + 'method', t.identifier('componentDidShow'), [], + t.blockStatement([]), false, false)) + } + if (!hasComponentDidHide) { + node.body.push(t.classMethod( + 'method', t.identifier('componentDidHide'), [], + t.blockStatement([]), false, false)) + } + node.body.push(t.classMethod( + 'method', t.identifier('__listenToSetNavigationBarEvent'), [], + t.blockStatement([convertSourceStringToAstExpression( + `if (!Taro.eventCenter.callbacks['TaroEvent:setNavigationBar']) { + Taro.eventCenter.on('TaroEvent:setNavigationBar', params => { + if (params.title) { + this.$scope.$page.setTitleBar({ text: params.title }) + } + if (params.frontColor) { + this.$scope.$page.setTitleBar({ textColor: params.frontColor }) + } + if (params.backgroundColor) { + this.$scope.$page.setTitleBar({ backgroundColor: params.backgroundColor }) + } + }) + }` + )]), false, false)) + node.body.push(t.classMethod( + 'method', t.identifier('__offListenToSetNavigationBarEvent'), [], + t.blockStatement([convertSourceStringToAstExpression( + `Taro.eventCenter.off('TaroEvent:setNavigationBar')` + )]), false, false)) + } + }, + ClassMethod (astPath) { + if (isQuickApp) { + const node = astPath.node + const keyName = (node.key as t.Identifier).name + if (keyName === 'componentDidShow' || keyName === 'componentWillMount') { + node.body.body.unshift(convertSourceStringToAstExpression(`this.__listenToSetNavigationBarEvent()`)) + } else if (keyName === 'componentDidHide') { + node.body.body.unshift(convertSourceStringToAstExpression(`this.__offListenToSetNavigationBarEvent()`)) + } + } + }, ImportDeclaration (astPath) { const node = astPath.node const source = node.source @@ -748,7 +827,7 @@ export function parseAst ( }) const node = astPath.node as t.Program const exportVariableName = exportTaroReduxConnected || componentClassName - if (needExportDefault && buildAdapter !== BUILD_TYPES.QUICKAPP) { + if (needExportDefault && !isQuickApp) { const exportDefault = template(`export default ${exportVariableName}`, babylonConfig as any)() node.body.push(exportDefault as any) } @@ -769,7 +848,7 @@ export function parseAst ( if (projectConfig.hasOwnProperty(DEVICE_RATIO_NAME)) { pxTransformConfig[DEVICE_RATIO_NAME] = projectConfig.deviceRatio } - if (buildAdapter === BUILD_TYPES.QUICKAPP) { + if (isQuickApp) { node.body.push(template(`export default require('${taroMiniAppFrameworkPath}').default.createApp(${exportVariableName})`, babylonConfig as any)() as any) } else { node.body.push(template(`App(require('${taroMiniAppFrameworkPath}').default.createApp(${exportVariableName}))`, babylonConfig as any)() as any) @@ -779,14 +858,14 @@ export function parseAst ( case PARSE_AST_TYPE.PAGE: if (buildAdapter === BUILD_TYPES.WEAPP) { node.body.push(template(`Component(require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}, true))`, babylonConfig as any)() as any) - } else if (buildAdapter === BUILD_TYPES.QUICKAPP) { + } else if (isQuickApp) { node.body.push(template(`export default require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}, true)`, babylonConfig as any)() as any) } else { node.body.push(template(`Page(require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}, true))`, babylonConfig as any)() as any) } break case PARSE_AST_TYPE.COMPONENT: - if (buildAdapter === BUILD_TYPES.QUICKAPP) { + if (isQuickApp) { node.body.push(template(`export default require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName})`, babylonConfig as any)() as any) } else { node.body.push(template(`Component(require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}))`, babylonConfig as any)() as any) diff --git a/packages/taro-cli/src/util/astConvert.ts b/packages/taro-cli/src/util/astConvert.ts index ffb39a922025..8aee0493b42f 100644 --- a/packages/taro-cli/src/util/astConvert.ts +++ b/packages/taro-cli/src/util/astConvert.ts @@ -95,9 +95,3 @@ export const getObjKey = (node) => { return node.value } } - -// exports.obj = convertObjectToAstExpression -// exports.array = convertArrayToAstExpression -// exports.source = convertSourceStringToAstExpression -// exports.getObjKey = getObjKey -// exports.generateMinimalEscapeCode = generateMinimalEscapeCode From e49600cbc894991e58b63d1ac841e94c138320fe Mon Sep 17 00:00:00 2001 From: luckyadam Date: Tue, 9 Apr 2019 16:39:20 +0800 Subject: [PATCH 069/126] =?UTF-8?q?feat(components-qa):=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=BF=AB=E5=BA=94=E7=94=A8=20text=20=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=96=87=E5=AD=97=E4=B8=8D=E6=98=BE=E7=A4=BA=E7=9A=84?= =?UTF-8?q?=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-components-qa/src/components/taro-text/index.ux | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/taro-components-qa/src/components/taro-text/index.ux b/packages/taro-components-qa/src/components/taro-text/index.ux index d0eba4ddf688..a97118c4e766 100644 --- a/packages/taro-components-qa/src/components/taro-text/index.ux +++ b/packages/taro-components-qa/src/components/taro-text/index.ux @@ -1,12 +1,12 @@ From b5b80c01e9b43cff0391a0b4882b672915a7ba08 Mon Sep 17 00:00:00 2001 From: yuche Date: Tue, 16 Apr 2019 14:21:27 +0800 Subject: [PATCH 084/126] =?UTF-8?q?fix(transformer):=20=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E8=B0=83=E7=94=A8=20transformer=20=E5=87=BD=E6=95=B0=E5=87=BA?= =?UTF-8?q?=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/taro-transformer-wx/src/index.ts b/packages/taro-transformer-wx/src/index.ts index 6199e27a4dd2..b2eff3eebd4a 100644 --- a/packages/taro-transformer-wx/src/index.ts +++ b/packages/taro-transformer-wx/src/index.ts @@ -181,8 +181,8 @@ export default function transform (options: Options): TransformResult { } if (Adapter.type === Adapters.swan || Adapter.type === Adapters.quickapp) { setLoopOriginal('privateOriginal') - setLoopCallee(LOOP_CALLEE.slice(1)) - setLoopState(LOOP_STATE.slice(1)) + setLoopCallee('anonymousCallee_') + setLoopState('loopState') } THIRD_PARTY_COMPONENTS.clear() const code = options.isTyped From a09528679e22ec8e04effc5fb7b9f0553dfcfdf1 Mon Sep 17 00:00:00 2001 From: yuche Date: Tue, 16 Apr 2019 15:07:54 +0800 Subject: [PATCH 085/126] =?UTF-8?q?chore(transformer):=20=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=9C=AA=E4=BD=BF=E7=94=A8=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/index.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/taro-transformer-wx/src/index.ts b/packages/taro-transformer-wx/src/index.ts index b2eff3eebd4a..991d41d90fee 100644 --- a/packages/taro-transformer-wx/src/index.ts +++ b/packages/taro-transformer-wx/src/index.ts @@ -30,13 +30,11 @@ import { COMPONENTS_PACKAGE_NAME, quickappComponentName, setFnPrefix, - PROPS_MANAGER, - GEN_COMP_ID, - GEN_LOOP_COMPID, setLoopCallee, - LOOP_CALLEE, setLoopState, - LOOP_STATE + PROPS_MANAGER, + GEN_COMP_ID, + GEN_LOOP_COMPID } from './constant' import { Adapters, setAdapter, Adapter } from './adapter' import { Options, setTransformOptions, buildBabelTransformOptions } from './options' From c7bf06d19d9116b8d182c28668e06acd624e2ef7 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Tue, 16 Apr 2019 16:45:47 +0800 Subject: [PATCH 086/126] =?UTF-8?q?fix(cli):=20=E7=BC=96=E8=AF=91=E6=97=B6?= =?UTF-8?q?=E6=8F=90=E5=89=8D=E5=8A=A0=E5=85=A5=E7=8E=AF=E5=A2=83=E5=8F=98?= =?UTF-8?q?=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/bin/taro-build | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/taro-cli/bin/taro-build b/packages/taro-cli/bin/taro-build index bf90af6fd898..645bd285b7fc 100755 --- a/packages/taro-cli/bin/taro-build +++ b/packages/taro-cli/bin/taro-build @@ -60,6 +60,8 @@ if (env) { } } +process.env.TARO_ENV = type + const projectConf = require(projectConfPath)(_.merge) console.log(chalk.green(`开始编译项目 ${chalk.bold(projectConf.projectName)}`)) From 4faab0e0b019e8fbe28f43aead24ef12674fab77 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Tue, 16 Apr 2019 16:46:18 +0800 Subject: [PATCH 087/126] =?UTF-8?q?fix(taro-qucikapp):=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../taro-quickapp/src/create-component.js | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/packages/taro-quickapp/src/create-component.js b/packages/taro-quickapp/src/create-component.js index 0865f48e5238..9cccbe240f91 100644 --- a/packages/taro-quickapp/src/create-component.js +++ b/packages/taro-quickapp/src/create-component.js @@ -42,13 +42,28 @@ function processEvent (eventHandlerName, obj) { obj[eventHandlerName] = function (event) { if (event) { - event.preventDefault = function () {} - event.stopPropagation = function () {} - event.currentTarget = event.currentTarget || event.target || {} - if (event.target) { - Object.assign(event.target, event.detail) - } - Object.assign(event.currentTarget, event.detail) + const currentTarget = event.currentTarget + const target = event.target + Object.defineProperties(event, { + target: { + configurable: true, + get () { + return Object.assign(target || {}, event.detail) + } + }, + currentTarget: { + configurable: true, + get () { + return Object.assign(currentTarget || target || {}, event.detail) + } + }, + stopPropagation: { + value: () => {} + }, + preventDefault: { + value: () => {} + } + }) } const scope = this.$component From c9a102fed063061ff761baf7f563739630744e0f Mon Sep 17 00:00:00 2001 From: luckyadam Date: Tue, 16 Apr 2019 16:46:53 +0800 Subject: [PATCH 088/126] =?UTF-8?q?fix(components-qa):=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E9=A1=B5=E9=9D=A2=E5=AE=B9=E5=99=A8=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-components-qa/src/components/taro-page/index.ux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taro-components-qa/src/components/taro-page/index.ux b/packages/taro-components-qa/src/components/taro-page/index.ux index 8c331494f087..30ab0aacb008 100644 --- a/packages/taro-components-qa/src/components/taro-page/index.ux +++ b/packages/taro-components-qa/src/components/taro-page/index.ux @@ -59,7 +59,7 @@ tabBar: { type: Object, required: false, - default: {} + default: null }, pagePath: { type: String, From 02ff644bed4e5b40ac001fc09c5de4bfaba565f6 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Tue, 16 Apr 2019 22:55:08 +0800 Subject: [PATCH 089/126] =?UTF-8?q?fix(taro-quickapp):=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E4=BA=8B=E4=BB=B6=E4=BC=A0=E5=8F=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-quickapp/src/create-component.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/taro-quickapp/src/create-component.js b/packages/taro-quickapp/src/create-component.js index 9cccbe240f91..80bb8c9d4b05 100644 --- a/packages/taro-quickapp/src/create-component.js +++ b/packages/taro-quickapp/src/create-component.js @@ -74,13 +74,15 @@ function processEvent (eventHandlerName, obj) { let datasetArgs = [] let isScopeBinded = false // 解析从dataset中传过来的参数 - const currentTarget = event.currentTarget const dataset = {} - if (currentTarget._vm) { - const tempalateAttr = currentTarget._vm._externalBinding.template.attr - Object.keys(tempalateAttr).forEach(item => { - if (/^data/.test(item)) { - dataset[item.replace(/^data/, '')] = tempalateAttr[item] + const currentTarget = event.currentTarget + const vm = currentTarget._vm || (currentTarget._target ? currentTarget._target._vm : null) + if (vm) { + const tempalateAttr = vm._externalBinding.template.attr + Object.keys(tempalateAttr).forEach(key => { + if (/^data/.test(key)) { + const item = tempalateAttr[key] + dataset[key.replace(/^data/, '')] = typeof item === 'function' ? item() : item } }) } From 334d440de96ac92197fa45d0ba9e254cbe2b4157 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Tue, 16 Apr 2019 22:55:41 +0800 Subject: [PATCH 090/126] =?UTF-8?q?fix(cli):=20=E5=BF=AB=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E9=9D=99=E6=80=81=E8=B5=84=E6=BA=90=20copy=20=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/mini/helper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taro-cli/src/mini/helper.ts b/packages/taro-cli/src/mini/helper.ts index 0faa7ab46b8b..b894865c2637 100644 --- a/packages/taro-cli/src/mini/helper.ts +++ b/packages/taro-cli/src/mini/helper.ts @@ -316,7 +316,7 @@ export function initCopyFiles () { } export function copyFilesFromSrcToOutput (files: string[]) { - const { nodeModulesPath, npmOutputDir } = BuildData + const { nodeModulesPath, npmOutputDir, outputDir } = BuildData files.forEach(file => { let outputFilePath if (NODE_MODULES_REG.test(file)) { From d0395231339cd1ac100cfbafd69f8337fc7cec2c Mon Sep 17 00:00:00 2001 From: luckyadam Date: Wed, 17 Apr 2019 15:11:07 +0800 Subject: [PATCH 091/126] =?UTF-8?q?fix(components-qa):=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20button=20=E7=BB=84=E4=BB=B6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/{button => taro-button}/img.js | 0 .../components/{button => taro-button}/index.ux | 15 +++++---------- 2 files changed, 5 insertions(+), 10 deletions(-) rename packages/taro-components-qa/src/components/{button => taro-button}/img.js (100%) rename packages/taro-components-qa/src/components/{button => taro-button}/index.ux (90%) diff --git a/packages/taro-components-qa/src/components/button/img.js b/packages/taro-components-qa/src/components/taro-button/img.js similarity index 100% rename from packages/taro-components-qa/src/components/button/img.js rename to packages/taro-components-qa/src/components/taro-button/img.js diff --git a/packages/taro-components-qa/src/components/button/index.ux b/packages/taro-components-qa/src/components/taro-button/index.ux similarity index 90% rename from packages/taro-components-qa/src/components/button/index.ux rename to packages/taro-components-qa/src/components/taro-button/index.ux index 0cf11a7b4ad8..8b8602d36340 100644 --- a/packages/taro-components-qa/src/components/button/index.ux +++ b/packages/taro-components-qa/src/components/taro-button/index.ux @@ -3,17 +3,16 @@ class="{{btnClass}}" style="{{btnStyle}}" id="{{id}}" - onclick="handleClick" disabled="{{disabled}}" > - + From 247a03edca07a9f5212fbd7d1d77e87376f631eb Mon Sep 17 00:00:00 2001 From: yuche Date: Wed, 17 Apr 2019 17:36:11 +0800 Subject: [PATCH 092/126] =?UTF-8?q?feat(transformer):=20=E5=BF=AB=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E6=96=B0=E5=A2=9E=E5=8F=82=E6=95=B0:=20rootProps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/options.ts | 3 ++- packages/taro-transformer-wx/src/render.ts | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/taro-transformer-wx/src/options.ts b/packages/taro-transformer-wx/src/options.ts index b169fccb3567..f3d19e2f1e26 100644 --- a/packages/taro-transformer-wx/src/options.ts +++ b/packages/taro-transformer-wx/src/options.ts @@ -13,7 +13,8 @@ export interface Options { isNormal?: boolean, env?: object, adapter?: Adapters, - jsxAttributeNameReplace?: Object + jsxAttributeNameReplace?: Object, + rootProps?: object } export const transformOptions: Options = {} as any diff --git a/packages/taro-transformer-wx/src/render.ts b/packages/taro-transformer-wx/src/render.ts index 4be0416af2e0..37af0a991bc3 100644 --- a/packages/taro-transformer-wx/src/render.ts +++ b/packages/taro-transformer-wx/src/render.ts @@ -54,7 +54,7 @@ import { FN_PREFIX } from './constant' import { Adapter, Adapters } from './adapter' -import { buildBabelTransformOptions } from './options' +import { transformOptions, buildBabelTransformOptions } from './options' import generate from 'babel-generator' import { LoopRef } from './interface' const template = require('babel-template') @@ -1909,6 +1909,20 @@ export class RenderParser { } setOutputTemplate () { + if (Adapter.type === Adapters.quickapp && transformOptions.rootProps && transformOptions.isRoot) { + const attrs: t.JSXAttribute[] = [] + for (const key in transformOptions.rootProps) { + if (transformOptions.rootProps.hasOwnProperty(key)) { + const value = transformOptions.rootProps[key] + const keyName = key + '__temp' + const decl = buildConstVariableDeclaration(keyName, t.identifier(JSON.stringify(value))) + this.referencedIdentifiers.add(t.identifier(keyName)) + this.renderPath.node.body.body.push(decl) + attrs.push(t.jSXAttribute(t.jSXIdentifier(key), t.jSXExpressionContainer(t.identifier(keyName)))) + } + } + this.finalReturnElement.openingElement.attributes.push(...attrs) + } this.outputTemplate = parseJSXElement(this.finalReturnElement, true) if (!this.isDefaultRender) { this.outputTemplate = `` From b159cf2c549c6def5d57d0606ddecf8dfac0b90a Mon Sep 17 00:00:00 2001 From: yuche Date: Wed, 17 Apr 2019 17:51:01 +0800 Subject: [PATCH 093/126] =?UTF-8?q?fix(transformer):=20=E5=BF=AB=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E7=94=9F=E6=88=90=E5=87=BD=E6=95=B0=E5=8C=BF=E5=90=8D?= =?UTF-8?q?=20state=20=E4=B9=9F=E4=B8=8D=E8=83=BD=E4=BB=A5=20=5F$=20?= =?UTF-8?q?=E5=BC=80=E5=A4=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-transformer-wx/src/utils.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/taro-transformer-wx/src/utils.ts b/packages/taro-transformer-wx/src/utils.ts index 787297babcb2..8fef046efa3b 100644 --- a/packages/taro-transformer-wx/src/utils.ts +++ b/packages/taro-transformer-wx/src/utils.ts @@ -7,7 +7,7 @@ import { cloneDeep } from 'lodash' import * as fs from 'fs' import * as path from 'path' import { buildBlockElement } from './jsx' -import { Adapter } from './adapter' +import { Adapter, Adapters } from './adapter' import { transformOptions } from './options' const template = require('babel-template') @@ -236,6 +236,11 @@ export function generateAnonymousState ( } }) variableName = newId.name + if (Adapter.type === Adapters.quickapp && variableName.startsWith('_$')) { + const newVarName = variableName.slice(2) + scope.rename(variableName, newVarName) + variableName = newVarName + } refIds.add(t.identifier(variableName)) blockStatement.scope.rename(id.name, newId.name) path.parentPath.replaceWith( From 2e818546cbf3a8a14e1d266c4b8207a347ba913b Mon Sep 17 00:00:00 2001 From: chenjiajian <798095202@qq.com> Date: Wed, 17 Apr 2019 17:56:32 +0800 Subject: [PATCH 094/126] =?UTF-8?q?feat(taro-qq):=20=E5=A2=9E=E5=8A=A0=20Q?= =?UTF-8?q?Q=20=E8=BD=BB=E5=BA=94=E7=94=A8=E7=AB=AF=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/bin/taro-build | 2 +- packages/taro-cli/src/build.ts | 10 + packages/taro-cli/src/mini/astProcess.ts | 2 +- packages/taro-cli/src/mini/index.ts | 2 +- packages/taro-cli/src/plugin.ts | 4 +- packages/taro-cli/src/util/constants.ts | 30 +- packages/taro-qq/README.md | 2 + packages/taro-qq/index.js | 2 + packages/taro-qq/package.json | 32 ++ packages/taro-qq/rollup.config.js | 74 ++++ packages/taro-qq/src/component.js | 134 ++++++ packages/taro-qq/src/create-app.js | 45 ++ packages/taro-qq/src/create-component.js | 428 ++++++++++++++++++++ packages/taro-qq/src/current-owner.js | 4 + packages/taro-qq/src/data-cache.js | 15 + packages/taro-qq/src/hooks.js | 166 ++++++++ packages/taro-qq/src/index.js | 44 ++ packages/taro-qq/src/lifecycle.js | 150 +++++++ packages/taro-qq/src/native-api.js | 205 ++++++++++ packages/taro-qq/src/next-tick.js | 7 + packages/taro-qq/src/pure-component.js | 13 + packages/taro-qq/src/render-queue.js | 23 ++ packages/taro-qq/src/util.js | 260 ++++++++++++ packages/taro-transformer-wx/src/adapter.ts | 17 +- packages/taro/src/env.js | 6 +- 25 files changed, 1665 insertions(+), 12 deletions(-) create mode 100644 packages/taro-qq/README.md create mode 100644 packages/taro-qq/index.js create mode 100644 packages/taro-qq/package.json create mode 100644 packages/taro-qq/rollup.config.js create mode 100644 packages/taro-qq/src/component.js create mode 100644 packages/taro-qq/src/create-app.js create mode 100644 packages/taro-qq/src/create-component.js create mode 100644 packages/taro-qq/src/current-owner.js create mode 100644 packages/taro-qq/src/data-cache.js create mode 100644 packages/taro-qq/src/hooks.js create mode 100644 packages/taro-qq/src/index.js create mode 100644 packages/taro-qq/src/lifecycle.js create mode 100644 packages/taro-qq/src/native-api.js create mode 100644 packages/taro-qq/src/next-tick.js create mode 100644 packages/taro-qq/src/pure-component.js create mode 100644 packages/taro-qq/src/render-queue.js create mode 100644 packages/taro-qq/src/util.js diff --git a/packages/taro-cli/bin/taro-build b/packages/taro-cli/bin/taro-build index 645bd285b7fc..396094265c9a 100755 --- a/packages/taro-cli/bin/taro-build +++ b/packages/taro-cli/bin/taro-build @@ -10,7 +10,7 @@ const { PROJECT_CONFIG, BUILD_TYPES } = require('../dist/util/constants') const projectConfPath = path.join(process.cwd(), PROJECT_CONFIG) program - .option('--type [typeName]', 'Build type, weapp/swan/alipay/tt/h5/quickapp/rn') + .option('--type [typeName]', 'Build type, weapp/swan/alipay/tt/h5/quickapp/rn/qq') .option('--watch', 'Watch mode') .option('--env [env]', 'Env type') .option('--ui', 'Build Taro UI library') diff --git a/packages/taro-cli/src/build.ts b/packages/taro-cli/src/build.ts index 1c6efbc7d4df..3edbf5406787 100644 --- a/packages/taro-cli/src/build.ts +++ b/packages/taro-cli/src/build.ts @@ -41,6 +41,9 @@ export default function build (args, buildConfig: IBuildConfig) { case BUILD_TYPES.QUICKAPP: buildForQuickApp({ watch, port }) break + case BUILD_TYPES.QQ: + buildForQQ({ watch }) + break case BUILD_TYPES.UI: buildForUILibrary({ watch }) break @@ -99,6 +102,13 @@ function buildForQuickApp ({ watch, port }: IBuildConfig) { }) } +function buildForQQ ({ watch }: IBuildConfig) { + require('./mini').build({ + watch, + adapter: BUILD_TYPES.QQ + }) +} + function buildForUILibrary ({ watch }: IBuildConfig) { require('./ui').build({ watch }) } diff --git a/packages/taro-cli/src/mini/astProcess.ts b/packages/taro-cli/src/mini/astProcess.ts index b1b9af423244..a82a50e580d6 100644 --- a/packages/taro-cli/src/mini/astProcess.ts +++ b/packages/taro-cli/src/mini/astProcess.ts @@ -867,7 +867,7 @@ export function parseAst ( node.body.push(template(`Taro.initPxTransform(${JSON.stringify(pxTransformConfig)})`, babylonConfig as any)() as any) break case PARSE_AST_TYPE.PAGE: - if (buildAdapter === BUILD_TYPES.WEAPP) { + if (buildAdapter === BUILD_TYPES.WEAPP || buildAdapter === BUILD_TYPES.QQ) { node.body.push(template(`Component(require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}, true))`, babylonConfig as any)() as any) } else if (isQuickApp) { node.body.push(template(`export default require('${taroMiniAppFrameworkPath}').default.createComponent(${exportVariableName}, true)`, babylonConfig as any)() as any) diff --git a/packages/taro-cli/src/mini/index.ts b/packages/taro-cli/src/mini/index.ts index b32f67f71522..33b2e29b9560 100644 --- a/packages/taro-cli/src/mini/index.ts +++ b/packages/taro-cli/src/mini/index.ts @@ -36,7 +36,7 @@ const appPath = process.cwd() function buildProjectConfig () { const { buildAdapter, sourceDir, outputDir, outputDirName } = getBuildData() let projectConfigFileName = `project.${buildAdapter}.json` - if (buildAdapter === BUILD_TYPES.WEAPP) { + if (buildAdapter === BUILD_TYPES.WEAPP || buildAdapter === BUILD_TYPES.QQ) { projectConfigFileName = 'project.config.json' } let projectConfigPath = path.join(appPath, projectConfigFileName) diff --git a/packages/taro-cli/src/plugin.ts b/packages/taro-cli/src/plugin.ts index 9fb751fec97a..6bac86a9349c 100644 --- a/packages/taro-cli/src/plugin.ts +++ b/packages/taro-cli/src/plugin.ts @@ -14,13 +14,13 @@ import { REG_IMAGE, REG_MEDIA, REG_TYPESCRIPT, - processTypeEnum + processTypeEnum, + isWindows } from './util/constants' import { buildEntry } from './mini/entry' import { buildPages, buildSinglePage } from './mini/page' import { build as buildWeapp } from './mini' -import { isWindows } from './mini/constants' import { getRealComponentsPathList, isFileToBePage, diff --git a/packages/taro-cli/src/util/constants.ts b/packages/taro-cli/src/util/constants.ts index 749b72991c82..558447fd2d44 100644 --- a/packages/taro-cli/src/util/constants.ts +++ b/packages/taro-cli/src/util/constants.ts @@ -99,7 +99,8 @@ export const enum BUILD_TYPES { TT ='tt', UI ='ui', PLUGIN = 'plugin', - QUICKAPP = 'quickapp' + QUICKAPP = 'quickapp', + QQ = 'qq' } export const enum TEMPLATE_TYPES { @@ -107,7 +108,8 @@ export const enum TEMPLATE_TYPES { SWAN = '.swan', ALIPAY = '.axml', TT = '.ttml', - QUICKAPP = '.ux' + QUICKAPP = '.ux', + QQ = '.qml' } export const enum STYLE_TYPES { @@ -115,7 +117,8 @@ export const enum STYLE_TYPES { SWAN = '.css', ALIPAY = '.acss', TT = '.ttss', - QUICKAPP = '.css' + QUICKAPP = '.css', + QQ = '.qss' } export const enum SCRIPT_TYPES { @@ -123,7 +126,8 @@ export const enum SCRIPT_TYPES { SWAN = '.js', ALIPAY = '.js', TT = '.js', - QUICKAPP = '.js' + QUICKAPP = '.js', + QQ = '.js' } export const enum CONFIG_TYPES { @@ -131,7 +135,8 @@ export const enum CONFIG_TYPES { SWAN = '.json', ALIPAY = '.json', TT = '.json', - QUICKAPP = '.json' + QUICKAPP = '.json', + QQ = '.json' } export type IMINI_APP_FILE_TYPE = { @@ -174,6 +179,12 @@ export const MINI_APP_FILES: IMINI_APP_FILES = { STYLE: STYLE_TYPES.QUICKAPP, SCRIPT: SCRIPT_TYPES.QUICKAPP, CONFIG: CONFIG_TYPES.QUICKAPP + }, + [BUILD_TYPES.QQ]: { + TEMPL: TEMPLATE_TYPES.QQ, + STYLE: STYLE_TYPES.QQ, + SCRIPT: SCRIPT_TYPES.QQ, + CONFIG: CONFIG_TYPES.QQ } } @@ -233,6 +244,15 @@ export const CONFIG_MAP = { backgroundColorBottom: false, backgroundColorTop: false, navigationStyle: false + }, + [BUILD_TYPES.QQ]: { + navigationBarTitleText: 'navigationBarTitleText', + navigationBarBackgroundColor: 'navigationBarBackgroundColor', + enablePullDownRefresh: 'enablePullDownRefresh', + list: 'list', + text: 'text', + iconPath: 'iconPath', + selectedIconPath: 'selectedIconPath' } } diff --git a/packages/taro-qq/README.md b/packages/taro-qq/README.md new file mode 100644 index 000000000000..952b4e516eea --- /dev/null +++ b/packages/taro-qq/README.md @@ -0,0 +1,2 @@ +# @tarojs/taro-qq +多端解决方案QQ轻应用端基础框架 diff --git a/packages/taro-qq/index.js b/packages/taro-qq/index.js new file mode 100644 index 000000000000..437a6d4788f4 --- /dev/null +++ b/packages/taro-qq/index.js @@ -0,0 +1,2 @@ +module.exports = require('./dist/index.js').default +module.exports.default = module.exports diff --git a/packages/taro-qq/package.json b/packages/taro-qq/package.json new file mode 100644 index 000000000000..094d4dd96917 --- /dev/null +++ b/packages/taro-qq/package.json @@ -0,0 +1,32 @@ +{ + "name": "@tarojs/taro-qq", + "version": "1.2.13", + "description": "Taro qq framework", + "main": "index.js", + "files": [ + "dist", + "src", + "index.js", + "package.json" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "rollup -c rollup.config.js", + "watch": "rollup -c rollup.config.js -w" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/NervJS/taro.git" + }, + "keywords": [ + "taro" + ], + "author": "O2Team", + "license": "MIT", + "dependencies": { + "@tarojs/taro": "1.2.13", + "@tarojs/utils": "1.2.13", + "lodash": "^4.17.10", + "prop-types": "^15.6.1" + } +} diff --git a/packages/taro-qq/rollup.config.js b/packages/taro-qq/rollup.config.js new file mode 100644 index 000000000000..4af44972956b --- /dev/null +++ b/packages/taro-qq/rollup.config.js @@ -0,0 +1,74 @@ +const { join } = require('path') +const resolve = require('rollup-plugin-node-resolve') +const babel = require('rollup-plugin-babel') +const common = require('rollup-plugin-commonjs') +const alias = require('rollup-plugin-alias') +const cwd = __dirname + +const baseConfig = { + input: join(cwd, 'src/index.js'), + external: ['nervjs'], + output: [ + { + file: join(cwd, 'dist/index.js'), + format: 'cjs', + sourcemap: true, + exports: 'named' + }, + { + file: join(cwd, 'dist/taro-weapp.js'), + format: 'umd', + name: 'TaroWeapp', + sourcemap: true, + exports: 'named' + } + ], + plugins: [ + alias({ + '@tarojs/taro': join(cwd, '../taro/src/index'), + '@tarojs/utils': join(cwd, '../taro-utils/dist/index') + }), + resolve({ + preferBuiltins: false + }), + + common({ + include: 'node_modules/**' + }), + babel({ + babelrc: false, + presets: [ + ['@babel/preset-env', { + modules: false + }] + ], + plugins: [ + '@babel/plugin-proposal-class-properties', + '@babel/plugin-proposal-object-rest-spread', + ['@babel/plugin-transform-react-jsx', { + 'pragma': 'Nerv.createElement' + }] + ] + }) + ] +} +const esmConfig = Object.assign({}, baseConfig, { + output: Object.assign({}, baseConfig.output, { + sourcemap: true, + format: 'es', + file: join(cwd, 'dist/index.esm.js') + }) +}) + +function rollup () { + const target = process.env.TARGET + + if (target === 'umd') { + return baseConfig + } else if (target === 'esm') { + return esmConfig + } else { + return [baseConfig, esmConfig] + } +} +module.exports = rollup() diff --git a/packages/taro-qq/src/component.js b/packages/taro-qq/src/component.js new file mode 100644 index 000000000000..bb18d600792d --- /dev/null +++ b/packages/taro-qq/src/component.js @@ -0,0 +1,134 @@ +import { enqueueRender } from './render-queue' +import { updateComponent } from './lifecycle' +import { isFunction } from './util' +import { + internal_safe_get as safeGet +} from '@tarojs/taro' +import { cacheDataSet, cacheDataGet } from './data-cache' +// #组件state对应小程序组件data +// #私有的__componentProps更新用于触发子组件中对应obsever,生命周期componentWillReceiveProps,componentShouldUpdate在这里处理 +// #父组件传过来的props放到data.__props中供模板使用,这么做的目的是模拟receiveProps生命周期 +// 执行顺序:组件setState -> 组件_createData() -> 对应的小程序组件setData(组件更新)-> 子组件的__componentProps.observer执行 +// -> 触发子组件componentWillReceiveProps,更新子组件props,componentShouldUpdate -> 子组件_createData -> 子组件setData + +const PRELOAD_DATA_KEY = 'preload' + +class BaseComponent { + // _createData的时候生成,小程序中通过data.__createData访问 + __computed = {} + // this.props,小程序中通过data.__props访问 + __props = {} + __isReady = false + // 会在componentDidMount后置为true + __mounted = false + nextProps = {} + _dirty = true + _disable = true + _isForceUpdate = false + _pendingStates = [] + _pendingCallbacks = [] + $componentType = '' + $router = { + params: {}, + path: '' + } + + _afterScheduleEffect = false + _disableEffect = false + hooks = [] + effects = [] + layoutEffects = [] + + constructor (props = {}, isPage) { + this.state = {} + this.props = props + this.$componentType = isPage ? 'PAGE' : 'COMPONENT' + this.isTaroComponent = this.$componentType && this.$router && this._pendingStates + } + _constructor (props) { + this.props = props || {} + } + _init (scope) { + this.$scope = scope + } + setState (state, callback) { + if (state) { + (this._pendingStates = this._pendingStates || []).push(state) + } + if (isFunction(callback)) { + (this._pendingCallbacks = this._pendingCallbacks || []).push(callback) + } + if (!this._disable) { + enqueueRender(this) + } + } + + getState () { + const { _pendingStates, state, props } = this + const stateClone = Object.assign({}, state) + delete stateClone.__data + if (!_pendingStates.length) { + return stateClone + } + const queue = _pendingStates.concat() + this._pendingStates.length = 0 + queue.forEach((nextState) => { + if (isFunction(nextState)) { + nextState = nextState.call(this, stateClone, props) + } + Object.assign(stateClone, nextState) + }) + return stateClone + } + + forceUpdate (callback) { + if (isFunction(callback)) { + (this._pendingCallbacks = this._pendingCallbacks || []).push(callback) + } + this._isForceUpdate = true + updateComponent(this) + } + + $preload (key, value) { + const preloadData = cacheDataGet(PRELOAD_DATA_KEY) || {} + if (typeof key === 'object') { + for (const k in key) { + preloadData[k] = key[k] + } + } else { + preloadData[key] = value + } + cacheDataSet(PRELOAD_DATA_KEY, preloadData) + } + + // 会被匿名函数调用 + __triggerPropsFn (key, args) { + const keyChain = key.split('.') + const reduxFnPrefix = '__event_' + const reduxFnName = reduxFnPrefix + keyChain.shift() + // redux标识过的方法,直接调用 + if (reduxFnName in this) { + const scope = args.shift() + let fn + if (keyChain.length > 0) { + fn = safeGet(this[reduxFnName], keyChain.join('.')) + } else { + fn = this[reduxFnName] + } + fn.apply(scope, args) + } else { + // 普通的 + const keyLower = key.toLocaleLowerCase() + const detail = { + __isCustomEvt: true, + __arguments: args + } + if (args.length > 0) { + detail.value = args.slice(1) + } + this.$scope.triggerEvent(keyLower, detail) + } + } +} + +export default BaseComponent diff --git a/packages/taro-qq/src/create-app.js b/packages/taro-qq/src/create-app.js new file mode 100644 index 000000000000..0d640702c892 --- /dev/null +++ b/packages/taro-qq/src/create-app.js @@ -0,0 +1,45 @@ +function createApp (AppClass) { + const app = new AppClass() + const weappAppConf = { + onLaunch (options) { + app.$app = this + app.$app.$router = app.$router = { + params: options + } + if (app.componentWillMount) { + app.componentWillMount() + } + if (app.componentDidMount) { + app.componentDidMount() + } + }, + + onShow (options) { + Object.assign(app.$router.params, options) + if (app.componentDidShow) { + app.componentDidShow() + } + }, + + onHide () { + if (app.componentDidHide) { + app.componentDidHide() + } + }, + + onError (err) { + if (app.componentDidCatchError) { + app.componentDidCatchError(err) + } + }, + + onPageNotFound (obj) { + if (app.componentDidNotFound) { + app.componentDidNotFound(obj) + } + } + } + return Object.assign(weappAppConf, app) +} + +export default createApp diff --git a/packages/taro-qq/src/create-component.js b/packages/taro-qq/src/create-component.js new file mode 100644 index 000000000000..c6b4b2dd674b --- /dev/null +++ b/packages/taro-qq/src/create-component.js @@ -0,0 +1,428 @@ +import { getCurrentPageUrl } from '@tarojs/utils' + +import { isEmptyObject, noop, isFunction } from './util' +import { updateComponent } from './lifecycle' +import { cacheDataSet, cacheDataGet, cacheDataHas } from './data-cache' +import { Current } from './current-owner'; + +const privatePropValName = '__triggerObserer' +const anonymousFnNamePreffix = 'funPrivate' +const componentFnReg = /^__fn_/ +const routerParamsPrivateKey = '__key_' +const preloadPrivateKey = '__preload_' +const PRELOAD_DATA_KEY = 'preload' +const preloadInitedComponent = '$preloadComponent' +const pageExtraFns = ['onPullDownRefresh', 'onReachBottom', 'onShareAppMessage', 'onPageScroll', 'onTabItemTap', 'onResize'] + +function bindProperties (weappComponentConf, ComponentClass, isPage) { + weappComponentConf.properties = ComponentClass.properties || {} + const defaultProps = ComponentClass.defaultProps || {} + for (const key in defaultProps) { + if (defaultProps.hasOwnProperty(key)) { + weappComponentConf.properties[key] = { + type: null, + value: null + } + } + } + if (isPage) { + weappComponentConf.properties[routerParamsPrivateKey] = { + type: null, + value: null + } + weappComponentConf.properties[preloadPrivateKey] = { + type: null, + value: null + } + const defaultParams = ComponentClass.defaultParams || {} + for (const key in defaultParams) { + if (defaultParams.hasOwnProperty(key)) { + weappComponentConf.properties[key] = { + type: null, + value: null + } + } + } + } + // 拦截props的更新,插入生命周期 + // 调用小程序setData或会造成性能消耗 + weappComponentConf.properties[privatePropValName] = { + type: null, + observer: function () { + if (!this.$component || !this.$component.__isReady) return + const nextProps = filterProps(ComponentClass.properties, ComponentClass.defaultProps, this.$component.props, this.data) + this.$component.props = nextProps + this.$component._unsafeCallUpdate = true + updateComponent(this.$component) + this.$component._unsafeCallUpdate = false + } + } +} + +function bindBehaviors (weappComponentConf, ComponentClass) { + if (ComponentClass.behaviors) { + weappComponentConf.behaviors = ComponentClass.behaviors + } +} + +function bindStaticOptions (weappComponentConf, ComponentClass) { + if (ComponentClass.options) { + weappComponentConf.options = ComponentClass.options + } +} + +function bindMultipleSlots (weappComponentConf, ComponentClass) { + const multipleSlots = ComponentClass.multipleSlots + if (!multipleSlots) { + return + } + weappComponentConf.options = { + ...weappComponentConf.options, + ...{ multipleSlots } + } +} + +function bindStaticFns (weappComponentConf, ComponentClass) { + for (const key in ComponentClass) { + typeof ComponentClass[key] === 'function' && (weappComponentConf[key] = ComponentClass[key]) + } + // 低版本 IOS 下部分属性不能直接访问 + Object.getOwnPropertyNames(ComponentClass).forEach(key => { + const excludes = ['arguments', 'caller', 'length', 'name', 'prototype'] + if (excludes.indexOf(key) < 0) { + typeof ComponentClass[key] === 'function' && (weappComponentConf[key] = ComponentClass[key]) + } + }) +} + +function processEvent (eventHandlerName, obj) { + if (obj[eventHandlerName]) return + + obj[eventHandlerName] = function (event) { + if (event) { + event.preventDefault = function () {} + event.stopPropagation = function () {} + event.currentTarget = event.currentTarget || event.target || {} + if (event.target) { + Object.assign(event.target, event.detail) + } + Object.assign(event.currentTarget, event.detail) + } + + const scope = this.$component + let callScope = scope + const isAnonymousFn = eventHandlerName.indexOf(anonymousFnNamePreffix) > -1 + let realArgs = [] + let detailArgs = [] + let datasetArgs = [] + let isScopeBinded = false + // 解析从dataset中传过来的参数 + const dataset = event.currentTarget.dataset || {} + const bindArgs = {} + const eventType = event.type.toLocaleLowerCase() + Object.keys(dataset).forEach(key => { + let keyLower = key.toLocaleLowerCase() + if (/^e/.test(keyLower)) { + // 小程序属性里中划线后跟一个下划线会解析成不同的结果 + keyLower = keyLower.replace(/^e/, '') + if (keyLower.indexOf(eventType) >= 0) { + const argName = keyLower.replace(eventType, '') + if (/^(a[a-z]|so)$/.test(argName)) { + bindArgs[argName] = dataset[key] + } + } + } + }) + // 如果是通过triggerEvent触发,并且带有参数 + if (event.detail && event.detail.__arguments && event.detail.__arguments.length > 0) { + detailArgs = event.detail.__arguments + } + // 普通的事件(非匿名函数),会直接call + if (!isAnonymousFn) { + if ('so' in bindArgs) { + if (bindArgs['so'] !== 'this') { + callScope = bindArgs['so'] + } + isScopeBinded = true + delete bindArgs['so'] + } + if (detailArgs.length > 0) { + !isScopeBinded && detailArgs[0] && (callScope = detailArgs[0]) + detailArgs.shift() + } + if (!isEmptyObject(bindArgs)) { + datasetArgs = Object.keys(bindArgs) + .sort() + .map(key => bindArgs[key]) + } + realArgs = [...datasetArgs, ...detailArgs, event] + } else { + // 匿名函数,会将scope作为第一个参数 + let _scope = null + if ('so' in bindArgs) { + if (bindArgs['so'] !== 'this') { + _scope = bindArgs['so'] + } + isScopeBinded = true + delete bindArgs['so'] + } + if (detailArgs.length > 0) { + !isScopeBinded && detailArgs[0] && (callScope = detailArgs[0]) + detailArgs.shift() + } + if (!isEmptyObject(bindArgs)) { + datasetArgs = Object.keys(bindArgs) + .sort() + .map(key => bindArgs[key]) + } + realArgs = [_scope, ...datasetArgs, ...detailArgs, event] + } + return scope[eventHandlerName].apply(callScope, realArgs) + } +} + +function bindEvents (weappComponentConf, events, isPage) { + weappComponentConf.methods = weappComponentConf.methods || {} + const target = weappComponentConf.methods + events.forEach(name => { + processEvent(name, target) + }) +} + +function filterProps (properties, defaultProps = {}, componentProps = {}, weappComponentData) { + let newProps = Object.assign({}, componentProps) + for (const propName in properties) { + if (propName === privatePropValName) { + continue + } + if (typeof componentProps[propName] === 'function') { + newProps[propName] = componentProps[propName] + } else if (propName in weappComponentData) { + newProps[propName] = weappComponentData[propName] + } + if (componentFnReg.test(propName)) { + if (weappComponentData[propName] === true) { + const fnName = propName.replace(componentFnReg, '') + newProps[fnName] = noop + } + delete newProps[propName] + } + } + if (!isEmptyObject(defaultProps)) { + for (const propName in defaultProps) { + if (newProps[propName] === undefined || newProps[propName] === null) { + newProps[propName] = defaultProps[propName] + } + } + } + return newProps +} + +function filterParams (data, defaultParams = {}) { + let res = {} + for (const paramName in defaultParams) { + res[paramName] = paramName in data ? data[paramName] : defaultParams[paramName] + } + return res +} + +export function componentTrigger (component, key, args) { + args = args || [] + + if (key === 'componentDidMount') { + if (component['$$refs'] && component['$$refs'].length > 0) { + let refs = {} + component['$$refs'].forEach(ref => { + let target + if (ref.type === 'component') { + target = component.$scope.selectComponent(`#${ref.id}`) + target = target ? (target.$component || target) : null + } else { + const query = qq.createSelectorQuery().in(component.$scope) + target = query.select(`#${ref.id}`) + } + if ('refName' in ref && ref['refName']) { + refs[ref.refName] = target + } else if ('fn' in ref && typeof ref['fn'] === 'function') { + ref['fn'].call(component, target) + } + ref.target = target + }) + component.refs = Object.assign({}, component.refs || {}, refs) + } + } + + component[key] && typeof component[key] === 'function' && component[key].call(component, ...args) + if (key === 'componentWillMount') { + component._dirty = false + component._disable = false + component.state = component.getState() + } + if (key === 'componentWillUnmount') { + component._dirty = true + component._disable = true + component.$router = { + params: {}, + path: '' + } + component._pendingStates = [] + component._pendingCallbacks = [] + // refs + if (component['$$refs'] && component['$$refs'].length > 0) { + component['$$refs'].forEach(ref => typeof ref['fn'] === 'function' && ref['fn'].call(component, null)) + component.refs = {} + } + } +} + +function initComponent (ComponentClass, isPage) { + if (this.$component.__isReady) return + // ready之后才可以setData, + // ready之前,小程序组件初始化时仍然会触发observer,__isReady为否的时候放弃处理observer + this.$component.__isReady = true + // 页面Ready的时候setData更新,此时并未didMount,触发observer但不会触发子组件更新 + // 小程序组件ready,但是数据并没有ready,需要通过updateComponent来初始化数据,setData完成之后才是真正意义上的组件ready + // 动态组件执行改造函数副本的时,在初始化数据前计算好props + if (!isPage) { + const nextProps = filterProps(ComponentClass.properties, ComponentClass.defaultProps, this.$component.props, this.data) + this.$component.props = nextProps + } else { + this.$component.$router.path = getCurrentPageUrl() + } + updateComponent(this.$component) +} + +function createComponent (ComponentClass, isPage) { + let initData = { + _componentProps: 1 + } + const componentProps = filterProps({}, ComponentClass.defaultProps) + const componentInstance = new ComponentClass(componentProps) + componentInstance._constructor && componentInstance._constructor(componentProps) + try { + Current.current = componentInstance + Current.index = 0 + componentInstance.state = componentInstance._createData() || componentInstance.state + } catch (err) { + if (isPage) { + console.warn(`[Taro warn] 请给页面提供初始 \`state\` 以提高初次渲染性能!`) + } else { + console.warn(`[Taro warn] 请给组件提供一个 \`defaultProps\` 以提高初次渲染性能!`) + } + console.warn(err) + } + initData = Object.assign({}, initData, componentInstance.props, componentInstance.state) + + const weappComponentConf = { + data: initData, + created (options = {}) { + if (isPage && cacheDataHas(preloadInitedComponent)) { + this.$component = cacheDataGet(preloadInitedComponent, true) + } else { + this.$component = new ComponentClass({}, isPage) + } + this.$component._init(this) + this.$component.render = this.$component._createData + this.$component.__propTypes = ComponentClass.propTypes + Object.assign(this.$component.$router.params, options) + }, + attached () { + let hasParamsCache + if (isPage) { + // params + let params = {} + hasParamsCache = cacheDataHas(this.data[routerParamsPrivateKey]) + if (hasParamsCache) { + params = Object.assign({}, ComponentClass.defaultParams, cacheDataGet(this.data[routerParamsPrivateKey], true)) + } else { + // 直接启动,非内部跳转 + params = filterParams(this.data, ComponentClass.defaultParams) + } + if (cacheDataHas(PRELOAD_DATA_KEY)) { + const data = cacheDataGet(PRELOAD_DATA_KEY, true) + this.$component.$router.preload = data + } + Object.assign(this.$component.$router.params, params) + // preload + if (cacheDataHas(this.data[preloadPrivateKey])) { + this.$component.$preloadData = cacheDataGet(this.data[preloadPrivateKey], true) + } else { + this.$component.$preloadData = null + } + } + if (!isPage || hasParamsCache || ComponentClass.defaultParams) { + initComponent.apply(this, [ComponentClass, isPage]) + } + }, + ready () { + if (!isPage && !this.$component.__mounted) { + this.$component.__mounted = true + componentTrigger(this.$component, 'componentDidMount') + } + }, + detached () { + const component = this.$component + componentTrigger(component, 'componentWillUnmount') + component.hooks.forEach((hook) => { + if (isFunction(hook.cleanup)) { + hook.cleanup() + } + }) + } + } + if (isPage) { + weappComponentConf.methods = weappComponentConf.methods || {} + weappComponentConf.methods['onLoad'] = function (options = {}) { + if (this.$component.__isReady) return + Object.assign(this.$component.$router.params, options) + initComponent.apply(this, [ComponentClass, isPage]) + } + weappComponentConf.methods['onReady'] = function () { + this.$component.__mounted = true + componentTrigger(this.$component, 'componentDidMount') + } + weappComponentConf.methods['onShow'] = function () { + componentTrigger(this.$component, 'componentDidShow') + } + weappComponentConf.methods['onHide'] = function () { + componentTrigger(this.$component, 'componentDidHide') + } + pageExtraFns.forEach(fn => { + if (componentInstance[fn] && typeof componentInstance[fn] === 'function') { + weappComponentConf.methods[fn] = function () { + const component = this.$component + if (component[fn] && typeof component[fn] === 'function') { + return component[fn].call(component, ...arguments) + } + } + } + }) + __wxRoute && cacheDataSet(__wxRoute, ComponentClass) + } else { + weappComponentConf.pageLifetimes = weappComponentConf.pageLifetimes || {} + + weappComponentConf.pageLifetimes['show'] = function () { + componentTrigger(this.$component, 'componentDidShow') + } + + weappComponentConf.pageLifetimes['hide'] = function () { + componentTrigger(this.$component, 'componentDidHide') + } + + weappComponentConf.pageLifetimes['resize'] = function () { + componentTrigger(this.$component, 'onResize') + } + } + bindProperties(weappComponentConf, ComponentClass, isPage) + bindBehaviors(weappComponentConf, ComponentClass) + bindStaticFns(weappComponentConf, ComponentClass) + bindStaticOptions(weappComponentConf, ComponentClass) + bindMultipleSlots(weappComponentConf, ComponentClass) + ComponentClass['$$events'] && bindEvents(weappComponentConf, ComponentClass['$$events'], isPage) + if (ComponentClass['externalClasses'] && ComponentClass['externalClasses'].length) { + weappComponentConf['externalClasses'] = ComponentClass['externalClasses'] + } + return weappComponentConf +} + +export default createComponent diff --git a/packages/taro-qq/src/current-owner.js b/packages/taro-qq/src/current-owner.js new file mode 100644 index 000000000000..dfaf7aa3d1dc --- /dev/null +++ b/packages/taro-qq/src/current-owner.js @@ -0,0 +1,4 @@ +export const Current = { + current: null, + index: 0 +} diff --git a/packages/taro-qq/src/data-cache.js b/packages/taro-qq/src/data-cache.js new file mode 100644 index 000000000000..f11a760035da --- /dev/null +++ b/packages/taro-qq/src/data-cache.js @@ -0,0 +1,15 @@ +const data = {} + +export function cacheDataSet (key, val) { + data[key] = val +} + +export function cacheDataGet (key, delelteAfterGet) { + const temp = data[key] + delelteAfterGet && delete data[key] + return temp +} + +export function cacheDataHas (key) { + return key in data +} diff --git a/packages/taro-qq/src/hooks.js b/packages/taro-qq/src/hooks.js new file mode 100644 index 000000000000..6b1d00e6e2e5 --- /dev/null +++ b/packages/taro-qq/src/hooks.js @@ -0,0 +1,166 @@ +import { isFunction, isUndefined, isArray, isNullOrUndef } from './util' +import { Current } from './current-owner' +import nextTick from './next-tick' + +function getHooks (index) { + if (Current.current === null) { + throw new Error(`invalid hooks call: hooks can only be called in a stateless component.`) + } + const hooks = Current.current.hooks + if (index >= hooks.length) { + hooks.push({}) + } + return hooks[index] +} + +export function useState (initialState) { + if (isFunction(initialState)) { + initialState = initialState() + } + const hook = getHooks(Current.index++) + if (!hook.state) { + hook.component = Current.current + hook.state = [ + initialState, + (action) => { + hook.state[0] = isFunction(action) ? action(hook.state[0]) : action + hook.component._disable = false + hook.component.setState({}) + } + ] + } + return hook.state +} + +export function useReducer ( + reducer, + initialState, + initializer +) { + if (isFunction(initialState)) { + initialState = initialState() + } + const hook = getHooks(Current.index++) + if (!hook.state) { + hook.component = Current.current + hook.state = [ + isUndefined(initializer) ? initialState : initializer(initialState), + (action) => { + hook.state[0] = reducer(hook.state[0], action) + hook.component._disable = false + hook.component.setState({}) + } + ] + } + return hook.state +} + +function areDepsChanged (prevDeps, deps) { + if (isNullOrUndef(prevDeps) || isNullOrUndef(deps)) { + return true + } + return deps.some((a, i) => a !== prevDeps[i]) +} + +export function invokeEffects (component, delay) { + const effects = delay ? component.effects : component.layoutEffects + effects.forEach((hook) => { + if (isFunction(hook.cleanup)) { + hook.cleanup() + } + const result = hook.effect() + if (isFunction(result)) { + hook.cleanup = result + } + }) + + if (delay) { + component.effects = [] + } else { + component.layoutEffects = [] + } +} + +let scheduleEffectComponents = [] + +function invokeScheduleEffects (component) { + if (!component._afterScheduleEffect) { + component._afterScheduleEffect = true + scheduleEffectComponents.push(component) + if (scheduleEffectComponents.length === 1) { + nextTick(() => { + setTimeout(() => { + scheduleEffectComponents.forEach((c) => { + c._afterScheduleEffect = false + invokeEffects(c, true) + }) + scheduleEffectComponents = [] + }, 0) + }) + } + } +} + +function useEffectImpl (effect, deps, delay) { + const hook = getHooks(Current.index++) + if (Current.current._disableHooks || !Current.current.__isReady) { + return + } + if (areDepsChanged(hook.deps, deps)) { + hook.effect = effect + hook.deps = deps + + if (delay) { + Current.current.effects = Current.current.effects.concat(hook) + invokeScheduleEffects(Current.current) + } else { + Current.current.layoutEffects = Current.current.layoutEffects.concat(hook) + } + } +} + +export function useEffect (effect, deps) { + useEffectImpl(effect, deps, true) +} + +export function useLayoutEffect (effect, deps) { + useEffectImpl(effect, deps) +} + +export function useRef (initialValue) { + const hook = getHooks(Current.index++) + if (!hook.ref) { + hook.ref = { + current: initialValue + } + } + return hook.ref +} + +export function useMemo (factory, deps) { + const hook = getHooks(Current.index++) + if (areDepsChanged(hook.deps, deps)) { + hook.deps = deps + hook.callback = factory + hook.value = factory() + } + return hook.value +} + +export function useCallback (callback, deps) { + return useMemo(() => callback, deps) +} + +export function useImperativeHandle (ref, init, deps) { + useLayoutEffect(() => { + if (isFunction(ref)) { + ref(init()) + return () => ref(null) + } else if (!isUndefined(ref)) { + ref.current = init() + return () => { + delete ref.current + } + } + }, isArray(deps) ? deps.concat([ref]) : undefined) +} diff --git a/packages/taro-qq/src/index.js b/packages/taro-qq/src/index.js new file mode 100644 index 000000000000..f15da579beda --- /dev/null +++ b/packages/taro-qq/src/index.js @@ -0,0 +1,44 @@ +/* eslint-disable camelcase */ +import { + getEnv, + Events, + eventCenter, + ENV_TYPE, + render, + internal_safe_get, + internal_safe_set, + internal_inline_style, + internal_get_original +} from '@tarojs/taro' + +import Component from './component' +import PureComponent from './pure-component' +import createApp from './create-app' +import createComponent from './create-component' +import initNativeApi from './native-api' +import { getElementById } from './util' +import { useEffect, useLayoutEffect, useReducer, useState, useRef, useCallback, useMemo, useImperativeHandle } from './hooks' + +export const Taro = { + Component, + PureComponent, + createApp, + initNativeApi, + Events, + eventCenter, + getEnv, + render, + ENV_TYPE, + internal_safe_get, + internal_safe_set, + internal_inline_style, + createComponent, + internal_get_original, + getElementById, + // eslint-disable-next-line object-property-newline + useEffect, useLayoutEffect, useReducer, useState, useRef, useCallback, useMemo, useImperativeHandle +} + +export default Taro + +initNativeApi(Taro) diff --git a/packages/taro-qq/src/lifecycle.js b/packages/taro-qq/src/lifecycle.js new file mode 100644 index 000000000000..ccb30acdcffd --- /dev/null +++ b/packages/taro-qq/src/lifecycle.js @@ -0,0 +1,150 @@ +import { + internal_safe_get as safeGet, + internal_safe_set as safeSet +} from '@tarojs/taro' +// import PropTypes from 'prop-types' +import { componentTrigger } from './create-component' +import { shakeFnFromObject, isEmptyObject, diffObjToPath } from './util' +import { Current } from './current-owner' +import { invokeEffects } from './hooks' + +// const isDEV = typeof process === 'undefined' || +// !process.env || +// process.env.NODE_ENV !== 'production' + +const privatePropKeyName = '_triggerObserer' +export function updateComponent (component) { + const { props } = component + // if (isDEV && __propTypes) { + // const componentName = component.constructor.name || component.constructor.toString().match(/^function\s*([^\s(]+)/)[1] + // PropTypes.checkPropTypes(__propTypes, props, 'prop', componentName) + // } + const prevProps = component.prevProps || props + component.props = prevProps + if (component.__mounted && component._unsafeCallUpdate === true && component.componentWillReceiveProps) { + component._disable = true + component.componentWillReceiveProps(props) + component._disable = false + } + // 在willMount前执行构造函数的副本 + if (!component.__componentWillMountTriggered) { + component._constructor && component._constructor(props) + } + let state = component.getState() + + const prevState = component.prevState || state + + let skip = false + if (component.__mounted) { + if (typeof component.shouldComponentUpdate === 'function' && + !component._isForceUpdate && + component.shouldComponentUpdate(props, state) === false) { + skip = true + } else if (typeof component.componentWillUpdate === 'function') { + component.componentWillUpdate(props, state) + } + } + component.props = props + component.state = state + component._dirty = false + component._isForceUpdate = false + if (!component.__componentWillMountTriggered) { + component.__componentWillMountTriggered = true + componentTrigger(component, 'componentWillMount') + } + if (!skip) { + doUpdate(component, prevProps, prevState) + } + component.prevProps = component.props + component.prevState = component.state +} + +function doUpdate (component, prevProps, prevState) { + const { state, props = {} } = component + let data = state || {} + if (component._createData) { + // 返回null或undefined则保持不变 + const runLoopRef = !component.__mounted + if (component.__isReady) { + Current.current = component + Current.index = 0 + invokeEffects(component, true) + } + data = component._createData(state, props, runLoopRef) || data + if (component.__isReady) { + Current.current = null + } + } + let privatePropKeyVal = component.$scope.data[privatePropKeyName] || false + + data = Object.assign({}, props, data) + if (component.$usedState && component.$usedState.length) { + const _data = {} + component.$usedState.forEach(key => { + let val = safeGet(data, key) + if (typeof val === 'undefined') { + return + } + if (typeof val === 'object') { + if (isEmptyObject(val)) return safeSet(_data, key, val) + + val = shakeFnFromObject(val) + // 避免筛选完 Fn 后产生了空对象还去渲染 + if (!isEmptyObject(val)) safeSet(_data, key, val) + } else { + safeSet(_data, key, val) + } + }) + data = _data + } + // 改变这个私有的props用来触发(observer)子组件的更新 + data[privatePropKeyName] = !privatePropKeyVal + const dataDiff = diffObjToPath(data, component.$scope.data) + const __mounted = component.__mounted + + // 每次 setData 都独立生成一个 callback 数组 + let cbs = [] + if (component._pendingCallbacks && component._pendingCallbacks.length) { + cbs = component._pendingCallbacks + component._pendingCallbacks = [] + } + + component.$scope.setData(dataDiff, function () { + if (__mounted) { + invokeEffects(component) + if (component['$$refs'] && component['$$refs'].length > 0) { + component['$$refs'].forEach(ref => { + // 只有 component 类型能做判断。因为 querySelector 每次调用都一定返回 nodeRefs,无法得知 dom 类型的挂载状态。 + if (ref.type !== 'component') return + + let target = component.$scope.selectComponent(`#${ref.id}`) + target = target ? (target.$component || target) : null + + const prevRef = ref.target + if (target !== prevRef) { + if (ref.refName) component.refs[ref.refName] = target + typeof ref.fn === 'function' && ref.fn.call(component, target) + ref.target = target + } + }) + } + + if (component['$$hasLoopRef']) { + component._disableEffect = true + component._createData(component.state, component.props, true) + component._disableEffect = false + } + + if (typeof component.componentDidUpdate === 'function') { + component.componentDidUpdate(prevProps, prevState) + } + } + + if (cbs.length) { + let i = cbs.length + while (--i >= 0) { + typeof cbs[i] === 'function' && cbs[i].call(component) + } + } + }) +} diff --git a/packages/taro-qq/src/native-api.js b/packages/taro-qq/src/native-api.js new file mode 100644 index 000000000000..7130e695ed80 --- /dev/null +++ b/packages/taro-qq/src/native-api.js @@ -0,0 +1,205 @@ +import { + onAndSyncApis, + noPromiseApis, + otherApis, + initPxTransform +} from '@tarojs/taro' +import { cacheDataSet, cacheDataGet } from './data-cache' +import { queryToJson, getUniqueKey } from './util' +const RequestQueue = { + MAX_REQUEST: 5, + queue: [], + request (options) { + this.push(options) + // 返回request task + return this.run() + }, + + push (options) { + this.queue.push(options) + }, + + run () { + if (!this.queue.length) { + return + } + if (this.queue.length <= this.MAX_REQUEST) { + let options = this.queue.shift() + let completeFn = options.complete + options.complete = (...args) => { + completeFn && completeFn.apply(options, args) + this.run() + } + return qq.request(options) + } + } +} + +function request (options) { + options = options || {} + if (typeof options === 'string') { + options = { + url: options + } + } + const originSuccess = options['success'] + const originFail = options['fail'] + const originComplete = options['complete'] + let requestTask + const p = new Promise((resolve, reject) => { + options['success'] = res => { + originSuccess && originSuccess(res) + resolve(res) + } + options['fail'] = res => { + originFail && originFail(res) + reject(res) + } + + options['complete'] = res => { + originComplete && originComplete(res) + } + + requestTask = RequestQueue.request(options) + }) + p.abort = (cb) => { + cb && cb() + if (requestTask) { + requestTask.abort() + } + return p + } + return p +} + +function processApis (taro) { + const weApis = Object.assign({ }, onAndSyncApis, noPromiseApis, otherApis) + const useDataCacheApis = { + 'navigateTo': true, + 'redirectTo': true, + 'reLaunch': true + } + const routerParamsPrivateKey = '__key_' + const preloadPrivateKey = '__preload_' + const preloadInitedComponent = '$preloadComponent' + Object.keys(weApis).forEach(key => { + if (!onAndSyncApis[key] && !noPromiseApis[key]) { + taro[key] = (options, ...args) => { + options = options || {} + let task = null + let obj = Object.assign({}, options) + if (typeof options === 'string') { + if (args.length) { + return qq[key](options, ...args) + } + return qq[key](options) + } + + if (key === 'navigateTo' || key === 'redirectTo' || key === 'switchTab') { + let url = obj['url'] ? obj['url'].replace(/^\//, '') : '' + if (url.indexOf('?') > -1) url = url.split('?')[0] + + const Component = cacheDataGet(url) + if (Component) { + const component = new Component() + if (component.componentWillPreload) { + const cacheKey = getUniqueKey() + const MarkIndex = obj.url.indexOf('?') + const params = queryToJson(obj.url.substring(MarkIndex + 1, obj.url.length)) + obj.url += (MarkIndex > -1 ? '&' : '?') + `${preloadPrivateKey}=${cacheKey}` + cacheDataSet(cacheKey, component.componentWillPreload(params)) + cacheDataSet(preloadInitedComponent, component) + } + } + } + + if (useDataCacheApis[key]) { + const url = obj['url'] = obj['url'] || '' + const MarkIndex = url.indexOf('?') + const params = queryToJson(url.substring(MarkIndex + 1, url.length)) + const cacheKey = getUniqueKey() + obj.url += (MarkIndex > -1 ? '&' : '?') + `${routerParamsPrivateKey}=${cacheKey}` + cacheDataSet(cacheKey, params) + } + + const p = new Promise((resolve, reject) => { + ['fail', 'success', 'complete'].forEach((k) => { + obj[k] = (res) => { + options[k] && options[k](res) + if (k === 'success') { + if (key === 'connectSocket') { + resolve( + Promise.resolve().then(() => Object.assign(task, res)) + ) + } else { + resolve(res) + } + } else if (k === 'fail') { + reject(res) + } + } + }) + if (args.length) { + task = qq[key](obj, ...args) + } else { + task = qq[key](obj) + } + }) + if (key === 'uploadFile' || key === 'downloadFile') { + p.progress = cb => { + if (task) { + task.onProgressUpdate(cb) + } + return p + } + p.abort = cb => { + cb && cb() + if (task) { + task.abort() + } + return p + } + } + return p + } + } else { + taro[key] = (...args) => { + const argsLen = args.length + const newArgs = args.concat() + const lastArg = newArgs[argsLen - 1] + if (lastArg && lastArg.isTaroComponent && lastArg.$scope) { + newArgs.splice(argsLen - 1, 1, lastArg.$scope) + } + return qq[key].apply(qq, newArgs) + } + } + }) +} + +function pxTransform (size) { + const { designWidth, deviceRatio } = this.config + if (!(designWidth in deviceRatio)) { + throw new Error(`deviceRatio 配置中不存在 ${designWidth} 的设置!`) + } + return parseInt(size, 10) / deviceRatio[designWidth] + 'rpx' +} + +function canIUseWebp () { + const { platform } = qq.getSystemInfoSync() + const platformLower = platform.toLowerCase() + if (platformLower === 'android' || platformLower === 'devtools') { + return true + } + return false +} + +export default function initNativeApi (taro) { + processApis(taro) + taro.request = request + taro.getCurrentPages = getCurrentPages + taro.getApp = getApp + taro.requirePlugin = requirePlugin + taro.initPxTransform = initPxTransform.bind(taro) + taro.pxTransform = pxTransform.bind(taro) + taro.canIUseWebp = canIUseWebp +} diff --git a/packages/taro-qq/src/next-tick.js b/packages/taro-qq/src/next-tick.js new file mode 100644 index 000000000000..10188216068e --- /dev/null +++ b/packages/taro-qq/src/next-tick.js @@ -0,0 +1,7 @@ +const nextTick = (fn, ...args) => { + fn = typeof fn === 'function' ? fn.bind(null, ...args) : fn + const timerFunc = qq.nextTick ? qq.nextTick : setTimeout + timerFunc(fn) +} + +export default nextTick diff --git a/packages/taro-qq/src/pure-component.js b/packages/taro-qq/src/pure-component.js new file mode 100644 index 000000000000..5aea70022c69 --- /dev/null +++ b/packages/taro-qq/src/pure-component.js @@ -0,0 +1,13 @@ +import { shallowEqual } from '@tarojs/utils' + +import Component from './component' + +class PureComponent extends Component { + isPureComponent = true + + shouldComponentUpdate (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState) + } +} + +export default PureComponent diff --git a/packages/taro-qq/src/render-queue.js b/packages/taro-qq/src/render-queue.js new file mode 100644 index 000000000000..9f2c40f7767e --- /dev/null +++ b/packages/taro-qq/src/render-queue.js @@ -0,0 +1,23 @@ +import nextTick from './next-tick' +import { updateComponent } from './lifecycle' + +let items = [] + +export function enqueueRender (component) { + // tslint:disable-next-line:no-conditional-assignment + if (!component._dirty && (component._dirty = true) && items.push(component) === 1) { + nextTick(rerender) + } +} + +export function rerender () { + let p + const list = items + items = [] + // tslint:disable-next-line:no-conditional-assignment + while ((p = list.pop())) { + if (p._dirty) { + updateComponent(p, true) + } + } +} diff --git a/packages/taro-qq/src/util.js b/packages/taro-qq/src/util.js new file mode 100644 index 000000000000..d9424bdb7cb2 --- /dev/null +++ b/packages/taro-qq/src/util.js @@ -0,0 +1,260 @@ +import isPlainObject from 'lodash/isPlainObject' + +export function isEmptyObject (obj) { + if (!obj || !isPlainObject(obj)) { + return false + } + for (const n in obj) { + if (obj.hasOwnProperty(n)) { + return false + } + } + return true +} + +export function isUndefined (o) { + return o === undefined +} + +export function isNullOrUndef (o) { + return isUndefined(o) || o === null +} + +/** + * JSON 克隆 + * @param {Object | Json} jsonObj json对象 + * @return {Object | Json} 新的json对象 + */ +export function objClone (jsonObj) { + let buf + if (Array.isArray(jsonObj)) { + buf = [] + let i = jsonObj.length + while (i--) { + buf[i] = objClone(jsonObj[i]) + } + return buf + } else if (isPlainObject(jsonObj)) { + buf = {} + for (const k in jsonObj) { + buf[k] = objClone(jsonObj[k]) + } + return buf + } else { + return jsonObj + } +} + +export function getPrototype (obj) { + /* eslint-disable */ + if (Object.getPrototypeOf) { + return Object.getPrototypeOf(obj) + } else if (obj.__proto__) { + return obj.__proto__ + } + /* eslint-enable */ + return obj.constructor.prototype +} + +export function getPrototypeChain (obj) { + const protoChain = [] + while ((obj = getPrototype(obj))) { + protoChain.push(obj) + } + return protoChain +} + +export function noop () {} + +export function isFunction (arg) { + return typeof arg === 'function' +} + +export function isArray (arg) { + return Array.isArray(arg) +} + +export function shakeFnFromObject (obj) { + let newObj + if (isArray(obj)) { + newObj = [] + const len = obj.length + for (let i = 0; i < len; i++) { + newObj.push(shakeFnFromObject(obj[i])) + } + } else if (isPlainObject(obj)) { + newObj = {} + for (const key in obj) { + if (isFunction(obj[key])) { + continue + } + const ret = shakeFnFromObject(obj[key]) + newObj[key] = ret + } + } else { + return obj + } + return newObj +} + +const keyList = Object.keys +const hasProp = Object.prototype.hasOwnProperty + +function diffArrToPath (to, from, res = {}, keyPrev = '') { + const len = to.length + for (let i = 0; i < len; i++) { + const toItem = to[i] + const fromItem = from[i] + const targetKey = `${keyPrev}[${i}]` + if (toItem === fromItem) { + continue + } else if (typeof toItem !== typeof fromItem) { + res[targetKey] = toItem + } else { + if (typeof toItem !== 'object') { + res[targetKey] = toItem + } else { + const arrTo = isArray(toItem) + const arrFrom = isArray(fromItem) + if (arrTo !== arrFrom) { + res[targetKey] = toItem + } else if (arrTo && arrFrom) { + if (toItem.length === fromItem.length) { + diffArrToPath(toItem, fromItem, res, `${targetKey}`) + } else { + res[targetKey] = toItem + } + } else { + if (!toItem || !fromItem || keyList(toItem).length < keyList(fromItem).length) { + res[targetKey] = toItem + } else { + // 对象 + let shouldDiffObject = true + Object.keys(fromItem).some(key => { + if (typeof toItem[key] === 'undefined') { + shouldDiffObject = false + return true + } + }) + if (shouldDiffObject) { + diffObjToPath(toItem, fromItem, res, `${targetKey}.`) + } else { + res[targetKey] = toItem + } + } + } + } + } + } + return res +} + +// 比较的对象均为plainObject,且函数已被过滤 +export function diffObjToPath (to, from, res = {}, keyPrev = '') { + const keys = keyList(to) + const len = keys.length + + for (let i = 0; i < len; i++) { + const key = keys[i] + const toItem = to[key] + const fromItem = from[key] + const targetKey = `${keyPrev}${key}` + if (toItem === fromItem) { + continue + } else if (!hasProp.call(from, key)) { + res[targetKey] = toItem + } else if (typeof toItem !== typeof fromItem) { + res[targetKey] = toItem + } else { + if (typeof toItem !== 'object') { + res[targetKey] = toItem + } else { + const arrTo = isArray(toItem) + const arrFrom = isArray(fromItem) + if (arrTo !== arrFrom) { + res[targetKey] = toItem + } else if (arrTo && arrFrom) { + if (toItem.length === fromItem.length) { + diffArrToPath(toItem, fromItem, res, `${targetKey}`) + } else { + res[targetKey] = toItem + } + } else { + // null + if (!toItem || !fromItem) { + res[targetKey] = toItem + } else { + // 对象 + let shouldDiffObject = true + Object.keys(fromItem).some(key => { + if (typeof toItem[key] === 'undefined') { + shouldDiffObject = false + return true + } + }) + if (shouldDiffObject) { + diffObjToPath(toItem, fromItem, res, `${targetKey}.`) + } else { + res[targetKey] = toItem + } + } + } + } + } + } + return res +} + +export function queryToJson (str) { + const dec = decodeURIComponent + const qp = str.split('&') + let ret = {} + let name + let val + for (let i = 0, l = qp.length, item; i < l; ++i) { + item = qp[i] + if (item.length) { + const s = item.indexOf('=') + if (s < 0) { + name = dec(item) + val = '' + } else { + name = dec(item.slice(0, s)) + val = dec(item.slice(s + 1)) + } + if (typeof ret[name] === 'string') { // inline'd type check + ret[name] = [ret[name]] + } + + if (isArray(ret[name])) { + ret[name].push(val) + } else { + ret[name] = val + } + } + } + return ret // Object +} + +const _loadTime = (new Date()).getTime().toString() +let _i = 1 +export function getUniqueKey () { + return _loadTime + (_i++) +} + +export function getElementById (component, id, type) { + if (!component) return null + + let res + if (type === 'component') { + res = component.selectComponent(id) + res = res ? (res.$component || res) : null + } else { + const query = qq.createSelectorQuery().in(component) + res = query.select(id) + } + + if (res) return res + + return null +} diff --git a/packages/taro-transformer-wx/src/adapter.ts b/packages/taro-transformer-wx/src/adapter.ts index f7e3f8349e44..507645cc96af 100644 --- a/packages/taro-transformer-wx/src/adapter.ts +++ b/packages/taro-transformer-wx/src/adapter.ts @@ -3,7 +3,8 @@ export const enum Adapters { swan = 'swan', alipay = 'alipay', quickapp = 'quickapp', - tt = 'tt' + tt = 'tt', + qq = 'qq' } interface Adapter { @@ -72,6 +73,17 @@ const quickappAdapter: Adapter = { type: Adapters.quickapp } +const qqAdapter: Adapter = { + if: 'qq:if', + else: 'qq:else', + elseif: 'qq:elif', + for: 'qq:for', + forItem: 'qq:for-item', + forIndex: 'qq:for-index', + key: 'qq:key', + type: Adapters.qq +} + export let Adapter: Adapter = weixinAdapter export function setAdapter (adapter: Adapters) { @@ -88,6 +100,9 @@ export function setAdapter (adapter: Adapters) { case Adapters.quickapp: Adapter = quickappAdapter break + case Adapters.qq: + Adapter = qqAdapter + break default: Adapter = weixinAdapter break diff --git a/packages/taro/src/env.js b/packages/taro/src/env.js index f455f035dd91..c87aa6d4646e 100644 --- a/packages/taro/src/env.js +++ b/packages/taro/src/env.js @@ -4,10 +4,14 @@ export const ENV_TYPE = { RN: 'RN', SWAN: 'SWAN', ALIPAY: 'ALIPAY', - TT: 'TT' + TT: 'TT', + QQ: 'QQ' } export function getEnv () { + if (typeof qq !== 'undefined' && qq.getSystemInfo) { + return ENV_TYPE.QQ + } if (typeof tt !== 'undefined' && tt.getSystemInfo) { return ENV_TYPE.TT } From 113b48e61991ae32a03d58c3efc573edfbb5f5d3 Mon Sep 17 00:00:00 2001 From: yuche Date: Thu, 18 Apr 2019 15:36:21 +0800 Subject: [PATCH 095/126] =?UTF-8?q?refactor(transformer):=20=E5=BF=AB?= =?UTF-8?q?=E5=BA=94=E7=94=A8=20taro-page=20=E7=9A=84=E7=9A=84=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E5=BA=94=E8=AF=A5=E4=BF=9D=E6=8C=81=E5=8E=9F=E6=A0=B7?= =?UTF-8?q?=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../taro-transformer-wx/src/create-html-element.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/taro-transformer-wx/src/create-html-element.ts b/packages/taro-transformer-wx/src/create-html-element.ts index 0fc2196cf5d9..f5aac71e63ab 100644 --- a/packages/taro-transformer-wx/src/create-html-element.ts +++ b/packages/taro-transformer-wx/src/create-html-element.ts @@ -1,6 +1,7 @@ import { Adapters, Adapter } from './adapter' import { quickappComponentName } from './constant' -import { transformOptions } from './options'; +import { transformOptions } from './options' +import { camelCase } from 'lodash' const voidHtmlTags = new Set([ // 'image', @@ -64,6 +65,13 @@ export const createHTMLElement = (options: Options, isFirstEmit = false) => { } if (isFirstEmit && name === 'div' && transformOptions.isRoot) { options.name = 'taro-page' + for (const key in options.attributes) { + if (options.attributes.hasOwnProperty(key)) { + const attr = options.attributes[key] + options.attributes[camelCase(key)] = attr + delete options.attributes[key] + } + } } } From 3f1b25f92ed6afcc7c8dd56f21029b093dcab98b Mon Sep 17 00:00:00 2001 From: jinjinjin0731 <709899428@qq.com> Date: Fri, 19 Apr 2019 15:19:10 +0800 Subject: [PATCH 096/126] =?UTF-8?q?feat(component):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=BF=AB=E5=BA=94=E7=94=A8=20button,=20checkbox?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/checkbox/index.ux | 33 +++++ .../src/components/taro-button/index.ux | 115 ++++++------------ 2 files changed, 73 insertions(+), 75 deletions(-) create mode 100644 packages/taro-components-qa/src/components/checkbox/index.ux diff --git a/packages/taro-components-qa/src/components/checkbox/index.ux b/packages/taro-components-qa/src/components/checkbox/index.ux new file mode 100644 index 000000000000..3658415a513c --- /dev/null +++ b/packages/taro-components-qa/src/components/checkbox/index.ux @@ -0,0 +1,33 @@ + + + + + diff --git a/packages/taro-components-qa/src/components/taro-button/index.ux b/packages/taro-components-qa/src/components/taro-button/index.ux index 8b8602d36340..d46707124fed 100644 --- a/packages/taro-components-qa/src/components/taro-button/index.ux +++ b/packages/taro-components-qa/src/components/taro-button/index.ux @@ -1,17 +1,13 @@ From acd3ec8bafc7a13eb56ce76ac680ce7771b159e6 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Wed, 17 Apr 2019 17:38:03 +0800 Subject: [PATCH 097/126] =?UTF-8?q?feat(cli):=20=E5=BF=AB=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E7=BC=96=E8=AF=91=E6=97=B6=E9=9C=80=E8=A6=81=E4=BC=A0?= =?UTF-8?q?=E5=85=A5=E6=A0=B9=E8=8A=82=E7=82=B9=E9=9C=80=E8=A6=81=E7=9A=84?= =?UTF-8?q?=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-cli/src/mini/page.ts | 24 ++++++++++++++++++- packages/taro-cli/src/util/constants.ts | 1 - .../src/components/taro-page/index.ux | 8 +++++-- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/packages/taro-cli/src/mini/page.ts b/packages/taro-cli/src/mini/page.ts index 02aad5f76d88..af2a12b57ec8 100644 --- a/packages/taro-cli/src/mini/page.ts +++ b/packages/taro-cli/src/mini/page.ts @@ -56,7 +56,8 @@ export async function buildSinglePage (page: string) { nodeModulesPath, npmOutputDir, jsxAttributeNameReplace, - pageConfigs + pageConfigs, + appConfig } = getBuildData() const pagePath = path.join(sourceDir, `${page}`) const pageJs = resolveScriptPath(pagePath) @@ -93,6 +94,26 @@ export async function buildSinglePage (page: string) { return } try { + const rootProps: { [key: string]: any } = {} + if (isQuickApp) { + // 如果是快应用,需要提前解析一次 ast,获取 config + const aheadTransformResult: IWxTransformResult = wxTransformer({ + code: pageJsContent, + sourcePath: pageJs, + outputPath: outputPageJSPath, + isRoot: true, + isTyped: REG_TYPESCRIPT.test(pageJs), + adapter: buildAdapter, + env: constantsReplaceList + }) + const res = parseAst(PARSE_AST_TYPE.PAGE, aheadTransformResult.ast, [], pageJs, outputPageJSPath) + if (res.configObj.enablePullDownRefresh || (appConfig.window && appConfig.window.enablePullDownRefresh)) { + rootProps.enablePullDownRefresh = true + } + if (appConfig.tabBar) { + rootProps.tabBar = appConfig.tabBar + } + } const transformResult: IWxTransformResult = wxTransformer({ code: pageJsContent, sourcePath: pageJs, @@ -101,6 +122,7 @@ export async function buildSinglePage (page: string) { isTyped: REG_TYPESCRIPT.test(pageJs), adapter: buildAdapter, env: constantsReplaceList, + rootProps, jsxAttributeNameReplace }) const pageDepComponents = transformResult.components diff --git a/packages/taro-cli/src/util/constants.ts b/packages/taro-cli/src/util/constants.ts index 558447fd2d44..64b129c5bc80 100644 --- a/packages/taro-cli/src/util/constants.ts +++ b/packages/taro-cli/src/util/constants.ts @@ -235,7 +235,6 @@ export const CONFIG_MAP = { navigationBarTextStyle: 'titleBarTextColor', pageOrientation: 'orientation', backgroundTextStyle: false, - enablePullDownRefresh: false, list: false, text: false, iconPath: false, diff --git a/packages/taro-components-qa/src/components/taro-page/index.ux b/packages/taro-components-qa/src/components/taro-page/index.ux index 30ab0aacb008..818fbfd1d8e2 100644 --- a/packages/taro-components-qa/src/components/taro-page/index.ux +++ b/packages/taro-components-qa/src/components/taro-page/index.ux @@ -1,6 +1,6 @@