diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 000000000..31346ac39 --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,25 @@ +module.exports = function (config) { + config.set({ + preprocessors: { + '**/*.vue': ['webpack', 'sourcemap'] + }, + webpack: { + devtool: 'inline-source-map', + module: { + loaders: [ + { test: /\.vue$/, loader: './index.js' } + ] + } + }, + frameworks: ['mocha', 'chai'], + files: ['test/*.vue'], + plugins: [ + require('karma-webpack'), + require('karma-mocha'), + require('karma-chai'), + require('karma-chrome-launcher'), + require('karma-phantomjs-launcher'), + require('karma-sourcemap-loader') + ] + }) +} diff --git a/lib/loader.js b/lib/loader.js index c2e2644e7..7bb0a11c2 100644 --- a/lib/loader.js +++ b/lib/loader.js @@ -144,6 +144,7 @@ module.exports = function (content) { var parts = parse(content, fileName, this.sourceMap) var hasLocalStyles = false var output = 'var __vue_script__, __vue_template__\n' + var testOutput = '' // check if there are any template syntax errors var templateWarnings = parts.template.length && parts.template[0].warnings @@ -163,29 +164,58 @@ module.exports = function (content) { output += getRequire('style', style, i, style.scoped) }) - // add require for script - var script - if (parts.script.length) { - script = parts.script[0] - output += - '__vue_script__ = ' + ( - script.src - ? getRequireForImport('script', script, 0) - : getRequire('script', script, 0) - ) - // check and warn named exports - if (!this.minimize) { - output += - 'if (__vue_script__ &&\n' + - ' __vue_script__.__esModule &&\n' + - ' Object.keys(__vue_script__).length > 1) {\n' + - ' console.warn(' + JSON.stringify( - '[vue-loader] ' + path.relative(process.cwd(), filePath) + - ': named exports in *.vue files are ignored.' - ) + ')' + - '}\n' + // add requires for scripts + var hasScript = false + parts.script.forEach(function (script, i) { + var requireStr = script.src + ? getRequireForImport('script', script, i) + : getRequire('script', script, i) + if (script.test === undefined) { + // only one script without test attribute + if (hasScript) { + throw new Error( + '[vue-loader] Only one diff --git a/test/basic.vue b/test/basic.vue new file mode 100644 index 000000000..d2bc71898 --- /dev/null +++ b/test/basic.vue @@ -0,0 +1,31 @@ + + + + + + diff --git a/test/fixtures/autoprefix.vue b/test/fixtures/autoprefix.vue deleted file mode 100644 index a5308b2e0..000000000 --- a/test/fixtures/autoprefix.vue +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/test/fixtures/basic.vue b/test/fixtures/basic.vue deleted file mode 100644 index 5035c8304..000000000 --- a/test/fixtures/basic.vue +++ /dev/null @@ -1,19 +0,0 @@ - - - - - diff --git a/test/fixtures/pre.vue b/test/fixtures/pre.vue deleted file mode 100644 index 2eafdb4fd..000000000 --- a/test/fixtures/pre.vue +++ /dev/null @@ -1,19 +0,0 @@ - - - - - diff --git a/test/fixtures/script-import.vue b/test/fixtures/script-import.vue deleted file mode 100644 index b45d1ec73..000000000 --- a/test/fixtures/script-import.vue +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/test/fixtures/template-import.vue b/test/fixtures/template-import.vue deleted file mode 100644 index ce534539b..000000000 --- a/test/fixtures/template-import.vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/karma.vue b/test/karma.vue new file mode 100644 index 000000000..fbb891237 --- /dev/null +++ b/test/karma.vue @@ -0,0 +1,27 @@ + + + + + + diff --git a/test/preprocessors.vue b/test/preprocessors.vue new file mode 100644 index 000000000..a7e7cd3ed --- /dev/null +++ b/test/preprocessors.vue @@ -0,0 +1,36 @@ + + + + + + + diff --git a/test/script-import.vue b/test/script-import.vue new file mode 100644 index 000000000..a39d112b8 --- /dev/null +++ b/test/script-import.vue @@ -0,0 +1,10 @@ + + + diff --git a/test/template-import.vue b/test/template-import.vue new file mode 100644 index 000000000..8b5ca968c --- /dev/null +++ b/test/template-import.vue @@ -0,0 +1,10 @@ + + + diff --git a/test/test.js b/test/test.js index 8644b3ef1..726f6b5ac 100644 --- a/test/test.js +++ b/test/test.js @@ -8,6 +8,41 @@ var hash = require('hash-sum') var SourceMapConsumer = require('source-map').SourceMapConsumer var ExtractTextPlugin = require("extract-text-webpack-plugin") +// to get loader.js output without webpack +describe('vue-loader webpack mock', function () { + var loader + before(function () { + // mock webpack + loader = require('../lib/loader.js').bind({ + cacheable: function () {}, + options: {}, + emitError: function (e) { throw e }, + resourcePath: "./test.vue" + }) + }) + + it('template', function () { + var result = loader('') + expect(result).to.match(/__vue_template__ = require.+selector\.js\?type=template&index=0!\.\/test\.vue"\)/g) + }) + it('script', function () { + var result = loader('') + expect(result).to.match(/__vue_script__ = require.+selector\.js\?type=script&index=0!\.\/test\.vue"\)/g) + }) + it('script test', function () { + var result = loader('') + expect(result).to.match(/\nrequire\("!!.+selector\.js\?type=script&index=0!\.\/test\.vue"\)/g) + }) + it('script test karma', function () { + var result = loader('') + expect(result).to.match(/\nif \(window\._karma__ !== "null"\) {/g) + }) + it('style', function () { + var result = loader('') + expect(result).to.match(/\nrequire.+selector\.js\?type=style&index=0!\.\/test\.vue"\)/g) + }) +}) + describe('vue-loader', function () { var testHTML = '' @@ -64,36 +99,6 @@ describe('vue-loader', function () { }) } - it('basic', function (done) { - test({ - entry: './test/fixtures/basic.vue' - }, function (window) { - var module = window.vueModule - expect(module.template).to.contain('

{{msg}}

') - expect(module.data().msg).to.contain('Hello from Component A!') - var style = window.document.querySelector('style').textContent - expect(style).to.contain('comp-a h2 {\n color: #f00;\n}') - done() - }) - }) - - it('pre-processors', function (done) { - test({ - entry: './test/fixtures/pre.vue' - }, function (window) { - var module = window.vueModule - expect(module.template).to.contain( - '

This is the app

' + - '' + - '' - ) - expect(module.data().msg).to.contain('Hello from coffee!') - var style = window.document.querySelector('style').textContent - expect(style).to.contain('body {\n font: 100% Helvetica, sans-serif;\n color: #999;\n}') - done() - }) - }) - it('scoped style', function (done) { test({ entry: './test/fixtures/scoped-css.vue' @@ -127,29 +132,9 @@ describe('vue-loader', function () { }) }) - it('template import', function (done) { - test({ - entry: './test/fixtures/template-import.vue' - }, function (window) { - var module = window.vueModule - expect(module.template).to.contain('

hello

') - done() - }) - }) - - it('script import', function (done) { - test({ - entry: './test/fixtures/script-import.vue' - }, function (window) { - var module = window.vueModule - expect(module.data().msg).to.contain('Hello from Component A!') - done() - }) - }) - it('source map', function (done) { var config = Object.assign({}, globalConfig, { - entry: './test/fixtures/basic.vue', + entry: './test/preprocessors.vue', devtool: 'source-map' }) webpack(config, function (err) { @@ -159,7 +144,7 @@ describe('vue-loader', function () { getFile('test.build.js', function (code) { var line var col - var targetRE = /^\s+msg: 'Hello from Component A!'/ + var targetRE = /^\s+msg: 'Hello from coffee!'/ code.split(/\r?\n/g).some(function (l, i) { if (targetRE.test(l)) { line = i + 1 @@ -172,23 +157,13 @@ describe('vue-loader', function () { column: col }) expect(pos.source.indexOf('basic.vue') > -1) - expect(pos.line).to.equal(9) + expect(pos.line).to.equal(18) done() }) }) }) }) - it('autoprefix', function (done) { - test({ - entry: './test/fixtures/autoprefix.vue' - }, function (window) { - var style = window.document.querySelector('style').textContent - expect(style).to.contain('body {\n -webkit-transform: scale(1);\n transform: scale(1);\n}') - done() - }) - }) - it('media-query', function (done) { test({ entry: './test/fixtures/media-query.vue'