Merge branch 'weex-loader-simplify' into weex-loader-element
diff --git a/weex-loader/.gitignore b/weex-loader/.gitignore
index b512c09..9730c19 100644
--- a/weex-loader/.gitignore
+++ b/weex-loader/.gitignore
@@ -1 +1,4 @@
-node_modules
\ No newline at end of file
+node_modules
+
+test/actual
+test/expect/*.js
diff --git a/weex-loader/index.js b/weex-loader/index.js
index 45e884f..a4b96d7 100644
--- a/weex-loader/index.js
+++ b/weex-loader/index.js
@@ -16,16 +16,18 @@
 var MODULE_EXPORTS_REG = /module\.exports/g;
 var REQUIRE_REG = /require\((["'])(\@weex\-module\/[^\)\1]+)\1\)/g;
 
-function parseScript(loader, params, source, config, data) {
+function parseScript(loader, params, source, config, data, elementName, elements) {
+    elements = elements || []
+
     if (!scripter) {
         return Promise.reject('please use a script parser. e.g. weex-scripter');
     }
 
     var target = scripter.fix(source);
-    var name = params.resourceQuery.name || 
+    var name = elementName || params.resourceQuery.name ||
                     path.basename(params.resourcePath).replace(/\..*$/, '');
 
-    if (params.resourceQuery.entry === true) {
+    if (!elementName && params.resourceQuery.entry === true) {
         name = md5(source);
     }
 
@@ -36,12 +38,14 @@
                 'function(__weex_require__, __weex_exports__, __weex_module__)' + 
                 '{\n' + target + '\n})';
 
-    if (params.resourceQuery.entry === true) {
+    if (!elementName && params.resourceQuery.entry === true) {
         target += '\n;__weex_bootstrap__("@weex-component/' + name + '", ' + 
                     String(config) + ',' + 
                     String(data) + ')';
     }
 
+    target = elements.concat(target).join(';\n\n')
+
     return Promise.resolve(target);
 }
 
@@ -122,9 +126,9 @@
     });
 }
 
-function parseWeexFile(loader, params, source) {
+function parseWeexFile(loader, params, source, deps, elementName) {
     var results;
-    var deps = [];
+    deps = deps || [];
 
     return new Promise(function(resolve, reject) {
         blocker.format(source, function(err, ret) {
@@ -136,24 +140,32 @@
             }
         });
     }).then(function() {
-        var promises = [Promise.resolve(), Promise.resolve()];
+        var promises = [Promise.resolve(), Promise.resolve(), Promise.resolve()];
         var content;
-
+        if (results.elements) {
+            var elPromises = []
+            Object.keys(results.elements).forEach(function (key) {
+                var el = results.elements[key];
+                elPromises.push(parseWeexFile(loader, params, el.content, deps, el.name));
+            });
+            promises[0] = Promise.all(elPromises);
+        }
         if (results.template) {
             content = results.template.content;
-            promises[0] = parseTemplate(loader, params, content, deps);
+            promises[1] = parseTemplate(loader, params, content, deps);
         }
         if (results.styles) {
             content = results.styles.reduce(function(pre, cur) {
                 return pre + '\n' + cur.content;
             }, '');
-            promises[1] = parseStyle(loader, params, content);
+            promises[2] = parseStyle(loader, params, content);
         }
 
         return Promise.all(promises);
     }).then(function(ret) {
-        var template = ret[0];
-        var style = ret[1];
+        var elements = ret[0] || [];
+        var template = ret[1];
+        var style = ret[2];
 
         var content = '';
         var config = {};
@@ -174,7 +186,6 @@
                     return '';
                 }
             }).join('\n');
-
             content = requireContent + '\n' + content;
         }
 
@@ -198,8 +209,7 @@
             data = new Function('return ' + results.data.content.replace(/\n/g, ''))();
             data = JSON.stringify(data, null, ' ');
         }
-        
-        return parseScript(loader, params, content, config, data);
+        return parseScript(loader, params, content, config, data, elementName, elements);
     });
 }
 
@@ -248,7 +258,6 @@
             type === 'html' || type === 'tpl' || type === 'template') {
             result = 'module.exports=' + result;
         }
-        // console.log('\n[' + type + ', ' + params.resourcePath + ']\n', source, '\n=========>\n', result + '\n');
         callback(null, result);
     }).catch(function(err) {
         self.emitError(err.toString());
diff --git a/weex-loader/package.json b/weex-loader/package.json
index a50ccc6..3911e54 100644
--- a/weex-loader/package.json
+++ b/weex-loader/package.json
@@ -16,7 +16,7 @@
     "transformer"
   ],
   "scripts": {
-    "test:build": "webpack --config webpack.config.js",
+    "test:build": "webpack --config test/webpack.config.js",
     "test:transform": "transformer test/expect/*.we -o test/expect",
     "test:mocha": "mocha --compilers js:babel-core/register test/test.js",
     "test": "npm run test:build && npm run test:transform && npm run test:mocha",
diff --git a/weex-loader/test/actual/a.js b/weex-loader/test/actual/a.js
deleted file mode 100644
index 54970b2..0000000
--- a/weex-loader/test/actual/a.js
+++ /dev/null
@@ -1,269 +0,0 @@
-/******/ (function(modules) { // webpackBootstrap
-/******/ 	// The module cache
-/******/ 	var installedModules = {};
-
-/******/ 	// The require function
-/******/ 	function __webpack_require__(moduleId) {
-
-/******/ 		// Check if module is in cache
-/******/ 		if(installedModules[moduleId])
-/******/ 			return installedModules[moduleId].exports;
-
-/******/ 		// Create a new module (and put it into the cache)
-/******/ 		var module = installedModules[moduleId] = {
-/******/ 			exports: {},
-/******/ 			id: moduleId,
-/******/ 			loaded: false
-/******/ 		};
-
-/******/ 		// Execute the module function
-/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-
-/******/ 		// Flag the module as loaded
-/******/ 		module.loaded = true;
-
-/******/ 		// Return the exports of the module
-/******/ 		return module.exports;
-/******/ 	}
-
-
-/******/ 	// expose the modules object (__webpack_modules__)
-/******/ 	__webpack_require__.m = modules;
-
-/******/ 	// expose the module cache
-/******/ 	__webpack_require__.c = installedModules;
-
-/******/ 	// __webpack_public_path__
-/******/ 	__webpack_require__.p = "";
-
-/******/ 	// Load entry module and return exports
-/******/ 	return __webpack_require__(0);
-/******/ })
-/************************************************************************/
-/******/ ([
-/* 0 */
-/***/ function(module, exports, __webpack_require__) {
-
-	;__weex_define__("@weex-component/50c4a966770a11c745d1edbe468d1d01", [], function(__weex_require__, __weex_exports__, __weex_module__){
-	'use strict';
-
-	__webpack_require__(1);
-	__webpack_require__(3);
-
-	var c = __webpack_require__(7);
-
-	__weex_module__.exports = {
-	    data: function () {return {
-	        text: 'Hello ' + c.name
-	    }}
-	};
-
-	__weex_module__.exports.style = __webpack_require__(8);
-	__weex_module__.exports.template = __webpack_require__(9);
-	})
-	;__weex_bootstrap__("@weex-component/50c4a966770a11c745d1edbe468d1d01", {"transformerVersion":"0.3.1"},undefined)
-
-/***/ },
-/* 1 */
-/***/ function(module, exports, __webpack_require__) {
-
-	;__weex_define__("@weex-component/goto", [], function(__weex_require__, __weex_exports__, __weex_module__){
-	'use strict';
-
-	var _b = __webpack_require__(2);
-
-	var _b2 = _interopRequireDefault(_b);
-
-	var _event = __weex_require__('@weex-module/event');
-
-	var event = _interopRequireWildcard(_event);
-
-	function _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; } }
-
-	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-	__weex_module__.exports = {
-	    data: function () {return {
-	        text: '',
-	        paddingLeft: 20
-	    }},
-	    template: _b2.default,
-	    created: function created() {
-	        this.text = 'Yes It is! Go Weex >>>';
-	    },
-
-	    methods: {
-	        clicked: function clicked() {
-	            event.openURL('https://github.com/alibaba/weex_toolchain');
-	        }
-	    }
-	};
-	})
-
-/***/ },
-/* 2 */
-/***/ function(module, exports) {
-
-	module.exports={
-	  "type": "container",
-	  "children": [
-	    {
-	      "type": "text",
-	      "events": {
-	        "click": "clicked"
-	      },
-	      "style": {
-	        "textDecoration": "underline",
-	        "paddingLeft": function () {return this.paddingLeft}
-	      },
-	      "attr": {
-	        "value": function () {return this.text}
-	      }
-	    }
-	  ]
-	}
-
-/***/ },
-/* 3 */
-/***/ function(module, exports, __webpack_require__) {
-
-	;__weex_define__("@weex-component/copyright", [], function(__weex_require__, __weex_exports__, __weex_module__){
-
-	;
-	    __webpack_require__(4);
-
-	    __weex_module__.exports = {
-	        data: function () {return {
-	            className: ''
-	        }},
-	        created: function (argument) {
-	            this.className = 'copyright';
-	        }
-	    }
-
-	    __weex_module__.exports.style = __webpack_require__(6)
-
-	;__weex_module__.exports.template = __weex_module__.exports.template || {}
-	;Object.assign(__weex_module__.exports.template, {
-	  "type": "container",
-	  "children": [
-	    {
-	      "type": "text",
-	      "classList": function () {return [this.className, 'highlight']},
-	      "attr": {
-	        "value": "Copy right @ 2016 Weex"
-	      }
-	    },
-	    {
-	      "type": "company"
-	    }
-	  ]
-	})
-	;__weex_module__.exports.style = __weex_module__.exports.style || {}
-	;Object.assign(__weex_module__.exports.style, {
-	  "copyright": {
-	    "textAlign": "center",
-	    "paddingTop": 20,
-	    "paddingBottom": 20
-	  }
-	})
-	})
-
-/***/ },
-/* 4 */
-/***/ function(module, exports, __webpack_require__) {
-
-	;__weex_define__("@weex-component/company", [], function(__weex_require__, __weex_exports__, __weex_module__){
-
-	;
-	var d = __webpack_require__(5);
-	__weex_module__.exports = {
-	    data: function () {return {
-	        name: d.name
-	    }}
-	}
-
-	;__weex_module__.exports.template = __weex_module__.exports.template || {}
-	;Object.assign(__weex_module__.exports.template, {
-	  "type": "container",
-	  "children": [
-	    {
-	      "type": "text",
-	      "style": {
-	        "textAlign": "center",
-	        "fontSize": 18,
-	        "color": "#CCCCCC"
-	      },
-	      "attr": {
-	        "value": function () {return this.name}
-	      }
-	    }
-	  ]
-	})
-	})
-
-/***/ },
-/* 5 */
-/***/ function(module, exports) {
-
-	exports.name = 'Alibaba Group';
-
-/***/ },
-/* 6 */
-/***/ function(module, exports) {
-
-	module.exports={
-	  "highlight": {
-	    "color": "#666666",
-	    "fontSize": 26
-	  }
-	}
-
-/***/ },
-/* 7 */
-/***/ function(module, exports) {
-
-	exports.name = 'Weex-Loader';
-
-/***/ },
-/* 8 */
-/***/ function(module, exports) {
-
-	module.exports={
-	  "h1": {
-	    "fontSize": 60,
-	    "color": "#FF0000",
-	    "paddingTop": 20,
-	    "paddingBottom": 20,
-	    "paddingLeft": 20,
-	    "paddingRight": 20
-	  }
-	}
-
-/***/ },
-/* 9 */
-/***/ function(module, exports) {
-
-	module.exports={
-	  "type": "container",
-	  "children": [
-	    {
-	      "type": "text",
-	      "classList": [
-	        "h1"
-	      ],
-	      "attr": {
-	        "value": function () {return this.text}
-	      }
-	    },
-	    {
-	      "type": "goto"
-	    },
-	    {
-	      "type": "copyright"
-	    }
-	  ]
-	}
-
-/***/ }
-/******/ ]);
\ No newline at end of file
diff --git a/weex-loader/test/actual/z.js b/weex-loader/test/actual/z.js
deleted file mode 100644
index 24dfa40..0000000
--- a/weex-loader/test/actual/z.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/******/ (function(modules) { // webpackBootstrap
-/******/ 	// The module cache
-/******/ 	var installedModules = {};
-
-/******/ 	// The require function
-/******/ 	function __webpack_require__(moduleId) {
-
-/******/ 		// Check if module is in cache
-/******/ 		if(installedModules[moduleId])
-/******/ 			return installedModules[moduleId].exports;
-
-/******/ 		// Create a new module (and put it into the cache)
-/******/ 		var module = installedModules[moduleId] = {
-/******/ 			exports: {},
-/******/ 			id: moduleId,
-/******/ 			loaded: false
-/******/ 		};
-
-/******/ 		// Execute the module function
-/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-
-/******/ 		// Flag the module as loaded
-/******/ 		module.loaded = true;
-
-/******/ 		// Return the exports of the module
-/******/ 		return module.exports;
-/******/ 	}
-
-
-/******/ 	// expose the modules object (__webpack_modules__)
-/******/ 	__webpack_require__.m = modules;
-
-/******/ 	// expose the module cache
-/******/ 	__webpack_require__.c = installedModules;
-
-/******/ 	// __webpack_public_path__
-/******/ 	__webpack_require__.p = "";
-
-/******/ 	// Load entry module and return exports
-/******/ 	return __webpack_require__(0);
-/******/ })
-/************************************************************************/
-/******/ ([
-/* 0 */
-/***/ function(module, exports) {
-
-	;__weex_define__("@weex-component/465f098187d45d0bb4e7c097ac00091e", [], function(__weex_require__, __weex_exports__, __weex_module__){
-
-	;__weex_module__.exports.template = __weex_module__.exports.template || {}
-	;Object.assign(__weex_module__.exports.template, {
-	  "type": "div"
-	})
-	})
-	;__weex_bootstrap__("@weex-component/465f098187d45d0bb4e7c097ac00091e", {
-	  "downgrade": {
-	    "ios": {
-	      "appVersion": ">=13.0.0"
-	    },
-	    "android": {
-	      "appVersion": "<=0.0.0"
-	    }
-	  },
-	  "transformerVersion": "0.3.1"
-	},{
-	 "a": 1,
-	 "b": 2
-	})
-
-/***/ }
-/******/ ]);
\ No newline at end of file
diff --git a/weex-loader/test/expect/a.js b/weex-loader/test/expect/a.js
deleted file mode 100644
index 91061e5..0000000
--- a/weex-loader/test/expect/a.js
+++ /dev/null
@@ -1,175 +0,0 @@
-browserifyRequire=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof browserifyRequire=="function"&&browserifyRequire;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof browserifyRequire=="function"&&browserifyRequire;for(var o=0;o<r.length;o++)s(r[o]);return s})({"2f45f2510f12e10f1ea5a8ee68e880cd":[function(require,module,exports){
-exports.name = 'Alibaba Group';
-},{}],"4302c316e5980c159f273a3b5da112b5":[function(require,module,exports){
-exports.name = 'Weex-Loader';
-},{}]},{},[]);
-
-
-define('@weex-component/company', function (require, exports, module) {
-
-;
-var d = browserifyRequire("2f45f2510f12e10f1ea5a8ee68e880cd");
-module.exports = {
-    data: function () {return {
-        name: d.name
-    }}
-}
-
-
-;module.exports.style = {}
-
-;module.exports.template = {
-  "type": "container",
-  "children": [
-    {
-      "type": "text",
-      "style": {
-        "textAlign": "center",
-        "fontSize": 18,
-        "color": "#CCCCCC"
-      },
-      "attr": {
-        "value": function () {return this.name}
-      }
-    }
-  ]
-}
-
-;})
-
-// module
-
-define('@weex-component/copyright', function (require, exports, module) {
-
-;
-    module.exports = {
-        data: function () {return {
-            className: ''
-        }},
-        created: function (argument) {
-            this.className = 'copyright';
-        }
-    }
-
-
-;module.exports.style = {
-  "copyright": {
-    "textAlign": "center",
-    "paddingTop": 20,
-    "paddingBottom": 20,
-    "color": "#666666",
-    "fontSize": 26
-  }
-}
-
-;module.exports.template = {
-  "type": "container",
-  "children": [
-    {
-      "type": "text",
-      "classList": function () {return [this.className]},
-      "attr": {
-        "value": "Copy right @ 2016 Weex"
-      }
-    },
-    {
-      "type": "company"
-    }
-  ]
-}
-
-;})
-
-// module
-
-define('@weex-component/goto', function (require, exports, module) {
-
-;
-    module.exports = {
-        data: function () {return {
-            text: '',
-            paddingLeft: 20
-        }},
-        created: function() {
-            this.text = 'Yes It is! Go Weex >>>';
-        },
-        methods: {
-            clicked: function() {
-                this.$openURL('http://github.com/alibaba/weex');
-            }
-        }
-    }
-
-
-;module.exports.style = {}
-
-;module.exports.template = {
-  "type": "container",
-  "children": [
-    {
-      "type": "text",
-      "events": {
-        "click": "clicked"
-      },
-      "style": {
-        "textDecoration": "underline",
-        "paddingLeft": function () {return this.paddingLeft}
-      },
-      "attr": {
-        "value": function () {return this.text}
-      }
-    }
-  ]
-}
-
-;})
-
-// module
-
-define('@weex-component/a', function (require, exports, module) {
-
-;
-var c = browserifyRequire("4302c316e5980c159f273a3b5da112b5")
-module.exports = {
-    data: function () {return {
-        text: 'Hello ' + c.name
-    }}
-}
-
-
-;module.exports.style = {
-  "h1": {
-    "fontSize": 60,
-    "color": "#FF0000",
-    "paddingTop": 20,
-    "paddingBottom": 20,
-    "paddingLeft": 20,
-    "paddingRight": 20
-  }
-}
-
-;module.exports.template = {
-  "type": "container",
-  "children": [
-    {
-      "type": "text",
-      "classList": [
-        "h1"
-      ],
-      "attr": {
-        "value": function () {return this.text}
-      }
-    },
-    {
-      "type": "goto"
-    },
-    {
-      "type": "copyright"
-    }
-  ]
-}
-
-;})
-
-// require module
-bootstrap('@weex-component/a', {"transformerVersion":"0.3.1"})
\ No newline at end of file
diff --git a/weex-loader/test/expect/b.we b/weex-loader/test/expect/b.we
new file mode 100644
index 0000000..0c1855b
--- /dev/null
+++ b/weex-loader/test/expect/b.we
@@ -0,0 +1,19 @@
+<element name="y">
+  <template>
+    <div>
+      <item></item>
+      <text>y</text>
+    </div>
+  </template>
+</element>
+
+<template>
+  <div>
+    <text>Hello</text>
+    <y></y>
+  </div>
+</template>
+
+<script>
+  require('../lib/3rd.js')
+</script>
diff --git a/weex-loader/test/expect/company.js b/weex-loader/test/expect/company.js
deleted file mode 100644
index 685cacc..0000000
--- a/weex-loader/test/expect/company.js
+++ /dev/null
@@ -1,39 +0,0 @@
-browserifyRequire=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof browserifyRequire=="function"&&browserifyRequire;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof browserifyRequire=="function"&&browserifyRequire;for(var o=0;o<r.length;o++)s(r[o]);return s})({"2f45f2510f12e10f1ea5a8ee68e880cd":[function(require,module,exports){
-exports.name = 'Alibaba Group';
-},{}]},{},[]);
-
-
-define('@weex-component/company', function (require, exports, module) {
-
-;
-var d = browserifyRequire("2f45f2510f12e10f1ea5a8ee68e880cd");
-module.exports = {
-    data: function () {return {
-        name: d.name
-    }}
-}
-
-
-;module.exports.style = {}
-
-;module.exports.template = {
-  "type": "container",
-  "children": [
-    {
-      "type": "text",
-      "style": {
-        "textAlign": "center",
-        "fontSize": 18,
-        "color": "#CCCCCC"
-      },
-      "attr": {
-        "value": function () {return this.name}
-      }
-    }
-  ]
-}
-
-;})
-
-// require module
-bootstrap('@weex-component/company', {"transformerVersion":"0.3.1"})
\ No newline at end of file
diff --git a/weex-loader/test/expect/copyright.js b/weex-loader/test/expect/copyright.js
deleted file mode 100644
index ba27cf3..0000000
--- a/weex-loader/test/expect/copyright.js
+++ /dev/null
@@ -1,82 +0,0 @@
-browserifyRequire=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof browserifyRequire=="function"&&browserifyRequire;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof browserifyRequire=="function"&&browserifyRequire;for(var o=0;o<r.length;o++)s(r[o]);return s})({"2f45f2510f12e10f1ea5a8ee68e880cd":[function(require,module,exports){
-exports.name = 'Alibaba Group';
-},{}]},{},[]);
-
-
-define('@weex-component/company', function (require, exports, module) {
-
-;
-var d = browserifyRequire("2f45f2510f12e10f1ea5a8ee68e880cd");
-module.exports = {
-    data: function () {return {
-        name: d.name
-    }}
-}
-
-
-;module.exports.style = {}
-
-;module.exports.template = {
-  "type": "container",
-  "children": [
-    {
-      "type": "text",
-      "style": {
-        "textAlign": "center",
-        "fontSize": 18,
-        "color": "#CCCCCC"
-      },
-      "attr": {
-        "value": function () {return this.name}
-      }
-    }
-  ]
-}
-
-;})
-
-// module
-
-define('@weex-component/copyright', function (require, exports, module) {
-
-;
-    module.exports = {
-        data: function () {return {
-            className: ''
-        }},
-        created: function (argument) {
-            this.className = 'copyright';
-        }
-    }
-
-
-;module.exports.style = {
-  "copyright": {
-    "textAlign": "center",
-    "paddingTop": 20,
-    "paddingBottom": 20,
-    "color": "#666666",
-    "fontSize": 26
-  }
-}
-
-;module.exports.template = {
-  "type": "container",
-  "children": [
-    {
-      "type": "text",
-      "classList": function () {return [this.className]},
-      "attr": {
-        "value": "Copy right @ 2016 Weex"
-      }
-    },
-    {
-      "type": "company"
-    }
-  ]
-}
-
-;})
-
-// require module
-bootstrap('@weex-component/copyright', {"transformerVersion":"0.3.1"})
\ No newline at end of file
diff --git a/weex-loader/test/expect/goto.js b/weex-loader/test/expect/goto.js
deleted file mode 100644
index 1878578..0000000
--- a/weex-loader/test/expect/goto.js
+++ /dev/null
@@ -1,44 +0,0 @@
-define('@weex-component/goto', function (require, exports, module) {
-
-;
-    module.exports = {
-        data: function () {return {
-            text: '',
-            paddingLeft: 20
-        }},
-        created: function() {
-            this.text = 'Yes It is! Go Weex >>>';
-        },
-        methods: {
-            clicked: function() {
-                this.$openURL('http://github.com/alibaba/weex');
-            }
-        }
-    }
-
-
-;module.exports.style = {}
-
-;module.exports.template = {
-  "type": "container",
-  "children": [
-    {
-      "type": "text",
-      "events": {
-        "click": "clicked"
-      },
-      "style": {
-        "textDecoration": "underline",
-        "paddingLeft": function () {return this.paddingLeft}
-      },
-      "attr": {
-        "value": function () {return this.text}
-      }
-    }
-  ]
-}
-
-;})
-
-// require module
-bootstrap('@weex-component/goto', {"transformerVersion":"0.3.1"})
\ No newline at end of file
diff --git a/weex-loader/test/expect/item.we b/weex-loader/test/expect/item.we
new file mode 100644
index 0000000..6edada6
--- /dev/null
+++ b/weex-loader/test/expect/item.we
@@ -0,0 +1,5 @@
+<template>
+  <div>
+    <text>ITEM</text>
+  </div>
+</template>
diff --git a/weex-loader/test/expect/z.js b/weex-loader/test/expect/z.js
deleted file mode 100644
index 8351a13..0000000
--- a/weex-loader/test/expect/z.js
+++ /dev/null
@@ -1,14 +0,0 @@
-define('@weex-component/z', function (require, exports, module) {
-
-;
-
-;module.exports.style = {}
-
-;module.exports.template = {
-  "type": "div"
-}
-
-;})
-
-// require module
-bootstrap('@weex-component/z', {"downgrade":{"ios":{"appVersion":">=13.0.0"},"android":{"appVersion":"<=0.0.0"}},"transformerVersion":"0.3.1"}, {"a":1,"b":2})
\ No newline at end of file
diff --git a/weex-loader/test/lib/3rd.js b/weex-loader/test/lib/3rd.js
new file mode 100644
index 0000000..e132ec8
--- /dev/null
+++ b/weex-loader/test/lib/3rd.js
@@ -0,0 +1 @@
+'Hello 3rd-party JavaScript'
diff --git a/weex-loader/test/test.js b/weex-loader/test/test.js
index e22726a..ab14972 100644
--- a/weex-loader/test/test.js
+++ b/weex-loader/test/test.js
@@ -40,6 +40,25 @@
     expect(actualJson).eql(expectJson);
   });
 
