Skip to content

Commit 518557b

Browse files
committed
nicer output with named exports support
1 parent 0aabf82 commit 518557b

File tree

4 files changed

+54
-55
lines changed

4 files changed

+54
-55
lines changed

lib/loader.js

+29-36
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,11 @@ module.exports = function (content) {
4141
var moduleId = 'data-v-' + genId(filePath)
4242
var styleRewriter = styleRewriterPath + '?id=' + moduleId
4343

44+
var isProduction = this.minimize || process.env.NODE_ENV === 'production'
45+
4446
var needCssSourceMap =
47+
!isProduction &&
4548
this.sourceMap &&
46-
!this.minimize &&
47-
process.env.NODE_ENV !== 'production' &&
4849
options.cssSourceMap !== false
4950

5051
var defaultLoaders = {
@@ -135,10 +136,11 @@ module.exports = function (content) {
135136

136137
var parts = parse(content, fileName, this.sourceMap)
137138
var hasScoped = parts.styles.some(function (s) { return s.scoped })
138-
var output = 'var __vue_script__\n'
139+
var output = 'var __vue_exports__, __vue_options__\n'
139140

140141
// add requires for styles
141-
if (!isServer) {
142+
if (!isServer && parts.styles.length) {
143+
output += '\n/* styles */\n'
142144
parts.styles.forEach(function (style, i) {
143145
output += style.src
144146
? getRequireForImport('styles', style, style.scoped)
@@ -149,42 +151,33 @@ module.exports = function (content) {
149151
// add require for script
150152
var script = parts.script
151153
if (script) {
154+
output += '\n/* script */\n'
152155
output +=
153-
'__vue_script__ = ' + (
156+
'__vue_exports__ = ' + (
154157
script.src
155158
? getRequireForImport('script', script)
156159
: getRequire('script', script)
157160
)
158-
// check and warn named exports
159-
if (!this.minimize) {
160-
output +=
161-
'if (__vue_script__ &&\n' +
162-
' __vue_script__.__esModule &&\n' +
163-
' Object.keys(__vue_script__).length > 1) {\n' +
164-
' console.warn(' + JSON.stringify(
165-
'[vue-loader] ' + path.relative(process.cwd(), filePath) +
166-
': named exports in *.vue files are ignored.'
167-
) + ')' +
168-
'}\n'
169-
}
170161
}
171162

172-
// plain require() compatibility
173-
var exports = 'if (__exports__.__esModule) __exports__ = __exports__.default\n'
163+
var exports =
164+
'__vue_options__ = __vue_exports__ || {}\n' +
165+
// ES6 modules interop
166+
'if (__vue_options__.__esModule) __vue_options__ = __vue_options__.default\n' +
167+
// constructor export interop
168+
'if (typeof __vue_options__ === "function") __vue_options__ = __vue_options__.options\n'
174169

175170
// add require for template
176171
var template = parts.template
177172
if (template) {
173+
output += '\n/* template */\n'
178174
output += 'var __vue_template__ = ' + (
179175
template.src
180176
? getRequireForImport('template', template)
181177
: getRequire('template', template)
182178
)
183179
// attach render functions to exported options
184180
exports +=
185-
'var __vue_options__ = (typeof __exports__ === "function" ' +
186-
'? (__exports__.options || (__exports__.options = {})) ' +
187-
': __exports__)\n' +
188181
'__vue_options__.render = __vue_template__.render\n' +
189182
'__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n'
190183
// attach scoped id
@@ -194,39 +187,39 @@ module.exports = function (content) {
194187
}
195188

196189
if (!query.inject) {
197-
output +=
198-
'var __exports__ = __vue_script__ || {}\n' +
199-
exports +
200-
'module.exports = __exports__'
190+
output += exports
201191
// hot reload
202192
if (
203193
!isServer &&
204-
!this.minimize &&
205-
process.env.NODE_ENV !== 'production' &&
194+
!isProduction &&
206195
(parts.script || parts.template)
207196
) {
208197
output +=
209-
'\nif (module.hot) {(function () {' +
198+
'\n/* hot reload */\n' +
199+
'if (module.hot) {(function () {\n' +
210200
' var hotAPI = require("' + hotReloadAPIPath + '")\n' +
211201
' hotAPI.install(require("vue"), false)\n' +
212202
' if (!hotAPI.compatible) return\n' +
213203
' module.hot.accept()\n' +
214204
' if (!module.hot.data) {\n' +
215205
// initial insert
216-
' hotAPI.createRecord("' + moduleId + '", __exports__)\n' +
206+
' hotAPI.createRecord("' + moduleId + '", __vue_options__)\n' +
217207
' } else {\n' +
218208
// update
219-
' hotAPI.reload("' + moduleId + '", __exports__)\n' +
209+
' hotAPI.reload("' + moduleId + '", __vue_options__)\n' +
220210
' }\n' +
221-
'})()}'
211+
'})()}\n'
222212
}
213+
// final export
214+
output += '\nmodule.exports = __vue_exports__ || __vue_options__\n'
223215
} else {
216+
// inject-loader support
224217
output +=
218+
'\n/* dependency injection */\n' +
225219
'module.exports = function (injections) {\n' +
226-
' var __exports__ = __vue_script__\n' +
227-
' ? __vue_script__(injections)\n' +
228-
' : {}\n' + exports +
229-
' return __exports__\n' +
220+
' __vue_exports__ = __vue_exports__(injections)\n' +
221+
exports +
222+
' return __vue_exports__ || __vue_options__\n' +
230223
'}'
231224
}
232225

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"homepage": "https://github.com/vuejs/vue-loader",
2525
"scripts": {
2626
"lint": "eslint lib",
27-
"test": "eslint lib && mocha test/test.js --slow 5000 --timeout 10000",
27+
"test": "eslint lib && mocha --slow 5000 --timeout 10000",
2828
"docs": "cd docs && gitbook serve",
2929
"deploy-docs": "bash ./docs/deploy.sh"
3030
},
@@ -39,7 +39,7 @@
3939
"source-map": "^0.5.6",
4040
"vue-hot-reload-api": "^2.0.1",
4141
"vue-style-loader": "^1.0.0",
42-
"vue-template-compiler": "^2.0.0-alpha.2"
42+
"vue-template-compiler": "^2.0.0-alpha.8"
4343
},
4444
"peerDependencies": {
4545
"css-loader": "^0.23.1"

test/fixtures/basic.vue

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
</template>
44

55
<script>
6+
export function test () {
7+
return 'hi'
8+
}
9+
610
export default {
711
data () {
812
return {

test/test.js

+19-17
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ function test (options, assert) {
5454
console.log(err[0].data.error.stack)
5555
expect(err).to.be.null
5656
}
57-
assert(window)
57+
assert(window, interopDefault(window.vueModule), window.vueModule)
5858
}
5959
})
6060
})
@@ -65,12 +65,19 @@ function assertRenderFn (options, template) {
6565
expect(options.render.toString()).to.equal('function (){' + compiled.render + '}')
6666
}
6767

68+
function interopDefault (module) {
69+
return module
70+
? module.__esModule ? module.default : module
71+
: module
72+
}
73+
6874
describe('vue-loader', function () {
6975
it('basic', function (done) {
7076
test({
7177
entry: './test/fixtures/basic.vue'
72-
}, function (window) {
73-
var module = window.vueModule
78+
}, function (window, module, rawModule) {
79+
// test named export
80+
expect(rawModule.test()).to.equal('hi')
7481
assertRenderFn(module, '<h2 class="red">{{msg}}</h2>')
7582
expect(module.data().msg).to.contain('Hello from Component A!')
7683
var style = window.document.querySelector('style').textContent
@@ -82,8 +89,7 @@ describe('vue-loader', function () {
8289
it('pre-processors', function (done) {
8390
test({
8491
entry: './test/fixtures/pre.vue'
85-
}, function (window) {
86-
var module = window.vueModule
92+
}, function (window, module) {
8793
assertRenderFn(module,
8894
'<div>' +
8995
'<h1>This is the app</h1>' +
@@ -101,8 +107,7 @@ describe('vue-loader', function () {
101107
it('scoped style', function (done) {
102108
test({
103109
entry: './test/fixtures/scoped-css.vue'
104-
}, function (window) {
105-
var module = window.vueModule
110+
}, function (window, module) {
106111
var id = 'data-v-' + genId(require.resolve('./fixtures/scoped-css.vue'))
107112
expect(module._scopeId).to.equal(id)
108113
assertRenderFn(module,
@@ -137,8 +142,7 @@ describe('vue-loader', function () {
137142
it('template import', function (done) {
138143
test({
139144
entry: './test/fixtures/template-import.vue'
140-
}, function (window) {
141-
var module = window.vueModule
145+
}, function (window, module) {
142146
assertRenderFn(module, '<div><h1>hello</h1></div>')
143147
done()
144148
})
@@ -147,8 +151,7 @@ describe('vue-loader', function () {
147151
it('script import', function (done) {
148152
test({
149153
entry: './test/fixtures/script-import.vue'
150-
}, function (window) {
151-
var module = window.vueModule
154+
}, function (window, module) {
152155
expect(module.data().msg).to.contain('Hello from Component A!')
153156
done()
154157
})
@@ -168,7 +171,7 @@ describe('vue-loader', function () {
168171
code.split(/\r?\n/g).some(function (l, i) {
169172
if (targetRE.test(l)) {
170173
line = i + 1
171-
col = l.length
174+
col = 0
172175
return true
173176
}
174177
})
@@ -177,7 +180,7 @@ describe('vue-loader', function () {
177180
column: col
178181
})
179182
expect(pos.source.indexOf('basic.vue') > -1)
180-
expect(pos.line).to.equal(9)
183+
expect(pos.line).to.equal(13)
181184
done()
182185
})
183186
})
@@ -216,11 +219,11 @@ describe('vue-loader', function () {
216219
test({
217220
entry: './test/fixtures/inject.js'
218221
}, function (window) {
219-
var module = window.injector({
222+
var module = interopDefault(window.injector({
220223
'./service': {
221224
msg: 'Hello from mocked service!'
222225
}
223-
})
226+
}))
224227
assertRenderFn(module, '<div class="msg">{{ msg }}</div>')
225228
expect(module.data().msg).to.contain('Hello from mocked service!')
226229
done()
@@ -241,8 +244,7 @@ describe('vue-loader', function () {
241244
{ test: /\.png$/, loader: 'file-loader?name=[name].[hash:6].[ext]' }
242245
]
243246
}
244-
}, function (window) {
245-
var module = window.vueModule
247+
}, function (window, module) {
246248
assertRenderFn(module, '<img src="logo.c9e00e.png">\n<img src="logo.c9e00e.png">')
247249
var style = window.document.querySelector('style').textContent
248250
expect(style).to.contain('html { background-image: url(logo.c9e00e.png);\n}')

0 commit comments

Comments
 (0)