Skip to content

Commit

Permalink
feat(okam-build): add native swan component event handler adapter in …
Browse files Browse the repository at this point in the history
…okam
  • Loading branch information
wuhy committed Nov 7, 2018
1 parent dcb119d commit 410dbda
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 18 deletions.
25 changes: 17 additions & 8 deletions packages/okam-build/lib/build/BuildManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,6 @@ class BuildManager extends EventEmitter {
}

initProcessor(buildConf) {
if (this.appType === 'swan' && buildConf.wx2swan) {
// register wx2swan processors
require('./init-wx2swan-processor')(buildConf.wx2swan);
}

// register custom processors
processor.registerProcessor(buildConf.processors);

Expand All @@ -64,6 +59,20 @@ class BuildManager extends EventEmitter {
extnames: componentConf.extname
}]);
}

if (this.appType === 'swan') {
// register native swan processor
let nativeOpts = buildConf.native;
if (nativeOpts !== false) {
require('./init-native-swan-processor')(nativeOpts);
}

// register wx2swan processors
let wx2swanOpts = buildConf.wx2swan;
if (wx2swanOpts) {
require('./init-wx2swan-processor')(wx2swanOpts);
}
}
}

/**
Expand All @@ -84,12 +93,12 @@ class BuildManager extends EventEmitter {
let {rules: baseRules, processors: baseProcessors} = buildConf;
let {rules, processors} = extraConf || {};

rules && (rules = [].concat(baseRules, rules));
this.rules = rules || baseRules || [];

processors && (processors = merge({}, baseProcessors, processors));
buildConf.processors = processors || baseProcessors;
this.initProcessor(buildConf);

rules && (rules = [].concat(baseRules, rules));
this.rules = rules || baseRules || [];
}

/**
Expand Down
48 changes: 48 additions & 0 deletions packages/okam-build/lib/build/init-native-swan-processor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* @file Native swan support processor initialization
* @author [email protected]
*/

'use strict';

const {registerProcessor} = require('../processor/type');
const adapterPlugin = require('../processor/js/plugins/babel-native-swan-plugin');

/**
* Initialize native component js processor
*
* @inner
* @param {Object=} opts the options to init
* @param {string=} opts.processor the builtin processor name, by default `babel`
* @param {Array=} opts.plugins the processor plugins
*/
function initJsProcessor(opts) {
let plugins = (opts && opts.plugins) || [adapterPlugin];
registerProcessor({
name: (opts && opts.processor) || 'babel', // override existed processor
hook: {
before(file, options) {
if (file.isSwanCompScript && !adapterPlugin.isAdapterModule(file.path)) {
options.plugins || (options.plugins = []);
options.plugins.push.apply(options.plugins, plugins);
}
}
}
});
}

/**
* Init native transformation processors
*
* @param {Object=} options the initialization options
* @param {Object=} options.js the component js processor init options
*/
function initProcessor(options = {}) {
let {js} = options;

if (js !== false) {
initJsProcessor(js);
}
}

module.exports = initProcessor;
5 changes: 3 additions & 2 deletions packages/okam-build/lib/build/init-wx2swan-processor.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const {registerProcessor} = require('../processor/type');
const wxmlPlugin = require('../processor/template/plugins/wx2swan-syntax-plugin');
const wxssPlugin = require('../processor/css/plugins/postcss-plugin-wx2swan');
const jsPlugin = require('../processor/js/plugins/babel-wx2swan-plugin');
const adapterPlugin = require('../processor/js/plugins/babel-native-swan-plugin');