+  it('element tag, 3rd-party js, implicit component', function() {
+    var name = 'b.js';
+
+    var actualCodePath = path.resolve(__dirname, 'actual', name);
+    var actualCodeContent = fs.readFileSync(actualCodePath);
+
+    var expectCodePath = path.resolve(__dirname, 'expect', name);
+    var expectCodeContent = fs.readFileSync(expectCodePath);
+
+
+    var actualResult = createInstance('actual/' + name, actualCodeContent);
+    var actualJson = getRoot('actual/' + name);
+
+    var expectResult = createInstance('expect/' + name, expectCodeContent);
+    var expectJson = getRoot('expect/' + name);
+
+    expect(actualJson).eql(expectJson);
+  });
+
   it('with config & data case', function() {
     var name = 'z.js';
 
@@ -58,4 +77,4 @@
 
     expect(actualJson).eql(expectJson);
   });
-})
\ No newline at end of file
+})
diff --git a/weex-loader/webpack.config.js b/weex-loader/test/webpack.config.js
similarity index 72%
rename from weex-loader/webpack.config.js
rename to weex-loader/test/webpack.config.js
index 201d2a2..6f306fe 100644
--- a/weex-loader/webpack.config.js
+++ b/weex-loader/test/webpack.config.js
@@ -1,14 +1,15 @@
 var path = require('path');
 var webpack = require('webpack');
-var loader = require('./index.js');
+var loader = require('../index.js');
 
 module.exports = {
   entry: {
-    a: './test/a.js?entry=true',
-    z: './test/expect/z.we?entry=true'
+    a: path.resolve(__dirname, 'a.js?entry=true'),
+    b: path.resolve(__dirname, 'expect/b.we?entry=true'),
+    z: path.resolve(__dirname, 'expect/z.we?entry=true')
   },
   output: {
-    path: './test/actual',
+    path: path.resolve(__dirname, 'actual'),
     filename: '[name].js'
   },
   module: {
@@ -20,7 +21,7 @@
       {
         test: /\.js(\?[^?]+)?$/,
         exclude: [
-          path.resolve(__dirname, 'test/lib')
+          path.resolve(__dirname, 'lib')
         ],
         loaders: ['index.js?type=script', 'babel?presets[]=es2015']
       },
@@ -41,4 +42,4 @@
   resolveLoader: {
     modulesDirectories: ['./', './node_modules']
   }
-}
+};