From 4c469492b5d6bb1154ba71424bb78de4a9f88f28 Mon Sep 17 00:00:00 2001 From: Javey Date: Wed, 15 Aug 2018 17:32:17 +0800 Subject: [PATCH] support sourcemap, Javey/vdt.js#12 --- .gitignore | 1 + index.js | 61 ++++++++++++++++++++++++++--------- package.json | 5 ++- test/output/delimiters.js | 31 ++++++++++-------- test/output/import.js | 54 +++++++++++++++++-------------- test/output/skipWhitespace.js | 35 ++++++++++++-------- test/test.js | 10 ++++++ 7 files changed, 128 insertions(+), 69 deletions(-) diff --git a/.gitignore b/.gitignore index 1ca9571..2c5ad14 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ npm-debug.log +.vscode/ diff --git a/index.js b/index.js index 25936d4..33b3a3f 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,8 @@ var Vdt = require('vdt'), - loaderUtils = require('loader-utils'); + loaderUtils = require('loader-utils'), + path = require('path'), + sourceMap = require('source-map'); -// module.exports = function() {}; module.exports = function(source) { if (this.cacheable) this.cacheable(); @@ -19,23 +20,51 @@ module.exports = function(source) { query = Object.assign({ noWith: true, onlySource: true, - delimiters: ['{', '}'] + delimiters: ['{', '}'], + sourceMap: false, + // sourceMap: this.sourceMap }, query); var fn = Vdt.compile(source, query); - // source = fn.source; - // var pos = source.indexOf('\n'); var head = fn.head || ''; - - // 当字符串或者v-raw中存在import语句时,也会被提取,所以先去掉 - // fn.source = fn.source.replace(/(import\s+?[^\(\)]*?(from)?['"].*?['"](\s*;)?)/g, function(match) { - // head += match; - // return ''; - // }); - - return [ - head, - 'export default ' + fn.source - ].join('\n'); + var content = 'export default ' + fn.source; + if (head) { + content = head + content; + } + + if (query.sourceMap) { + var sourceRoot = process.cwd(); + var filename = path.relative(sourceRoot, this.resourcePath); + var map = getSourceMap({ + mappings: fn.mappings, + source: source, + filename: filename, + sourceRoot: sourceRoot, + offsetLine: head.split(/\n/).length - 1 + }); + + this.callback(null, content, map); + } else { + this.callback(null, content); + } }; + +function getSourceMap(options) { + var generator = new sourceMap.SourceMapGenerator({ + sourceRoot: options.sourceRoot, + file: path.basename(options.filename) + }); + + generator.setSourceContent(options.filename, options.source); + + options.mappings.forEach(function(mapping) { + mapping.generated.line += options.offsetLine; + if (mapping.original) { + mapping.source = options.filename; + } + generator.addMapping(mapping); + }); + + return generator.toJSON(); +} diff --git a/package.json b/package.json index 95de0ec..52b9f9a 100644 --- a/package.json +++ b/package.json @@ -13,12 +13,15 @@ "author": "jiawei23716@sina.com", "license": "ISC", "dependencies": { - "loader-utils": "^1.1.0" + "loader-utils": "^1.1.0", + "source-map": "^0.7.3" }, "peerDependencies": { "vdt": "*" }, "devDependencies": { + "babel-core": "^6.26.3", + "babel-loader": "^7.1.5", "intact": "^2.2.0-17", "mocha": "^3.4.2", "webpack": "^2.7.0" diff --git a/test/output/delimiters.js b/test/output/delimiters.js index ce8f63d..15d9d92 100644 --- a/test/output/delimiters.js +++ b/test/output/delimiters.js @@ -68,21 +68,23 @@ /************************************************************************/ /******/ ([ /* 0 */ -/***/ (function(module, exports) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); +/* harmony default export */ __webpack_exports__["default"] = (function(obj, _Vdt, blocks, $callee) { + _Vdt || (_Vdt = Vdt); + obj || (obj = {}); + blocks || (blocks = {}); + var h = _Vdt.miss.h, hc = _Vdt.miss.hc, hu = _Vdt.miss.hu, widgets = this && this.widgets || {}, _blocks = {}, __blocks = {}, + __u = _Vdt.utils, extend = __u.extend, _e = __u.error, _className = __u.className, __slice = __u.slice, __noop = __u.noop, + __m = __u.map, __o = __u.Options, _getModel = __o.getModel, _setModel = __o.setModel, + _setCheckboxModel = __u.setCheckboxModel, _detectCheckboxChecked = __u.detectCheckboxChecked, + _setSelectModel = __u.setSelectModel, + self = this.data, $this = this, scope = obj, Animate = self && self.Animate, parent = ($callee || {})._super; -module.exports = function(obj, _Vdt, blocks, $callee) { -_Vdt || (_Vdt = Vdt); -obj || (obj = {}); -blocks || (blocks = {}); -var h = _Vdt.miss.h, hc = _Vdt.miss.hc, hu = _Vdt.miss.hu, widgets = this && this.widgets || {}, _blocks = {}, __blocks = {}, -__u = _Vdt.utils, extend = __u.extend, _e = __u.error, _className = __u.className, -__o = __u.Options, _getModel = __o.getModel, _setModel = __o.setModel, -_setCheckboxModel = __u.setCheckboxModel, _detectCheckboxChecked = __u.detectCheckboxChecked, -_setSelectModel = __u.setSelectModel, -self = this.data, $this = this, scope = obj, Animate = self && self.Animate, parent = ($callee || {})._super -return h('div', null, function() {try {return [a][0]} catch(e) {_e(e)}}.call(this)) -} + return h('div', null, function() {try {return (a)} catch(e) {_e(e)}}.call($this)) +}); /***/ }), /* 1 */ @@ -92,4 +94,5 @@ var a = __webpack_require__(0); /***/ }) -/******/ ]); \ No newline at end of file +/******/ ]); +//# sourceMappingURL=delimiters.js.map \ No newline at end of file diff --git a/test/output/import.js b/test/output/import.js index 0f2e6e7..12645aa 100644 --- a/test/output/import.js +++ b/test/output/import.js @@ -76,37 +76,42 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__delimiters___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__delimiters__); /* harmony default export */ __webpack_exports__["default"] = (function(obj, _Vdt, blocks, $callee) { -_Vdt || (_Vdt = Vdt); -obj || (obj = {}); -blocks || (blocks = {}); -var h = _Vdt.miss.h, hc = _Vdt.miss.hc, hu = _Vdt.miss.hu, widgets = this && this.widgets || {}, _blocks = {}, __blocks = {}, -__u = _Vdt.utils, extend = __u.extend, _e = __u.error, _className = __u.className, -__o = __u.Options, _getModel = __o.getModel, _setModel = __o.setModel, -_setCheckboxModel = __u.setCheckboxModel, _detectCheckboxChecked = __u.detectCheckboxChecked, -_setSelectModel = __u.setSelectModel, -self = this.data, $this = this, scope = obj, Animate = self && self.Animate, parent = ($callee || {})._super + _Vdt || (_Vdt = Vdt); + obj || (obj = {}); + blocks || (blocks = {}); + var h = _Vdt.miss.h, hc = _Vdt.miss.hc, hu = _Vdt.miss.hu, widgets = this && this.widgets || {}, _blocks = {}, __blocks = {}, + __u = _Vdt.utils, extend = __u.extend, _e = __u.error, _className = __u.className, __slice = __u.slice, __noop = __u.noop, + __m = __u.map, __o = __u.Options, _getModel = __o.getModel, _setModel = __o.setModel, + _setCheckboxModel = __u.setCheckboxModel, _detectCheckboxChecked = __u.detectCheckboxChecked, + _setSelectModel = __u.setSelectModel, + self = this.data, $this = this, scope = obj, Animate = self && self.Animate, parent = ($callee || {})._super; -return h(__WEBPACK_IMPORTED_MODULE_0__delimiters___default.a, {'children': 'test', '_context': $this}) + return h(__WEBPACK_IMPORTED_MODULE_0__delimiters___default.a, { + 'children': 'test', + '_context': $this + }) }); /***/ }), /* 1 */ -/***/ (function(module, exports) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); +/* harmony default export */ __webpack_exports__["default"] = (function(obj, _Vdt, blocks, $callee) { + _Vdt || (_Vdt = Vdt); + obj || (obj = {}); + blocks || (blocks = {}); + var h = _Vdt.miss.h, hc = _Vdt.miss.hc, hu = _Vdt.miss.hu, widgets = this && this.widgets || {}, _blocks = {}, __blocks = {}, + __u = _Vdt.utils, extend = __u.extend, _e = __u.error, _className = __u.className, __slice = __u.slice, __noop = __u.noop, + __m = __u.map, __o = __u.Options, _getModel = __o.getModel, _setModel = __o.setModel, + _setCheckboxModel = __u.setCheckboxModel, _detectCheckboxChecked = __u.detectCheckboxChecked, + _setSelectModel = __u.setSelectModel, + self = this.data, $this = this, scope = obj, Animate = self && self.Animate, parent = ($callee || {})._super; -module.exports = function(obj, _Vdt, blocks, $callee) { -_Vdt || (_Vdt = Vdt); -obj || (obj = {}); -blocks || (blocks = {}); -var h = _Vdt.miss.h, hc = _Vdt.miss.hc, hu = _Vdt.miss.hu, widgets = this && this.widgets || {}, _blocks = {}, __blocks = {}, -__u = _Vdt.utils, extend = __u.extend, _e = __u.error, _className = __u.className, -__o = __u.Options, _getModel = __o.getModel, _setModel = __o.setModel, -_setCheckboxModel = __u.setCheckboxModel, _detectCheckboxChecked = __u.detectCheckboxChecked, -_setSelectModel = __u.setSelectModel, -self = this.data, $this = this, scope = obj, Animate = self && self.Animate, parent = ($callee || {})._super -return h('div', null, function() {try {return [a][0]} catch(e) {_e(e)}}.call(this)) -} + return h('div', null, function() {try {return (a)} catch(e) {_e(e)}}.call($this)) +}); /***/ }), /* 2 */ @@ -123,4 +128,5 @@ __webpack_require__(0); /***/ }) -/******/ ]); \ No newline at end of file +/******/ ]); +//# sourceMappingURL=import.js.map \ No newline at end of file diff --git a/test/output/skipWhitespace.js b/test/output/skipWhitespace.js index d30db9c..f22770a 100644 --- a/test/output/skipWhitespace.js +++ b/test/output/skipWhitespace.js @@ -68,21 +68,27 @@ /************************************************************************/ /******/ ([ /* 0 */ -/***/ (function(module, exports) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); +/* harmony default export */ __webpack_exports__["default"] = (function(obj, _Vdt, blocks, $callee) { + _Vdt || (_Vdt = Vdt); + obj || (obj = {}); + blocks || (blocks = {}); + var h = _Vdt.miss.h, hc = _Vdt.miss.hc, hu = _Vdt.miss.hu, widgets = this && this.widgets || {}, _blocks = {}, __blocks = {}, + __u = _Vdt.utils, extend = __u.extend, _e = __u.error, _className = __u.className, __slice = __u.slice, __noop = __u.noop, + __m = __u.map, __o = __u.Options, _getModel = __o.getModel, _setModel = __o.setModel, + _setCheckboxModel = __u.setCheckboxModel, _detectCheckboxChecked = __u.detectCheckboxChecked, + _setSelectModel = __u.setSelectModel, + self = this.data, $this = this, scope = obj, Animate = self && self.Animate, parent = ($callee || {})._super; -module.exports = function(obj, _Vdt, blocks, $callee) { -_Vdt || (_Vdt = Vdt); -obj || (obj = {}); -blocks || (blocks = {}); -var h = _Vdt.miss.h, hc = _Vdt.miss.hc, hu = _Vdt.miss.hu, widgets = this && this.widgets || {}, _blocks = {}, __blocks = {}, -__u = _Vdt.utils, extend = __u.extend, _e = __u.error, _className = __u.className, -__o = __u.Options, _getModel = __o.getModel, _setModel = __o.setModel, -_setCheckboxModel = __u.setCheckboxModel, _detectCheckboxChecked = __u.detectCheckboxChecked, -_setSelectModel = __u.setSelectModel, -self = this.data, $this = this, scope = obj, Animate = self && self.Animate, parent = ($callee || {})._super -return h('div', null, ['\n ', h('span', null, function() {try {return [a][0]} catch(e) {_e(e)}}.call(this)), '\n']) -} + return h('div', null, [ + '\n ', + h('span', null, function() {try {return (a)} catch(e) {_e(e)}}.call($this)), + '\n' + ]) +}); /***/ }), /* 1 */ @@ -92,4 +98,5 @@ var a = __webpack_require__(0); /***/ }) -/******/ ]); \ No newline at end of file +/******/ ]); +//# sourceMappingURL=skipWhitespace.js.map \ No newline at end of file diff --git a/test/test.js b/test/test.js index 19de0db..8deec01 100644 --- a/test/test.js +++ b/test/test.js @@ -13,6 +13,7 @@ var config = { path: output, filename: '[name].js' }, + devtool: '#source-map', module: { rules: [ { @@ -25,6 +26,15 @@ var config = { } }; +// config.entry = { + // import: path.resolve(__dirname, './input/import.js') +// }; + +// webpack(config, function(err, stats) { + // console.log(stats.toString({colors: true})); +// }); + + describe('Vdt Loader', function() { it('set error delimiters should get error result', function(done) { config.module.rules[0].use.options = {delimiters: ['{{', '}}']};