|
| 1 | +/** |
| 2 | + * Inspired By https://github.com/benjycui/bisheng/blob/master/packages/bisheng-plugin-react/lib/transformer.js |
| 3 | + */ |
| 4 | + |
| 5 | +const babel = require('@babel/core') |
| 6 | +const types = require('@babel/types'); |
| 7 | +const generator = require('@babel/generator').default; |
| 8 | +const traverse = require('@babel/traverse').default; |
| 9 | +const babelConfig = require('../../../babel.config') |
| 10 | + |
| 11 | +// babelConfig = babelConfig({env: () => ''}) |
| 12 | +// babelConfig.presets[0][1].modules = 'commonjs' |
| 13 | + |
| 14 | +function requireGenerator(varName, moduleName) { |
| 15 | + return types.variableDeclaration('var', [ |
| 16 | + types.variableDeclarator( |
| 17 | + types.identifier(varName), |
| 18 | + types.callExpression(types.identifier('require'), [ |
| 19 | + types.stringLiteral(moduleName), |
| 20 | + ]), |
| 21 | + ), |
| 22 | + ]); |
| 23 | +} |
| 24 | + |
| 25 | + |
| 26 | + |
| 27 | +module.exports = function generate(source) { |
| 28 | + const { |
| 29 | + ast: codeAst |
| 30 | + } = babel.transformSync(source, { |
| 31 | + ast: true, |
| 32 | + code: false, |
| 33 | + filename: 'hackFile.js', |
| 34 | + ...babelConfig |
| 35 | + }) |
| 36 | + |
| 37 | + let renderReturn = null; |
| 38 | + traverse(codeAst, { |
| 39 | + CallExpression(callPath) { |
| 40 | + const callPathNode = callPath.node; |
| 41 | + if ( |
| 42 | + callPathNode.callee && |
| 43 | + callPathNode.callee.object && |
| 44 | + callPathNode.callee.object.name === 'ReactDOM' && |
| 45 | + callPathNode.callee.property && |
| 46 | + callPathNode.callee.property.name === 'render' |
| 47 | + ) { |
| 48 | + renderReturn = types.returnStatement(callPathNode.arguments[0]); |
| 49 | + |
| 50 | + callPath.remove(); |
| 51 | + } |
| 52 | + }, |
| 53 | + }); |
| 54 | + |
| 55 | + const astProgramBody = codeAst.program.body; |
| 56 | + // if (!noreact) { |
| 57 | + astProgramBody.unshift(requireGenerator('ReactDOM', 'react-dom')); |
| 58 | + astProgramBody.unshift(requireGenerator('React', 'react')); |
| 59 | + // } |
| 60 | + // ReactDOM.render always at the last of preview method |
| 61 | + if (renderReturn) { |
| 62 | + astProgramBody.push(renderReturn); |
| 63 | + } |
| 64 | + |
| 65 | + const codeBlock = types.BlockStatement(astProgramBody); |
| 66 | + const previewFunction = types.functionDeclaration( |
| 67 | + types.Identifier('MarkdownSFC'), |
| 68 | + [], |
| 69 | + codeBlock, |
| 70 | + ); |
| 71 | + |
| 72 | + return generator(types.program([previewFunction]), {}, source).code; |
| 73 | +} |
0 commit comments