1 | import * as path from 'path'
|
2 | import * as babel from 'babel-core'
|
3 | import traverse, { NodePath } from 'babel-traverse'
|
4 | import * as t from 'babel-types'
|
5 | import * as _ from 'lodash'
|
6 | import generate from 'babel-generator'
|
7 | import wxTransformer from '@tarojs/transformer-wx'
|
8 | import {
|
9 | REG_STYLE,
|
10 | REG_TYPESCRIPT,
|
11 | REG_SCRIPTS,
|
12 | resolveScriptPath,
|
13 | resolveStylePath,
|
14 | replaceAliasPath,
|
15 | isAliasPath,
|
16 | promoteRelativePath,
|
17 | isNpmPkg,
|
18 | generateEnvList,
|
19 | generateConstantsList
|
20 | } from '@tarojs/helper'
|
21 |
|
22 | import babylonConfig from '../config/babylon'
|
23 | import { convertSourceStringToAstExpression as toAst, convertAstExpressionToVariable as toVar } from '../util/astConvert'
|
24 |
|
25 | const template = require('babel-template')
|
26 |
|
27 | const reactImportDefaultName = 'React'
|
28 | let taroImportDefaultName
|
29 | let componentClassName
|
30 | const providerComponentName = 'Provider'
|
31 | const taroComponentsRNProviderName = 'TCRNProvider'
|
32 | const setStoreFuncName = 'setStore'
|
33 | const routerImportDefaultName = 'TaroRouter'
|
34 | const DEVICE_RATIO = 'deviceRatio'
|
35 |
|
36 | const taroApis = ['getEnv', 'ENV_TYPE', 'eventCenter', 'Events', 'internal_safe_get', 'internal_dynamic_recursive']
|
37 |
|
38 | const PACKAGES = {
|
39 | '@tarojs/taro': '@tarojs/taro',
|
40 | '@tarojs/taro-rn': '@tarojs/taro-rn',
|
41 | '@tarojs/taro-router-rn': '@tarojs/taro-router-rn',
|
42 | '@tarojs/redux': '@tarojs/redux',
|
43 | '@tarojs/components': '@tarojs/components',
|
44 | '@tarojs/components-rn': '@tarojs/components-rn',
|
45 | react: 'react',
|
46 | 'react-native': 'react-native',
|
47 | 'react-redux-rn': '@tarojs/taro-redux-rn',
|
48 | '@tarojs/mobx': '@tarojs/mobx',
|
49 | '@tarojs/mobx-rn': '@tarojs/mobx-rn'
|
50 | }
|
51 |
|
52 | const additionalConstructorNode = toAst('Taro._$app = this')
|
53 | const superNode = t.expressionStatement(
|
54 | t.callExpression(
|
55 |
|
56 |
|
57 | t.super(),
|
58 | [
|
59 | t.identifier('props'),
|
60 | t.identifier('context')
|
61 | ]
|
62 | )
|
63 | )
|
64 |
|
65 | function getInitPxTransformNode (projectConfig) {
|
66 | const pxTransformConfig = { designWidth: projectConfig.designWidth || 750 }
|
67 |
|
68 | if (projectConfig.hasOwnProperty(DEVICE_RATIO)) {
|
69 | pxTransformConfig[DEVICE_RATIO] = projectConfig.deviceRatio
|
70 | }
|
71 | const initPxTransformNode = toAst(`Taro.initPxTransform(${JSON.stringify(pxTransformConfig)})`)
|
72 | return initPxTransformNode
|
73 | }
|
74 |
|
75 | function getClassPropertyVisitor ({ pages, iconPaths, isEntryFile }) {
|
76 | return astPath => {
|
77 | const node = astPath.node
|
78 | const key = node.key
|
79 | const value = node.value
|
80 | if (key.name !== 'config' || !t.isObjectExpression(value)) return
|
81 |
|
82 | if (isEntryFile) {
|
83 |
|
84 | astPath.traverse({
|
85 | ObjectProperty (astPath) {
|
86 | const node = astPath.node
|
87 | const key = node.key
|
88 | const value = node.value
|
89 |
|
90 | if (key.name === 'pages' && t.isArrayExpression(value)) {
|
91 |
|
92 | let root = ''
|
93 | const rootNode = astPath.parent.properties.find(v => {
|
94 | return v.key.name === 'root'
|
95 | })
|
96 | root = rootNode ? rootNode.value.value : ''
|
97 |
|
98 | value.elements.forEach(v => {
|
99 | if (t.isStringLiteral(v)) {
|
100 | const pagePath = `${root}/${v.value}`.replace(/\/{2,}/g, '/')
|
101 | pages.push(pagePath.replace(/^\//, ''))
|
102 | }
|
103 | })
|
104 | astPath.remove()
|
105 | }
|
106 |
|
107 | if (key.name === 'window' && t.isObjectExpression(value)) {
|
108 | return
|
109 | }
|
110 | if (key.name === 'tabBar' && t.isObjectExpression(value)) {
|
111 | astPath.traverse({
|
112 | ObjectProperty (astPath) {
|
113 | const node = astPath.node as any
|
114 | const value = node.value.value
|
115 | if (
|
116 | node.key.name === 'iconPath' ||
|
117 | node.key.value === 'iconPath' ||
|
118 | node.key.name === 'selectedIconPath' ||
|
119 | node.key.value === 'selectedIconPath'
|
120 | ) {
|
121 | if (typeof value !== 'string') return
|
122 | const iconName = _.camelCase(value)
|
123 | if (iconPaths.indexOf(value) === -1) {
|
124 | iconPaths.push(value)
|
125 | }
|
126 | astPath.insertAfter(
|
127 | t.objectProperty(t.identifier(node.key.name || node.key.value), t.identifier(iconName))
|
128 | )
|
129 | astPath.remove()
|
130 | }
|
131 | }
|
132 | })
|
133 | }
|
134 | }
|
135 | })
|
136 | }
|
137 | astPath.node.static = 'true'
|
138 | }
|
139 | }
|
140 |
|
141 | function getJSAst (code, filePath) {
|
142 | return wxTransformer({
|
143 | code,
|
144 | sourcePath: filePath,
|
145 | isNormal: true,
|
146 | isTyped: REG_TYPESCRIPT.test(filePath),
|
147 | adapter: 'rn'
|
148 | }).ast
|
149 | }
|
150 |
|
151 |
|
152 |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 | function resetTSClassProperty (body) {
|
158 | for (const method of body) {
|
159 | if (t.isClassMethod(method) && method.kind === 'constructor') {
|
160 | for (const statement of _.cloneDeep(method.body.body)) {
|
161 | if (t.isExpressionStatement(statement) && t.isAssignmentExpression(statement.expression)) {
|
162 | const expr = statement.expression
|
163 | const { left, right } = expr
|
164 | if (t.isMemberExpression(left) && t.isThisExpression(left.object) && t.isIdentifier(left.property)) {
|
165 | if (
|
166 | t.isArrowFunctionExpression(right) ||
|
167 | t.isFunctionExpression(right) ||
|
168 | (left.property.name === 'config' && t.isObjectExpression(right))
|
169 | ) {
|
170 | body.push(t.classProperty(left.property, right))
|
171 | _.remove(method.body.body, statement)
|
172 | }
|
173 | }
|
174 | }
|
175 | }
|
176 | }
|
177 | }
|
178 | }
|
179 |
|
180 | const ClassDeclarationOrExpression = {
|
181 | enter (astPath) {
|
182 | const node = astPath.node
|
183 | if (!node.superClass) return
|
184 | if (node.superClass.type === 'MemberExpression' && node.superClass.object.name === taroImportDefaultName) {
|
185 | node.superClass.object.name = taroImportDefaultName
|
186 | if (node.id === null) {
|
187 | const renameComponentClassName = '_TaroComponentClass'
|
188 | componentClassName = renameComponentClassName
|
189 | astPath.replaceWith(
|
190 | t.classDeclaration(t.identifier(renameComponentClassName), node.superClass, node.body, node.decorators || [])
|
191 | )
|
192 | } else {
|
193 | componentClassName = node.id.name
|
194 | }
|
195 | } else if (node.superClass.name === 'Component' || node.superClass.name === 'PureComponent') {
|
196 | resetTSClassProperty(node.body.body)
|
197 | if (node.id === null) {
|
198 | const renameComponentClassName = '_TaroComponentClass'
|
199 | componentClassName = renameComponentClassName
|
200 | astPath.replaceWith(
|
201 | t.classDeclaration(t.identifier(renameComponentClassName), node.superClass, node.body, node.decorators || [])
|
202 | )
|
203 | } else {
|
204 | componentClassName = node.id.name
|
205 | }
|
206 | }
|
207 | }
|
208 | }
|
209 |
|
210 | export function parseJSCode ({ code, filePath, isEntryFile, projectConfig }) {
|
211 | let ast
|
212 | ast = getJSAst(code, filePath)
|
213 | const styleFiles: string[] = []
|
214 | const pages: string[] = []
|
215 | const iconPaths: string[] = []
|
216 | let hasAddReactImportDefaultName = false
|
217 | let providorImportName
|
218 | let storeName
|
219 | let hasAppExportDefault
|
220 | let classRenderReturnJSX
|
221 |
|
222 | let hasConstructor = false
|
223 | let hasComponentDidMount = false
|
224 | let hasComponentDidShow = false
|
225 | let hasComponentDidHide = false
|
226 | let hasComponentWillUnmount = false
|
227 | let hasJSX = false
|
228 |
|
229 | traverse(ast, {
|
230 | ClassExpression: ClassDeclarationOrExpression,
|
231 | ClassDeclaration: ClassDeclarationOrExpression,
|
232 | ExpressionStatement (astPath) {
|
233 | const node = astPath.node as t.ExpressionStatement
|
234 | const expression = node.expression as t.CallExpression
|
235 | const callee = expression.callee as t.Identifier
|
236 | if (callee && callee.name === 'require') {
|
237 | const argument = expression.arguments[0] as t.StringLiteral
|
238 | const value = argument.value
|
239 | const valueExtname = path.extname(value)
|
240 | if (REG_STYLE.test(valueExtname)) {
|
241 | astPath.replaceWith(t.importDeclaration([], t.stringLiteral(value)))
|
242 | }
|
243 | }
|
244 | },
|
245 | ImportDeclaration (astPath) {
|
246 | const node = astPath.node as t.ImportDeclaration
|
247 | const source = node.source
|
248 | let value = source.value
|
249 | const valueExtname = path.extname(value)
|
250 | const specifiers = node.specifiers
|
251 | const pathAlias = projectConfig.alias || {}
|
252 | if (isAliasPath(value, pathAlias)) {
|
253 | source.value = value = replaceAliasPath(filePath, value, pathAlias)
|
254 | }
|
255 |
|
256 | if (!isNpmPkg(value)) {
|
257 |
|
258 | if (REG_STYLE.test(valueExtname)) {
|
259 | const stylePath = path.resolve(path.dirname(filePath), value)
|
260 | if (styleFiles.indexOf(stylePath) < 0) {
|
261 |
|
262 | const realStylePath = resolveStylePath(stylePath)
|
263 | styleFiles.push(realStylePath)
|
264 | }
|
265 | }
|
266 | if (value.indexOf('.') === 0) {
|
267 |
|
268 |
|
269 |
|
270 |
|
271 | if (REG_SCRIPTS.test(value) || path.extname(value) === '') {
|
272 | const absolutePath = path.resolve(filePath, '..', value)
|
273 | const dirname = path.dirname(absolutePath)
|
274 | const extname = path.extname(absolutePath)
|
275 | const realFilePath = resolveScriptPath(path.join(dirname, path.basename(absolutePath, extname)))
|
276 | const removeExtPath = realFilePath.replace(path.extname(realFilePath), '')
|
277 | node.source = t.stringLiteral(
|
278 | promoteRelativePath(path.relative(filePath, removeExtPath)).replace(/\\/g, '/')
|
279 | )
|
280 | }
|
281 | }
|
282 | return
|
283 | }
|
284 | if (value === PACKAGES['@tarojs/taro']) {
|
285 | const specifier = specifiers.find(item => item.type === 'ImportDefaultSpecifier')
|
286 | if (specifier) {
|
287 | hasAddReactImportDefaultName = true
|
288 | taroImportDefaultName = specifier.local.name
|
289 | specifier.local.name = reactImportDefaultName
|
290 | } else if (!hasAddReactImportDefaultName) {
|
291 | hasAddReactImportDefaultName = true
|
292 | node.specifiers.unshift(t.importDefaultSpecifier(t.identifier(reactImportDefaultName)))
|
293 | }
|
294 |
|
295 | specifiers.forEach((item, index) => {
|
296 | if (item.type === 'ImportDefaultSpecifier') {
|
297 | specifiers.splice(index, 1)
|
298 | }
|
299 | })
|
300 | const taroApisSpecifiers: t.ImportSpecifier[] = []
|
301 | specifiers.forEach((item, index) => {
|
302 | if (
|
303 | (item as t.ImportSpecifier).imported &&
|
304 | taroApis.indexOf((item as t.ImportSpecifier).imported.name) >= 0
|
305 | ) {
|
306 | taroApisSpecifiers.push(
|
307 | t.importSpecifier(
|
308 | t.identifier((item as t.ImportSpecifier).local.name),
|
309 | t.identifier((item as t.ImportSpecifier).imported.name)
|
310 | )
|
311 | )
|
312 | specifiers.splice(index, 1)
|
313 | }
|
314 | })
|
315 | source.value = PACKAGES['@tarojs/taro-rn']
|
316 |
|
317 | if (taroApisSpecifiers.length) {
|
318 | astPath.insertBefore(t.importDeclaration(taroApisSpecifiers, t.stringLiteral(PACKAGES['@tarojs/taro-rn'])))
|
319 | }
|
320 | if (!specifiers.length) {
|
321 | astPath.remove()
|
322 | }
|
323 | } else if (value === PACKAGES['@tarojs/redux']) {
|
324 | const specifier = specifiers.find(item => {
|
325 | return t.isImportSpecifier(item) && item.imported.name === providerComponentName
|
326 | })
|
327 | if (specifier) {
|
328 | providorImportName = specifier.local.name
|
329 | } else {
|
330 | providorImportName = providerComponentName
|
331 | specifiers.push(t.importSpecifier(t.identifier(providerComponentName), t.identifier(providerComponentName)))
|
332 | }
|
333 | source.value = PACKAGES['react-redux-rn']
|
334 | } else if (value === PACKAGES['@tarojs/mobx']) {
|
335 | const specifier = specifiers.find(item => {
|
336 | return t.isImportSpecifier(item) && item.imported.name === providerComponentName
|
337 | })
|
338 | if (specifier) {
|
339 | providorImportName = specifier.local.name
|
340 | } else {
|
341 | providorImportName = providerComponentName
|
342 | specifiers.push(t.importSpecifier(t.identifier(providerComponentName), t.identifier(providerComponentName)))
|
343 | }
|
344 | source.value = PACKAGES['@tarojs/mobx-rn']
|
345 | } else if (value === PACKAGES['@tarojs/components']) {
|
346 | source.value = PACKAGES['@tarojs/components-rn']
|
347 | }
|
348 | },
|
349 | ClassProperty: getClassPropertyVisitor({ pages, iconPaths, isEntryFile }),
|
350 | ClassMethod: {
|
351 | enter (astPath: NodePath<t.ClassMethod>) {
|
352 | const node = astPath.node
|
353 | const key = node.key
|
354 | const keyName = toVar(key)
|
355 |
|
356 | if (!isEntryFile) return
|
357 |
|
358 | if (keyName === 'constructor') {
|
359 | hasConstructor = true
|
360 | } else if (keyName === 'componentDidMount') {
|
361 | hasComponentDidMount = true
|
362 | } else if (keyName === 'componentDidShow') {
|
363 | hasComponentDidShow = true
|
364 | } else if (keyName === 'componentDidHide') {
|
365 | hasComponentDidHide = true
|
366 | } else if (keyName === 'componentWillUnmount') {
|
367 | hasComponentWillUnmount = true
|
368 | }
|
369 |
|
370 | if (keyName === 'render') {
|
371 | astPath.traverse({
|
372 | BlockStatement (astPath) {
|
373 | if (astPath.parent === node) {
|
374 | const node = astPath.node
|
375 | astPath.traverse({
|
376 | ReturnStatement (astPath) {
|
377 | if (astPath.parent === node) {
|
378 | astPath.traverse({
|
379 | JSXElement (astPath) {
|
380 | classRenderReturnJSX = generate(astPath.node).code
|
381 | }
|
382 | })
|
383 | }
|
384 | }
|
385 | })
|
386 | }
|
387 | }
|
388 | })
|
389 | }
|
390 | }
|
391 | },
|
392 |
|
393 | ExportDefaultDeclaration () {
|
394 | if (isEntryFile) {
|
395 | hasAppExportDefault = true
|
396 | }
|
397 | },
|
398 | JSXElement: {
|
399 | exit () {
|
400 | hasJSX = true
|
401 | }
|
402 | },
|
403 | JSXOpeningElement: {
|
404 | enter (astPath) {
|
405 | const node = astPath.node as t.JSXOpeningElement
|
406 | if ((node.name as any).name === 'Provider') {
|
407 | for (const v of node.attributes) {
|
408 | if (v.name.name !== 'store') continue
|
409 | storeName = (v.value as any).expression.name
|
410 | break
|
411 | }
|
412 | }
|
413 | }
|
414 | },
|
415 | Program: {
|
416 | exit (astPath) {
|
417 | const node = astPath.node as t.Program
|
418 | astPath.traverse({
|
419 | ClassMethod (astPath) {
|
420 | const node = astPath.node
|
421 | const key = node.key as t.Identifier
|
422 |
|
423 | const keyName = toVar(key)
|
424 | const isComponentDidMount = keyName === 'componentDidMount'
|
425 | const isComponentWillUnmount = keyName === 'componentWillUnmount'
|
426 | const isConstructor = keyName === 'constructor'
|
427 |
|
428 | if (!isEntryFile) return
|
429 |
|
430 | if (hasConstructor && isConstructor) {
|
431 | node.body.body.push(additionalConstructorNode)
|
432 | }
|
433 |
|
434 | if (hasComponentDidShow && isComponentDidMount) {
|
435 | const componentDidShowCallNode = toAst('this.componentDidShow()')
|
436 | node.body.body.push(componentDidShowCallNode)
|
437 | }
|
438 |
|
439 | if (hasComponentDidHide && isComponentWillUnmount) {
|
440 | const componentDidHideCallNode = toAst('this.componentDidHide()')
|
441 | node.body.body.unshift(componentDidHideCallNode)
|
442 | }
|
443 |
|
444 | if (key.name === 'render') {
|
445 | let funcBody = `
|
446 | <${taroComponentsRNProviderName}>
|
447 | ${classRenderReturnJSX}
|
448 | </${taroComponentsRNProviderName}>`
|
449 |
|
450 | if (pages.length > 0) {
|
451 | funcBody = `
|
452 | <${taroComponentsRNProviderName}>
|
453 | <RootStack/>
|
454 | </${taroComponentsRNProviderName}>`
|
455 | }
|
456 |
|
457 | if (providerComponentName && storeName) {
|
458 |
|
459 | funcBody = `
|
460 | <${providorImportName} store={${storeName}}>
|
461 | ${funcBody}
|
462 | </${providorImportName}>`
|
463 | }
|
464 | node.body = template(`{return (${funcBody});}`, babylonConfig as any)() as any
|
465 | }
|
466 | },
|
467 |
|
468 | ClassBody: {
|
469 | exit (astPath: NodePath<t.ClassBody>) {
|
470 | if (!isEntryFile) return
|
471 | const node = astPath.node
|
472 | if (hasComponentDidShow && !hasComponentDidMount) {
|
473 | node.body.push(
|
474 | t.classMethod(
|
475 | 'method',
|
476 | t.identifier('componentDidMount'),
|
477 | [],
|
478 | t.blockStatement([toAst('this.componentDidShow && this.componentDidShow()') as t.Statement]),
|
479 | false,
|
480 | false
|
481 | )
|
482 | )
|
483 | }
|
484 | if (hasComponentDidHide && !hasComponentWillUnmount) {
|
485 | node.body.push(
|
486 | t.classMethod(
|
487 | 'method',
|
488 | t.identifier('componentWillUnmount'),
|
489 | [],
|
490 | t.blockStatement([toAst('this.componentDidHide && this.componentDidHide()') as t.Statement]),
|
491 | false,
|
492 | false
|
493 | )
|
494 | )
|
495 | }
|
496 | if (!hasConstructor) {
|
497 | node.body.unshift(
|
498 | t.classMethod(
|
499 | 'constructor',
|
500 | t.identifier('constructor'),
|
501 | [t.identifier('props'), t.identifier('context')],
|
502 | t.blockStatement([superNode, additionalConstructorNode] as t.Statement[]),
|
503 | false,
|
504 | false
|
505 | )
|
506 | )
|
507 | }
|
508 | }
|
509 | },
|
510 | CallExpression (astPath) {
|
511 | const node = astPath.node
|
512 | const callee = node.callee as t.Identifier
|
513 | const calleeName = callee.name
|
514 | const parentPath = astPath.parentPath
|
515 |
|
516 | if (t.isMemberExpression(callee)) {
|
517 | const object = callee.object as t.Identifier
|
518 | const property = callee.property as t.Identifier
|
519 | if (object.name === taroImportDefaultName && property.name === 'render') {
|
520 | astPath.remove()
|
521 | }
|
522 | } else {
|
523 | if (calleeName === setStoreFuncName) {
|
524 | if (
|
525 | parentPath.isAssignmentExpression() ||
|
526 | parentPath.isExpressionStatement() ||
|
527 | parentPath.isVariableDeclarator()
|
528 | ) {
|
529 | parentPath.remove()
|
530 | }
|
531 | }
|
532 | }
|
533 | }
|
534 | })
|
535 |
|
536 | if (hasJSX) {
|
537 | node.body.unshift(template("import React from 'react'", babylonConfig as any)())
|
538 | }
|
539 |
|
540 | if (taroImportDefaultName) {
|
541 | const importTaro = template(
|
542 | `import ${taroImportDefaultName} from '${PACKAGES['@tarojs/taro-rn']}'`,
|
543 | babylonConfig as any
|
544 | )()
|
545 | node.body.unshift(importTaro as any)
|
546 | }
|
547 |
|
548 | if (isEntryFile) {
|
549 |
|
550 | pages.forEach(item => {
|
551 | const pagePath = item.startsWith('/') ? item : `/${item}`
|
552 | const screenName = _.camelCase(pagePath)
|
553 | const importScreen = template(`import ${screenName} from '.${pagePath}'`, babylonConfig as any)()
|
554 | node.body.unshift(importScreen as any)
|
555 | })
|
556 |
|
557 |
|
558 | iconPaths.forEach(item => {
|
559 | const iconPath = item.startsWith('/') ? item : `/${item}`
|
560 | const iconName = _.camelCase(iconPath)
|
561 | const importIcon = template(`import ${iconName} from '.${iconPath}'`, babylonConfig as any)()
|
562 | node.body.unshift(importIcon as any)
|
563 | })
|
564 |
|
565 |
|
566 | const routerPages = pages
|
567 | .map(item => {
|
568 | const pagePath = item.startsWith('/') ? item : `/${item}`
|
569 | const screenName = _.camelCase(pagePath)
|
570 | return `['${item}',${screenName}]`
|
571 | })
|
572 | .join(',')
|
573 | node.body.push(template(
|
574 | `const RootStack = ${routerImportDefaultName}.initRouter(
|
575 | [${routerPages}],
|
576 | ${taroImportDefaultName},
|
577 | App.config
|
578 | )`,
|
579 | babylonConfig as any
|
580 | )() as any)
|
581 |
|
582 | const initNativeApi = template(
|
583 | `${taroImportDefaultName}.initNativeApi(${taroImportDefaultName})`,
|
584 | babylonConfig as any
|
585 | )()
|
586 | node.body.push(initNativeApi as any)
|
587 |
|
588 |
|
589 | const importTaroRouter = template(
|
590 | `import TaroRouter from '${PACKAGES['@tarojs/taro-router-rn']}'`,
|
591 | babylonConfig as any
|
592 | )()
|
593 | node.body.unshift(importTaroRouter as any)
|
594 |
|
595 |
|
596 | const importTCRNProvider = template(
|
597 | `import { Provider as ${taroComponentsRNProviderName} } from '${PACKAGES['@tarojs/components-rn']}'`,
|
598 | babylonConfig
|
599 | )()
|
600 | node.body.unshift(importTCRNProvider)
|
601 |
|
602 |
|
603 | node.body.push(getInitPxTransformNode(projectConfig) as any)
|
604 |
|
605 |
|
606 | if (!hasAppExportDefault) {
|
607 | const appExportDefault = template(`export default ${componentClassName}`, babylonConfig as any)()
|
608 | node.body.push(appExportDefault as any)
|
609 | }
|
610 | }
|
611 | }
|
612 | }
|
613 | })
|
614 | const constantsReplaceList = Object.assign(
|
615 | {
|
616 | 'process.env.TARO_ENV': 'rn'
|
617 | },
|
618 | generateEnvList(projectConfig.env || {}),
|
619 | generateConstantsList(projectConfig.defineConstants || {})
|
620 | )
|
621 |
|
622 |
|
623 | const plugins = [
|
624 | [require('babel-plugin-transform-jsx-to-stylesheet'), { filePath }],
|
625 | [require('babel-plugin-danger-remove-unused-import'), { ignore: ['@tarojs/taro', 'react', 'react-native', 'nervjs'] }],
|
626 | [require('babel-plugin-transform-define').default, constantsReplaceList]
|
627 | ]
|
628 |
|
629 |
|
630 |
|
631 | const newBabelConfig = Object.assign({}, { plugins })
|
632 |
|
633 | ast = babel.transformFromAst(ast, code, newBabelConfig).ast
|
634 |
|
635 | return {
|
636 | code: unescape(generate(ast).code.replace(/\\u/g, '%u')),
|
637 | styleFiles
|
638 | }
|
639 | }
|