/**
* Initialize wx component js processor
Expand All @@ -19,12 +20,12 @@ const jsPlugin = require('../processor/js/plugins/babel-wx2swan-plugin');
* @param {Array=} opts.plugins the processor plugins
*/
function initJsProcessor(opts) {
let plugins = (opts && opts.plugins) || [jsPlugin];
let plugins = (opts && opts.plugins) || [jsPlugin, adapterPlugin];
registerProcessor({
name: (opts && opts.processor) || 'babel', // override existed processor
hook: {
before(file, options) {
if (file.isWxCompScript) {
if (file.isWxCompScript && !adapterPlugin.isAdapterModule(file.path)) {
options.plugins || (options.plugins = []);
options.plugins.push.apply(options.plugins, plugins);
}
Expand Down
28 changes: 27 additions & 1 deletion packages/okam-build/lib/config/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,37 @@ module.exports = {

/**
* 是否启用微信组件转换成 swan 组件处理,可选,默认 false
* 可以传入对象,控制各个部分转换选项
* {
* js: {
* plugins: [], // babel plugins using,重写内部使用的 plugins
* processor: 'babel' // 使用的 babel 处理器,默认 babel(即 babel6),
* // 如果整个项目转换使用 babel7,这里改成 babel7
* },
* tpl: {}, // 模板转换选项,具体可以参考模板处理器选项
* css: {}, // 样式转换选项,具体可以参考 postcss 处理器选项
* }
*
* @type {boolean}
* @type {boolean|Object}
*/
wx2swan: false,

/**
* 是否启用原生转换处理,可选,默认 true。
* 当前主要用在 swan 原生支持上适配 okam。
* 也可以传入配置对象:
* {
* js: {
* plugins: [], // babel plugins using,重写内部使用的 plugins
* processor: 'babel' // 使用的 babel 处理器,默认 babel(即 babel6),
* // 如果整个项目转换使用 babel7,这里改成 babel7
* }
* }
*
* @type {boolean|Object}
*/
native: true,

/**
* 自定义的构建处理器
*
Expand Down
10 changes: 9 additions & 1 deletion packages/okam-build/lib/processor/helper/processor.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ const BUILTIN_PROCESSORS = require('../type').BUILTIN_PROCESSORS;
const initBabelProcessorOptions = require('./init-babel');
const initViewProcessorOptions = require('./init-view');

/**
* The default babel processor to use
*
* @const
* @type {string}
*/
const DEFAULT_BABEL_PROCESSOR = 'babel';

function hasBabelProcessor(processorName) {
return (processorName === 'babel'
|| processorName === 'babel7'
Expand Down Expand Up @@ -196,7 +204,7 @@ function addScriptDefaultBabelProcessor(file, buildManager, processors) {
if (!hasBabel) {
processors.unshift(
getBuiltinProcessor(
file, {name: 'babel', options: {}}, buildManager
file, {name: DEFAULT_BABEL_PROCESSOR, options: {}}, buildManager
)
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**
* @file Native swan component transformation plugin.
* Fix component triggerEvent API to adapt the okam event handler.
* @author [email protected]
*/

'use strict';

const {isVariableDefined, createImportDeclaration} = require('../transform/helper');

/**
* The component polyfill module id
*
* @const
* @type {string}
*/
const COMPONENT_ADAPTER_MODULE_ID = 'okam-core/src/swan/adapter/component';

module.exports = exports = function ({types: t}) {
return {
visitor: {

/**
* Replace native component init
*
* @param {Object} path ast node path
* @param {Object} state the processed node state
*/
CallExpression(path, state) {
if (path.isComponentAdapted) {
return;
}

let {arguments: args, callee} = path.node;
const calleeName = callee.name;
if (!t.isIdentifier(callee) || args.length !== 1) {
return;
}

if (calleeName === 'Component') {
if (isVariableDefined(path, calleeName)) {
return;
}

let rootPath = path.findParent(p => t.isProgram(p));
let bodyPath = rootPath.get('body.0');

// insert the component fix import statement
const fixComponentFuncName = path.scope.generateUid('fixComponent');
bodyPath.insertBefore(
createImportDeclaration(
fixComponentFuncName, COMPONENT_ADAPTER_MODULE_ID, t
)
);

path.replaceWith(t.callExpression(
t.identifier(calleeName),
[
t.callExpression(
t.identifier(fixComponentFuncName),
args
)
]
));

// add flag to avoid repeat visiting
path.isComponentAdapted = true;
}
},

/**
* Replace `triggerEvent` API with custom `$emit` API
*
* @param {Object} path ast node path
* @param {Object} state the processed node state
*/
MemberExpression(path, state) {
let {property} = path.node;
if (t.isIdentifier(property) && property.name === 'triggerEvent') {
property.name = '$emit';
return;
}
}
}
};
};

exports.adapterModuleId = COMPONENT_ADAPTER_MODULE_ID;

exports.isAdapterModule = function (path) {
return path.indexOf(COMPONENT_ADAPTER_MODULE_ID) !== -1;
};
23 changes: 17 additions & 6 deletions packages/okam-build/lib/processor/js/transform/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ function getPlainObjectNodeValue(node, path, t) {
/**
* Create require variable declaration statement
*
* @param {string} varName the varialble name
* @param {string} varName the variable name
* @param {string} requireId the required id
* @param {Object} t the babel type definition
* @return {Object}
Expand All @@ -86,7 +86,7 @@ exports.createRequireVarDeclaration = function (varName, requireId, t) {
/**
* Create import declaration statement
*
* @param {string|Array.<string>} varName the varialble name to export
* @param {string|Array.<string>} varName the variable name to export
* @param {string} requireId the required id
* @param {Object} t the babel type definition
* @return {Object}
Expand Down Expand Up @@ -186,8 +186,8 @@ exports.normalizeInternalBehavior = normalizeInternalBehavior;
* @param {string} type the comment type
*/
function removeComments(t, path, type) {
let commmentPaths = path.get(type);
if (!commmentPaths || !commmentPaths.length) {
let commentPaths = path.get(type);
if (!commentPaths || !commentPaths.length) {
return;
}

Expand All @@ -200,12 +200,12 @@ function removeComments(t, path, type) {
if (isParentProgram) {
parentPath.addComments(
'leading',
commmentPaths.map(item => item.node)
commentPaths.map(item => item.node)
);
}
}

commmentPaths.forEach(item => item.remove());
commentPaths.forEach(item => item.remove());
}

exports.removeComments = removeComments;
Expand Down Expand Up @@ -244,3 +244,14 @@ exports.removeNode = function (t, path, commentsRemoveOpts = {}) {
* @return {Object}
*/
exports.getPlainObjectNodeValue = getPlainObjectNodeValue;

/**
* Check whether the given variable name is defined in its scope
*
* @param {Object} path the variable used path
* @param {string} varName the variable name
* @return {boolean}
*/
exports.isVariableDefined = function (path, varName) {
return path.scope.hasBinding(varName);
};

0 comments on commit 410dbda

Please sign in to comment.