UNPKG

5.29 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = traverseImport;
7
8var _babylon = require('babylon');
9
10var babylon = _interopRequireWildcard(_babylon);
11
12var _babelTraverse = require('babel-traverse');
13
14var _babelTraverse2 = _interopRequireDefault(_babelTraverse);
15
16var _babelTypes = require('babel-types');
17
18var types = _interopRequireWildcard(_babelTypes);
19
20var _babelGenerator = require('babel-generator');
21
22var _babelGenerator2 = _interopRequireDefault(_babelGenerator);
23
24var _babelCodeFrame = require('babel-code-frame');
25
26var _babelCodeFrame2 = _interopRequireDefault(_babelCodeFrame);
27
28function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
30function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
31
32/* eslint-disable new-cap */
33
34function traverseImport(options, inputSource, sourceMapOption) {
35 var specified = void 0; // Collector import specifiers
36 var hasPlatformSpecified = false;
37
38 var platformMap = {
39 weex: 'isWeex',
40 web: 'isWeb',
41 node: 'isNode',
42 reactnative: 'isReactNative'
43 };
44
45 /**
46 * generator variable expression
47 *
48 * @param {string} name identifier
49 * @param {boolean} value
50 * @return {VariableDeclaration}
51 * @example
52 * variableDeclarationMethod('isWeex', true)
53 *
54 * const isWeex = true;
55 */
56 function variableDeclarationMethod(name, value) {
57 return types.VariableDeclaration('const', [types.variableDeclarator(types.Identifier(name), types.BooleanLiteral(value))]);
58 }
59
60 /**
61 * generator object expression
62 *
63 * @param {string} platformName specified platform value it true
64 * @return {objectExpression}
65 * @example
66 * objectExpressionMethod('isWeex')
67 *
68 * {
69 * isWeex: true,
70 * isWeb: false
71 * }
72 */
73 function objectExpressionMethod(platformName) {
74 var properties = [];
75
76 Object.keys(platformMap).forEach(function (p) {
77 properties.push(types.objectProperty(types.Identifier(platformMap[p]), types.booleanLiteral(p === platformName)));
78 });
79
80 return types.objectExpression(properties);
81 }
82
83 var ast = void 0;
84
85 try {
86 ast = babylon.parse(inputSource, {
87 sourceType: 'module',
88 plugins: ['*']
89 });
90 } catch (err) {
91 if (err instanceof SyntaxError) {
92 err.lineNumber = err.loc.line;
93 err.column = err.loc.column + 1;
94
95 // remove trailing "(LINE:COLUMN)" acorn message and add in esprima syntax error message start
96 err.message = 'Line ' + err.lineNumber + ': ' + err.message.replace(/ \((\d+):(\d+)\)$/, '') +
97 // add codeframe
98 '\n\n' + (0, _babelCodeFrame2.default)(inputSource, err.lineNumber, err.column, { highlightCode: true });
99 }
100
101 throw err;
102 }
103
104 (0, _babelTraverse2.default)(ast, {
105 enter: function enter() {
106 specified = new Array();
107
108 if (typeof platformMap[options.platform] !== 'undefined') {
109 hasPlatformSpecified = true;
110 }
111 },
112
113 // Support commonjs method `require`
114 CallExpression: function CallExpression(path) {
115 var node = path.node;
116
117
118 if (hasPlatformSpecified && node.callee.name === 'require' && node.arguments[0] && -1 !== options.name.indexOf(node.arguments[0].value)) {
119 path.replaceWith(objectExpressionMethod(options.platform));
120 }
121 },
122 ImportDeclaration: function ImportDeclaration(path) {
123 var node = path.node;
124
125
126 if (-1 !== options.name.indexOf(node.source.value)) {
127 node.specifiers.forEach(function (spec) {
128 if (spec.type === 'ImportNamespaceSpecifier') {
129 specified.push({
130 local: spec.local.name,
131 imported: '*'
132 });
133 } else {
134 specified.push({
135 local: spec.local.name,
136 imported: spec.imported.name
137 });
138 }
139 });
140
141 if (hasPlatformSpecified) {
142 specified.forEach(function (specObj) {
143 if (specObj.imported === '*') {
144 path.insertAfter(types.VariableDeclaration('const', [types.variableDeclarator(types.Identifier(specObj.local), objectExpressionMethod(options.platform))]));
145 } else {
146 var newNodeInit = specObj.imported === platformMap[options.platform] ? true : false;
147 var newNode = variableDeclarationMethod(specObj.imported, newNodeInit);
148
149 path.insertAfter(newNode);
150
151 // Support custom alise import:
152 // import { isWeex as iw } from 'universal-env';
153 // const isWeex = true;
154 // const iw = true;
155 if (specObj.imported !== specObj.local) {
156 newNode = variableDeclarationMethod(specObj.local, newNodeInit);
157 path.insertAfter(newNode);
158 }
159 }
160 });
161
162 path.remove();
163 }
164 }
165 }
166 });
167
168 return (0, _babelGenerator2.default)(ast, Object.assign({
169 sourceMaps: true,
170 sourceFileName: 'inline',
171 sourceMapTarget: 'inline'
172 }, sourceMapOption), inputSource);
173};
174module.exports = exports['default'];
\No newline at end of file