From 028f22cb168f67ec6f414dd97473a66c436191c6 Mon Sep 17 00:00:00 2001 From: luckyadam Date: Tue, 4 Jun 2019 23:11:08 +0800 Subject: [PATCH] =?UTF-8?q?feat(taro-mini-runner):=20=E7=94=9F=E6=88=90?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E4=BB=A5=E5=8F=8A=E7=BB=84=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=20usingComponents=20=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/plugins/MiniPlugin.ts | 6 +- packages/taro-mini-runner/src/utils/index.ts | 72 +++++++++++++++++++ packages/taro-mini-runner/src/utils/types.ts | 6 ++ 3 files changed, 81 insertions(+), 3 deletions(-) diff --git a/packages/taro-mini-runner/src/plugins/MiniPlugin.ts b/packages/taro-mini-runner/src/plugins/MiniPlugin.ts index 3cb77791e08f..352e84e0622f 100644 --- a/packages/taro-mini-runner/src/plugins/MiniPlugin.ts +++ b/packages/taro-mini-runner/src/plugins/MiniPlugin.ts @@ -9,13 +9,13 @@ import * as FunctionModulePlugin from 'webpack/lib/FunctionModulePlugin' import * as NodeSourcePlugin from 'webpack/lib/node/NodeSourcePlugin' import * as LoaderTargetPlugin from 'webpack/lib/LoaderTargetPlugin' import * as VirtualModulePlugin from 'virtual-module-webpack-plugin' -import { defaults } from 'lodash' +import { merge, defaults } from 'lodash' import * as t from 'babel-types' import traverse from 'babel-traverse' import { Config as IConfig } from '@tarojs/taro' import { REG_TYPESCRIPT, BUILD_TYPES, PARSE_AST_TYPE } from '../utils/constants' -import { traverseObjectNode, resolveScriptPath } from '../utils' +import { traverseObjectNode, resolveScriptPath, buildUsingComponents } from '../utils' import TaroTemplatePlugin from './TaroTemplatePlugin' import TaroLoadChunksPlugin from './TaroLoadChunksPlugin' @@ -234,7 +234,7 @@ export default class MiniPlugin { const { configObj } = this.parseAst(transformResult.ast, buildAdapter) taroFileTypeMap[file.path] = { type: isRoot ? PARSE_AST_TYPE.PAGE : PARSE_AST_TYPE.COMPONENT, - config: configObj, + config: merge({}, buildUsingComponents(file.path, {}, transformResult.components),configObj), wxml: transformResult.template, code: transformResult.code } diff --git a/packages/taro-mini-runner/src/utils/index.ts b/packages/taro-mini-runner/src/utils/index.ts index bcff6290cdec..d839bfbdcba1 100644 --- a/packages/taro-mini-runner/src/utils/index.ts +++ b/packages/taro-mini-runner/src/utils/index.ts @@ -4,6 +4,7 @@ import * as fs from 'fs-extra' import * as t from 'babel-types' import { CONFIG_MAP, JS_EXT, TS_EXT } from './constants' +import { IOption, IComponentObj } from './types' export function isNpmPkg (name: string): boolean { if (/^(\.|\/)/.test(name)) { @@ -56,6 +57,50 @@ export function traverseObjectNode (node, buildAdapter: string, parentKey?: stri return node.value } +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(resolveScriptPath(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 function resolveScriptPath (p: string): string { const realPath = p const taroEnv = process.env.TARO_ENV @@ -82,3 +127,30 @@ export function resolveScriptPath (p: string): string { } return realPath } + +export function buildUsingComponents ( + filePath: string, + pathAlias: IOption, + 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 + } : {}) +} diff --git a/packages/taro-mini-runner/src/utils/types.ts b/packages/taro-mini-runner/src/utils/types.ts index ce7418cab98e..85088955d277 100644 --- a/packages/taro-mini-runner/src/utils/types.ts +++ b/packages/taro-mini-runner/src/utils/types.ts @@ -8,6 +8,12 @@ export interface IOption { [key: string]: any } +export interface IComponentObj { + name?: string, + path: string | null, + type?: string +} + type TogglableOptions = { enable?: boolean config?: T