Skip to content

Commit d8c82d5

Browse files
committedOct 24, 2017
feat: use file content for generating scoped id
1 parent f5a6e26 commit d8c82d5

File tree

3 files changed

+89
-106
lines changed

3 files changed

+89
-106
lines changed
 

‎lib/loader.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
const path = require('path')
22
const hash = require('hash-sum')
33
const parse = require('./parser')
4-
const genId = require('./utils/gen-id')
54
const querystring = require('querystring')
65
const loaderUtils = require('loader-utils')
76
const normalize = require('./utils/normalize')
@@ -82,7 +81,7 @@ module.exports = function (content) {
8281
this.options.context ||
8382
process.cwd()
8483
const sourceRoot = path.dirname(path.relative(context, filePath))
85-
const moduleId = 'data-v-' + genId(filePath, context, options.hashKey)
84+
const moduleId = 'data-v-' + hash(content)
8685
const shortFilePath = path
8786
.relative(context, filePath)
8887
.replace(/^(\.\.\/)+/, '')

‎lib/utils/gen-id.js

Lines changed: 0 additions & 17 deletions
This file was deleted.

‎test/test.js

Lines changed: 88 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
process.env.VUE_LOADER_TEST = true
22

3-
var fs = require('fs')
4-
var path = require('path')
5-
var jsdom = require('jsdom')
6-
var webpack = require('webpack')
7-
var MemoryFS = require('memory-fs')
8-
var expect = require('chai').expect
9-
var hash = require('hash-sum')
10-
var Vue = require('vue')
11-
var SSR = require('vue-server-renderer')
3+
const fs = require('fs')
4+
const path = require('path')
5+
const jsdom = require('jsdom')
6+
const webpack = require('webpack')
7+
const MemoryFS = require('memory-fs')
8+
const expect = require('chai').expect
9+
const hash = require('hash-sum')
10+
const Vue = require('vue')
11+
const SSR = require('vue-server-renderer')
1212
// var compiler = require('../lib/template-compiler')
13-
var normalizeNewline = require('normalize-newline')
14-
var ExtractTextPlugin = require('extract-text-webpack-plugin')
15-
var SourceMapConsumer = require('source-map').SourceMapConsumer
16-
17-
var rawLoaderPath = path.resolve(__dirname, '../index.js')
18-
var loaderPath = 'expose-loader?vueModule!' + rawLoaderPath
19-
var mfs = new MemoryFS()
20-
var globalConfig = {
13+
const normalizeNewline = require('normalize-newline')
14+
const ExtractTextPlugin = require('extract-text-webpack-plugin')
15+
const SourceMapConsumer = require('source-map').SourceMapConsumer
16+
17+
const rawLoaderPath = path.resolve(__dirname, '../index.js')
18+
const loaderPath = 'expose-loader?vueModule!' + rawLoaderPath
19+
const mfs = new MemoryFS()
20+
const globalConfig = {
2121
output: {
2222
path: '/',
2323
filename: 'test.build.js'
@@ -35,10 +35,14 @@ var globalConfig = {
3535
]
3636
}
3737

38+
function genId (file) {
39+
return hash(fs.readFileSync(path.resolve(__dirname, './fixtures', file), 'utf-8'))
40+
}
41+
3842
function bundle (options, cb) {
39-
var vueOptions = options.vue
43+
const vueOptions = options.vue
4044
delete options.vue
41-
var config = Object.assign({}, globalConfig, options)
45+
const config = Object.assign({}, globalConfig, options)
4246

4347
// assign vue Options
4448
if (vueOptions) {
@@ -47,7 +51,7 @@ function bundle (options, cb) {
4751
}))
4852
}
4953

50-
var webpackCompiler = webpack(config)
54+
const webpackCompiler = webpack(config)
5155
webpackCompiler.outputFileSystem = mfs
5256
webpackCompiler.run((err, stats) => {
5357
expect(err).to.be.null
@@ -99,12 +103,12 @@ function interopDefault (module) {
99103
: module
100104
}
101105

102-
describe('vue-loader', function () {
106+
describe('vue-loader', () => {
103107
it('basic', done => {
104108
test({
105109
entry: './test/fixtures/basic.vue'
106110
}, (window, module, rawModule) => {
107-
var vnode = mockRender(module, {
111+
const vnode = mockRender(module, {
108112
msg: 'hi'
109113
})
110114

@@ -114,7 +118,7 @@ describe('vue-loader', function () {
114118
expect(vnode.children[0].text).to.equal('hi')
115119

116120
expect(module.data().msg).to.contain('Hello from Component A!')
117-
var style = window.document.querySelector('style').textContent
121+
let style = window.document.querySelector('style').textContent
118122
style = normalizeNewline(style)
119123
expect(style).to.contain('comp-a h2 {\n color: #f00;\n}')
120124
done()
@@ -134,7 +138,7 @@ describe('vue-loader', function () {
134138
test({
135139
entry: './test/fixtures/pre.vue'
136140
}, (window, module) => {
137-
var vnode = mockRender(module)
141+
const vnode = mockRender(module)
138142
// div
139143
// h1 This is the app
140144
// comp-a
@@ -144,7 +148,7 @@ describe('vue-loader', function () {
144148
expect(vnode.children[2].tag).to.equal('comp-b')
145149

146150
expect(module.data().msg).to.contain('Hello from coffee!')
147-
var style = window.document.querySelector('style').textContent
151+
const style = window.document.querySelector('style').textContent
148152
expect(style).to.contain('body {\n font: 100% Helvetica, sans-serif;\n color: #999;\n}')
149153
done()
150154
})
@@ -160,15 +164,15 @@ describe('vue-loader', function () {
160164
new ExtractTextPlugin('test.output.css')
161165
]
162166
}, (window, module) => {
163-
var vnode = mockRender(module)
167+
const vnode = mockRender(module)
164168

165169
expect(vnode.children[0].tag).to.equal('h1')
166170
expect(vnode.children[1].tag).to.equal('comp-a')
167171
expect(vnode.children[2].tag).to.equal('comp-b')
168172

169173
expect(module.data().msg).to.contain('Hello from coffee!')
170174

171-
var css = mfs.readFileSync('/test.output.css').toString()
175+
let css = mfs.readFileSync('/test.output.css').toString()
172176
css = normalizeNewline(css)
173177
expect(css).to.contain('body {\n font: 100% Helvetica, sans-serif;\n color: #999;\n}')
174178

@@ -178,15 +182,12 @@ describe('vue-loader', function () {
178182

179183
it('scoped style', done => {
180184
test({
181-
entry: './test/fixtures/scoped-css.vue',
182-
vue: {
183-
hashKey: 'foo'
184-
}
185+
entry: './test/fixtures/scoped-css.vue'
185186
}, (window, module) => {
186-
var id = 'data-v-' + hash('vue-loader/test/fixtures/scoped-css.vue' + 'foo')
187+
const id = 'data-v-' + genId('scoped-css.vue')
187188
expect(module._scopeId).to.equal(id)
188189

189-
var vnode = mockRender(module, {
190+
const vnode = mockRender(module, {
190191
ok: true
191192
})
192193
// <div>
@@ -202,7 +203,7 @@ describe('vue-loader', function () {
202203
expect(vnode.children[4].tag).to.equal('p')
203204
expect(vnode.children[4].data.staticClass).to.equal('test')
204205

205-
var style = window.document.querySelector('style').textContent
206+
let style = window.document.querySelector('style').textContent
206207
style = normalizeNewline(style)
207208
expect(style).to.contain(`.test[${id}] {\n color: yellow;\n}`)
208209
expect(style).to.contain(`.test[${id}]:after {\n content: \'bye!\';\n}`)
@@ -222,10 +223,10 @@ describe('vue-loader', function () {
222223
test({
223224
entry: './test/fixtures/style-import.vue'
224225
}, (window) => {
225-
var styles = window.document.querySelectorAll('style')
226+
const styles = window.document.querySelectorAll('style')
226227
expect(styles[0].textContent).to.contain('h1 { color: red;\n}')
227228
// import with scoped
228-
var id = 'data-v-' + hash('vue-loader/test/fixtures/style-import.vue')
229+
const id = 'data-v-' + genId('style-import.vue')
229230
expect(styles[1].textContent).to.contain('h1[' + id + '] { color: green;\n}')
230231
done()
231232
})
@@ -235,7 +236,7 @@ describe('vue-loader', function () {
235236
test({
236237
entry: './test/fixtures/template-import.vue'
237238
}, (window, module) => {
238-
var vnode = mockRender(module)
239+
const vnode = mockRender(module)
239240
// '<div><h1>hello</h1></div>'
240241
expect(vnode.children[0].tag).to.equal('h1')
241242
expect(vnode.children[0].children[0].text).to.equal('hello')
@@ -257,19 +258,19 @@ describe('vue-loader', function () {
257258
entry: './test/fixtures/basic.vue',
258259
devtool: '#source-map'
259260
}, (code, warnings) => {
260-
var map = mfs.readFileSync('/test.build.js.map').toString()
261-
var smc = new SourceMapConsumer(JSON.parse(map))
262-
var line
263-
var col
264-
var targetRE = /^\s+msg: 'Hello from Component A!'/
261+
const map = mfs.readFileSync('/test.build.js.map').toString()
262+
const smc = new SourceMapConsumer(JSON.parse(map))
263+
let line
264+
let col
265+
const targetRE = /^\s+msg: 'Hello from Component A!'/
265266
code.split(/\r?\n/g).some((l, i) => {
266267
if (targetRE.test(l)) {
267268
line = i + 1
268269
col = 0
269270
return true
270271
}
271272
})
272-
var pos = smc.originalPositionFor({
273+
const pos = smc.originalPositionFor({
273274
line: line,
274275
column: col
275276
})
@@ -283,9 +284,9 @@ describe('vue-loader', function () {
283284
test({
284285
entry: './test/fixtures/media-query.vue'
285286
}, (window) => {
286-
var style = window.document.querySelector('style').textContent
287+
let style = window.document.querySelector('style').textContent
287288
style = normalizeNewline(style)
288-
var id = 'data-v-' + hash('vue-loader/test/fixtures/media-query.vue')
289+
const id = 'data-v-' + genId('media-query.vue')
289290
expect(style).to.contain('@media print {\n.foo[' + id + '] {\n color: #000;\n}\n}')
290291
done()
291292
})
@@ -295,9 +296,9 @@ describe('vue-loader', function () {
295296
test({
296297
entry: './test/fixtures/supports-query.vue'
297298
}, (window) => {
298-
var style = window.document.querySelector('style').textContent
299+
let style = window.document.querySelector('style').textContent
299300
style = normalizeNewline(style)
300-
var id = 'data-v-' + hash('vue-loader/test/fixtures/supports-query.vue')
301+
const id = 'data-v-' + genId('supports-query.vue')
301302
expect(style).to.contain('@supports ( color: #000 ) {\n.foo[' + id + '] {\n color: #000;\n}\n}')
302303
done()
303304
})
@@ -316,7 +317,7 @@ describe('vue-loader', function () {
316317
new ExtractTextPlugin('test.output.css')
317318
]
318319
}, (code, warnings) => {
319-
var css = mfs.readFileSync('/test.output.css').toString()
320+
let css = mfs.readFileSync('/test.output.css').toString()
320321
css = normalizeNewline(css)
321322
expect(css).to.contain('h1 {\n color: #f00;\n}')
322323
expect(css).to.contain('h2 {\n color: green;\n}')
@@ -334,7 +335,7 @@ describe('vue-loader', function () {
334335
new ExtractTextPlugin('test.output.css')
335336
]
336337
}, (code, warnings) => {
337-
var css = mfs.readFileSync('/test.output.css').toString()
338+
let css = mfs.readFileSync('/test.output.css').toString()
338339
css = normalizeNewline(css)
339340
expect(css).to.contain('h1 {\n color: #f00;\n}')
340341
expect(css).to.contain('h2 {\n color: green;\n}')
@@ -353,7 +354,7 @@ describe('vue-loader', function () {
353354
plugin
354355
]
355356
}, (code, warnings) => {
356-
var css = mfs.readFileSync('/test.output.css').toString()
357+
let css = mfs.readFileSync('/test.output.css').toString()
357358
css = normalizeNewline(css)
358359
expect(css).to.contain('h1 {\n color: #f00;\n}')
359360
expect(css).to.contain('h2 {\n color: green;\n}')
@@ -366,12 +367,12 @@ describe('vue-loader', function () {
366367
entry: './test/fixtures/inject.js'
367368
}, (window) => {
368369
// console.log(window.injector.toString())
369-
var module = interopDefault(window.injector({
370+
const module = interopDefault(window.injector({
370371
'./service': {
371372
msg: 'Hello from mocked service!'
372373
}
373374
}))
374-
var vnode = mockRender(module, module.data())
375+
const vnode = mockRender(module, module.data())
375376
// <div class="msg">{{ msg }}</div>
376377
expect(vnode.tag).to.equal('div')
377378
expect(vnode.data.staticClass).to.equal('msg')
@@ -395,7 +396,7 @@ describe('vue-loader', function () {
395396
]
396397
}
397398
}, (window, module) => {
398-
var vnode = mockRender(module)
399+
const vnode = mockRender(module)
399400
// <div>
400401
// <img src="logo.c9e00e.png">
401402
// <img src="logo.c9e00e.png">
@@ -405,7 +406,7 @@ describe('vue-loader', function () {
405406
expect(vnode.children[2].tag).to.equal('img')
406407
expect(vnode.children[2].data.attrs.src).to.equal('logo.c9e00e.png')
407408

408-
var style = window.document.querySelector('style').textContent
409+
const style = window.document.querySelector('style').textContent
409410
expect(style).to.contain('html { background-image: url(logo.c9e00e.png);\n}')
410411
expect(style).to.contain('body { background-image: url(logo.c9e00e.png);\n}')
411412
done()
@@ -428,12 +429,12 @@ describe('vue-loader', function () {
428429
function includeDataURL (s) {
429430
return !!s.match(/\s*data:([a-z]+\/[a-z]+(;[a-z\-]+\=[a-z\-]+)?)?(;base64)?,[a-z0-9\!\$\&\'\,\(\)\*\+\,\;\=\-\.\_\~\:\@\/\?\%\s]*\s*/i)
430431
}
431-
var vnode = mockRender(module)
432+
const vnode = mockRender(module)
432433
// img tag
433434
expect(includeDataURL(vnode.children[0].data.attrs.src)).to.equal(true)
434435
// image tag (SVG)
435436
expect(includeDataURL(vnode.children[2].children[0].data.attrs['xlink:href'])).to.equal(true)
436-
var style = window.document.querySelector('style').textContent
437+
const style = window.document.querySelector('style').textContent
437438

438439
const dataURL = vnode.children[0].data.attrs.src
439440

@@ -461,7 +462,7 @@ describe('vue-loader', function () {
461462
}
462463
}
463464
}, (window) => {
464-
var style = window.document.querySelector('style').textContent
465+
let style = window.document.querySelector('style').textContent
465466
style = normalizeNewline(style)
466467
expect(style).to.contain('h1 {\n color: red;\n font-size: 14px\n}')
467468
done()
@@ -473,7 +474,7 @@ describe('vue-loader', function () {
473474
test({
474475
entry: './test/fixtures/postcss.vue'
475476
}, (window) => {
476-
var style = window.document.querySelector('style').textContent
477+
let style = window.document.querySelector('style').textContent
477478
style = normalizeNewline(style)
478479
expect(style).to.contain('h1 {\n color: red;\n font-size: 14px\n}')
479480
fs.unlinkSync('.postcssrc')
@@ -493,7 +494,7 @@ describe('vue-loader', function () {
493494
}
494495
}
495496
}, (window) => {
496-
var style = window.document.querySelector('style').textContent
497+
let style = window.document.querySelector('style').textContent
497498
style = normalizeNewline(style)
498499
expect(style).to.contain('h1 {\n color: red;\n font-size: 14px\n}')
499500
fs.unlinkSync('test/.postcssrc')
@@ -505,7 +506,7 @@ describe('vue-loader', function () {
505506
test({
506507
entry: './test/fixtures/es2015.vue'
507508
}, (window, module) => {
508-
var vnode = mockRender(module, {
509+
const vnode = mockRender(module, {
509510
a: 'hello',
510511
b: true
511512
})
@@ -522,7 +523,7 @@ describe('vue-loader', function () {
522523
entry: './test/fixtures/extend.vue'
523524
}, (window, Module) => {
524525
// extend.vue should export Vue constructor
525-
var vnode = mockRender(Module.options, {
526+
const vnode = mockRender(Module.options, {
526527
msg: 'success'
527528
})
528529
expect(vnode.tag).to.equal('div')
@@ -540,7 +541,7 @@ describe('vue-loader', function () {
540541
}
541542
}, (window, module, rawModule) => {
542543
expect(rawModule.__esModule).to.equal(true)
543-
var vnode = mockRender(rawModule.default, {
544+
const vnode = mockRender(rawModule.default, {
544545
msg: 'hi'
545546
})
546547
expect(vnode.tag).to.equal('h2')
@@ -563,27 +564,27 @@ describe('vue-loader', function () {
563564
}
564565
}, (window, module, raw, instance) => {
565566
// get local class name
566-
var className = instance.style.red
567+
const className = instance.style.red
567568
expect(className).to.match(regexToMatch)
568569

569570
// class name in style
570-
var style = [].slice.call(window.document.querySelectorAll('style')).map((style) => {
571+
let style = [].slice.call(window.document.querySelectorAll('style')).map((style) => {
571572
return style.textContent
572573
}).join('\n')
573574
style = normalizeNewline(style)
574575
expect(style).to.contain('.' + className + ' {\n color: red;\n}')
575576

576577
// animation name
577-
var match = style.match(/@keyframes\s+(\S+)\s+{/)
578+
const match = style.match(/@keyframes\s+(\S+)\s+{/)
578579
expect(match).to.have.length(2)
579-
var animationName = match[1]
580+
const animationName = match[1]
580581
expect(animationName).to.not.equal('fade')
581582
expect(style).to.contain('animation: ' + animationName + ' 1s;')
582583

583584
// default module + pre-processor + scoped
584-
var anotherClassName = instance.$style.red
585+
const anotherClassName = instance.$style.red
585586
expect(anotherClassName).to.match(regexToMatch).and.not.equal(className)
586-
var id = 'data-v-' + hash('vue-loader/test/fixtures/css-modules.vue')
587+
const id = 'data-v-' + genId('css-modules.vue')
587588
expect(style).to.contain('.' + anotherClassName + '[' + id + ']')
588589

589590
cb()
@@ -592,8 +593,8 @@ describe('vue-loader', function () {
592593
// default localIdentName
593594
testWithIdent(undefined, /^\w{23}/, () => {
594595
// specified localIdentName
595-
var ident = '[path][name]---[local]---[hash:base64:5]'
596-
var regex = /^test-fixtures-css-modules---red---\w{5}/
596+
const ident = '[path][name]---[local]---[hash:base64:5]'
597+
const regex = /^test-fixtures-css-modules---red---\w{5}/
597598
testWithIdent(ident, regex, done)
598599
})
599600
})
@@ -608,14 +609,14 @@ describe('vue-loader', function () {
608609
}, (code, warnings) => {
609610
// http://stackoverflow.com/questions/17581830/load-node-js-module-from-string-in-memory
610611
function requireFromString (src, filename) {
611-
var Module = module.constructor
612-
var m = new Module()
612+
const Module = module.constructor
613+
const m = new Module()
613614
m._compile(src, filename)
614615
return m.exports
615616
}
616617

617-
var output = interopDefault(requireFromString(code, './test.build.js'))
618-
var mockInstance = {}
618+
const output = interopDefault(requireFromString(code, './test.build.js'))
619+
const mockInstance = {}
619620

620621
output.beforeCreate.forEach(hook => hook.call(mockInstance))
621622
expect(mockInstance.style.red).to.exist
@@ -633,7 +634,7 @@ describe('vue-loader', function () {
633634
}
634635
}
635636
}, (window, module) => {
636-
var vnode = mockRender(module, {
637+
const vnode = mockRender(module, {
637638
msg: 'hi'
638639
})
639640
// <h2 id="-msg-">{{msg}}</h2>
@@ -713,7 +714,7 @@ describe('vue-loader', function () {
713714
new ExtractTextPlugin('doc.md')
714715
]
715716
}, (code, warnings) => {
716-
var unitTest = mfs.readFileSync('/doc.md').toString()
717+
let unitTest = mfs.readFileSync('/doc.md').toString()
717718
unitTest = normalizeNewline(unitTest)
718719
expect(unitTest).to.contain('This is example documentation for a component.')
719720
done()
@@ -814,7 +815,7 @@ describe('vue-loader', function () {
814815
}
815816
}
816817
}, (window, module) => {
817-
var vnode = mockRender(module, {
818+
const vnode = mockRender(module, {
818819
msg: 'hi'
819820
})
820821
// <h2 class="green">{{msg}}</h2>
@@ -823,7 +824,7 @@ describe('vue-loader', function () {
823824
expect(vnode.children[0].text).to.equal('hi')
824825

825826
expect(module.data().msg).to.contain('Changed!')
826-
var style = window.document.querySelector('style').textContent
827+
let style = window.document.querySelector('style').textContent
827828
style = normalizeNewline(style)
828829
expect(style).to.contain('comp-a h2 {\n color: #00f;\n}')
829830
done()
@@ -846,7 +847,7 @@ describe('vue-loader', function () {
846847
}
847848
}
848849
}, (window, module) => {
849-
var vnode = mockRender(module, {
850+
const vnode = mockRender(module, {
850851
msg: JSON.parse(module.__i18n).en.hello,
851852
blog: module.__blog
852853
})
@@ -874,7 +875,7 @@ describe('vue-loader', function () {
874875
]
875876
}
876877
}, (window, module) => {
877-
var results = []
878+
const results = []
878879
// var vnode =
879880
mockRender(
880881
Object.assign(module, { methods: { $processStyle: style => results.push(style) }}),
@@ -895,7 +896,7 @@ describe('vue-loader', function () {
895896
compilerModules: require.resolve('./fixtures/custom-module')
896897
}
897898
}, (window, module) => {
898-
var vnode = mockRender(module, {
899+
const vnode = mockRender(module, {
899900
msg: 'hi'
900901
})
901902
expect(vnode.data.staticClass).to.equal('red blue')
@@ -920,7 +921,7 @@ describe('vue-loader', function () {
920921
}
921922
}
922923
}, (window, module) => {
923-
var vnode = mockRender(module)
924+
const vnode = mockRender(module)
924925
expect(vnode.data.domProps.textContent).to.equal('keypath')
925926
done()
926927
})
@@ -931,13 +932,13 @@ describe('vue-loader', function () {
931932
entry: './test/fixtures/functional-style.vue'
932933
}, (window, module, rawModule) => {
933934
expect(module.functional).to.equal(true)
934-
var vnode = mockRender(module)
935+
const vnode = mockRender(module)
935936
// <div class="foo">hi</div>
936937
expect(vnode.tag).to.equal('div')
937938
expect(vnode.data.class).to.equal('foo')
938939
expect(vnode.children[0].text).to.equal('functional')
939940

940-
var style = window.document.querySelector('style').textContent
941+
let style = window.document.querySelector('style').textContent
941942
style = normalizeNewline(style)
942943
expect(style).to.contain('.foo { color: red;\n}')
943944
done()
@@ -949,7 +950,7 @@ describe('vue-loader', function () {
949950
entry: './test/fixtures/template-comment.vue'
950951
}, (window, module, rawModule) => {
951952
expect(module.comments).to.equal(true)
952-
var vnode = mockRender(module, {
953+
const vnode = mockRender(module, {
953954
msg: 'hi'
954955
})
955956
expect(vnode.tag).to.equal('div')
@@ -969,7 +970,7 @@ describe('vue-loader', function () {
969970
cacheBusting: false
970971
}
971972
}, (window, module, rawModule) => {
972-
var vnode = mockRender(module, {
973+
const vnode = mockRender(module, {
973974
msg: 'hi'
974975
})
975976

@@ -979,7 +980,7 @@ describe('vue-loader', function () {
979980
expect(vnode.children[0].text).to.equal('hi')
980981

981982
expect(module.data().msg).to.contain('Hello from Component A!')
982-
var style = window.document.querySelector('style').textContent
983+
let style = window.document.querySelector('style').textContent
983984
style = normalizeNewline(style)
984985
expect(style).to.contain('comp-a h2 {\n color: #f00;\n}')
985986
done()

0 commit comments

Comments
 (0)
Please sign in to comment.