Skip to content
This repository was archived by the owner on Aug 16, 2022. It is now read-only.

Commit b8bfc58

Browse files
authored
fix: produce deterministic css class names for css modules (#101)
* fix: add missing ts definitions, fix ts errors * fix: return correct class name for css modules in PROD mode
1 parent 91dbdf5 commit b8bfc58

File tree

7 files changed

+209
-14
lines changed

7 files changed

+209
-14
lines changed

Diff for: .gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ node_modules
33
/dist
44
*.log
55
/test/output/
6+
.idea
7+
.vscode

Diff for: package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -32,30 +32,30 @@
3232
"homepage": "https://github.com/vuejs/vue-component-compiler#readme",
3333
"devDependencies": {
3434
"@types/clean-css": "^3.4.30",
35-
"@types/jest": "^22.2.3",
35+
"@types/jest": "^25.2.3",
3636
"@types/node": "^9.4.7",
3737
"babel-plugin-external-helpers": "^6.22.0",
3838
"babel-preset-env": "^1.6.1",
3939
"conventional-changelog": "^1.1.24",
4040
"jest": "^22.4.2",
41-
"sass": "^1.18.0",
4241
"pug": "^2.0.3",
4342
"puppeteer": "^1.3.0",
4443
"rollup": "^0.58.2",
4544
"rollup-plugin-babel": "^3.0.4",
4645
"rollup-plugin-commonjs": "^9.1.0",
4746
"rollup-plugin-image": "^1.0.2",
4847
"rollup-plugin-node-resolve": "^3.3.0",
48+
"sass": "^1.18.0",
4949
"ts-jest": "^22.4.2",
5050
"typescript": "^3.2.4",
5151
"typescript-eslint-parser": "^15.0.0",
5252
"vue": "^2.5.16",
5353
"vue-template-compiler": "^2.5.16"
5454
},
5555
"optionalDependencies": {
56-
"sass": "^1.18.0",
57-
"pug": "^2.0.3",
5856
"less": "^3.9.0",
57+
"pug": "^2.0.3",
58+
"sass": "^1.18.0",
5959
"stylus": "^0.54.5"
6060
},
6161
"peerDependencies": {

Diff for: src/compiler.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,6 @@ export class SFCCompiler {
232232
const postcssPlugins = (this.style.postcssPlugins || [])
233233
.slice()
234234
.concat([
235-
needsCleanCSS
236-
? postcssClean(this.style.postcssCleanOptions)
237-
: undefined,
238235
needsCSSModules
239236
? postcssModules({
240237
generateScopedName: '[path][local]-[hash:base64:4]',
@@ -244,9 +241,12 @@ export class SFCCompiler {
244241
}
245242
})
246243
: undefined,
244+
needsCleanCSS
245+
? postcssClean(this.style.postcssCleanOptions)
246+
: undefined,
247247
])
248248
.filter(Boolean)
249-
249+
250250
const preprocessOptions =
251251
(style.lang &&
252252
this.style.preprocessOptions &&

Diff for: src/postcss-clean.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as postcss from 'postcss'
2-
import CleanCSS = require('clean-css')
2+
import CleanCSS from 'clean-css'
33

4-
export default postcss.plugin('clean', options => {
4+
export default postcss.plugin('clean', (options: any) => {
55
const clean = new CleanCSS({ compatibility: 'ie9', ...options })
66

77
return (css: any, res: any) => {

Diff for: test/compile.spec.ts

+61
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,64 @@ function removeRawResult(result: DescriptorCompileResult): DescriptorCompileResu
6060

6161
return result
6262
}
63+
64+
describe('when source contains css module', () => {
65+
const componentSource = `
66+
<template>
67+
<h1 id="test" :class="$style.title">Hello {{ name }}!</h1>
68+
</template>
69+
70+
<script>
71+
export default {
72+
data () {
73+
return { name: 'John Doe' }
74+
}
75+
}
76+
</script>
77+
78+
<style module>
79+
.title {
80+
color: red;
81+
}
82+
</style>
83+
`
84+
85+
86+
describe('production mode', () => {
87+
const prodCompiler = createDefaultCompiler(({
88+
template: {
89+
isProduction: true
90+
}
91+
}) as any)
92+
93+
it('should generate deterministic class names when the same component is compiled multiple times', () => {
94+
95+
const result1 = prodCompiler.compileToDescriptor('foo.vue', componentSource)
96+
const result2 = prodCompiler.compileToDescriptor('foo.vue', componentSource)
97+
98+
const styles1 = result1.styles[0].code;
99+
const styles2 = result2.styles[0].code;
100+
101+
expect(styles1).toEqual(styles2)
102+
})
103+
})
104+
105+
describe('develop mode', () => {
106+
const devCompiler = createDefaultCompiler(({
107+
template: {
108+
isProduction: false
109+
}
110+
}) as any)
111+
112+
it('should generate deterministic class names when the same component is compiled multiple times', () => {
113+
114+
const result1 = devCompiler.compileToDescriptor('foo.vue', componentSource)
115+
const result2 = devCompiler.compileToDescriptor('foo.vue', componentSource)
116+
117+
const styles1 = result1.styles[0].code;
118+
const styles2 = result2.styles[0].code;
119+
120+
expect(styles1).toEqual(styles2)
121+
})
122+
})
123+
})

Diff for: tsconfig.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
"strictNullChecks": true,
1414
"noImplicitAny": true,
1515
"removeComments": false,
16-
"lib": ["es6", "es7"]
16+
"lib": ["es6", "es7"],
17+
"types": ["@types/jest", "node"]
1718
},
1819
"include": ["src", "typings"]
1920
}

Diff for: yarn.lock

+134-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@
1616
esutils "^2.0.2"
1717
js-tokens "^3.0.0"
1818

19+
"@jest/types@^25.5.0":
20+
version "25.5.0"
21+
resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d"
22+
integrity sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==
23+
dependencies:
24+
"@types/istanbul-lib-coverage" "^2.0.0"
25+
"@types/istanbul-reports" "^1.1.1"
26+
"@types/yargs" "^15.0.0"
27+
chalk "^3.0.0"
28+
1929
"@types/babel-types@*", "@types/babel-types@^7.0.0":
2030
version "7.0.1"
2131
resolved "https://registry.yarnpkg.com/@types/babel-types/-/babel-types-7.0.1.tgz#1405e5396968c4302994b0161ce405b72b874257"
@@ -30,13 +40,42 @@
3040
version "3.4.30"
3141
resolved "https://registry.yarnpkg.com/@types/clean-css/-/clean-css-3.4.30.tgz#0052c136f5248002428e3638b37de4a39818641d"
3242

43+
"@types/color-name@^1.1.1":
44+
version "1.1.1"
45+
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
46+
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
47+
3348
3449
version "0.0.38"
3550
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.38.tgz#c1be40aa933723c608820a99a373a16d215a1ca2"
3651

37-
"@types/jest@^22.2.3":
38-
version "22.2.3"
39-
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-22.2.3.tgz#0157c0316dc3722c43a7b71de3fdf3acbccef10d"
52+
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
53+
version "2.0.2"
54+
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz#79d7a78bad4219f4c03d6557a1c72d9ca6ba62d5"
55+
integrity sha512-rsZg7eL+Xcxsxk2XlBt9KcG8nOp9iYdKCOikY9x2RFJCyOdNj4MKPQty0e8oZr29vVAzKXr1BmR+kZauti3o1w==
56+
57+
"@types/istanbul-lib-report@*":
58+
version "3.0.0"
59+
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686"
60+
integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==
61+
dependencies:
62+
"@types/istanbul-lib-coverage" "*"
63+
64+
"@types/istanbul-reports@^1.1.1":
65+
version "1.1.2"
66+
resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz#e875cc689e47bce549ec81f3df5e6f6f11cfaeb2"
67+
integrity sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==
68+
dependencies:
69+
"@types/istanbul-lib-coverage" "*"
70+
"@types/istanbul-lib-report" "*"
71+
72+
"@types/jest@^25.2.3":
73+
version "25.2.3"
74+
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-25.2.3.tgz#33d27e4c4716caae4eced355097a47ad363fdcaf"
75+
integrity sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==
76+
dependencies:
77+
jest-diff "^25.2.1"
78+
pretty-format "^25.2.1"
4079

4180
"@types/node@*":
4281
version "10.0.0"
@@ -46,6 +85,18 @@
4685
version "9.6.7"
4786
resolved "https://registry.yarnpkg.com/@types/node/-/node-9.6.7.tgz#5f3816d1db2155edcde1b2e3aa5d0e5c520cb564"
4887

88+
"@types/yargs-parser@*":
89+
version "15.0.0"
90+
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d"
91+
integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==
92+
93+
"@types/yargs@^15.0.0":
94+
version "15.0.5"
95+
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.5.tgz#947e9a6561483bdee9adffc983e91a6902af8b79"
96+
integrity sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==
97+
dependencies:
98+
"@types/yargs-parser" "*"
99+
49100
"@vue/component-compiler-utils@^3.0.0":
50101
version "3.0.0"
51102
resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.0.0.tgz#d16fa26b836c06df5baaeb45f3d80afc47e35634"
@@ -140,6 +191,11 @@ ansi-regex@^3.0.0:
140191
version "3.0.0"
141192
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
142193

194+
ansi-regex@^5.0.0:
195+
version "5.0.0"
196+
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
197+
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
198+
143199
ansi-styles@^2.2.1:
144200
version "2.2.1"
145201
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
@@ -151,6 +207,14 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1:
151207
dependencies:
152208
color-convert "^1.9.0"
153209

210+
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
211+
version "4.2.1"
212+
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359"
213+
integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==
214+
dependencies:
215+
"@types/color-name" "^1.1.1"
216+
color-convert "^2.0.1"
217+
154218
anymatch@^1.3.0:
155219
version "1.3.2"
156220
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
@@ -991,6 +1055,14 @@ chalk@^2.3.2, chalk@^2.4.2:
9911055
escape-string-regexp "^1.0.5"
9921056
supports-color "^5.3.0"
9931057

1058+
chalk@^3.0.0:
1059+
version "3.0.0"
1060+
resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
1061+
integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
1062+
dependencies:
1063+
ansi-styles "^4.1.0"
1064+
supports-color "^7.1.0"
1065+
9941066
character-parser@^2.1.1:
9951067
version "2.2.0"
9961068
resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0"
@@ -1097,11 +1169,23 @@ color-convert@^1.9.0:
10971169
dependencies:
10981170
color-name "1.1.3"
10991171

1172+
color-convert@^2.0.1:
1173+
version "2.0.1"
1174+
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
1175+
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
1176+
dependencies:
1177+
color-name "~1.1.4"
1178+
11001179
11011180
version "1.1.3"
11021181
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
11031182
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
11041183

1184+
color-name@~1.1.4:
1185+
version "1.1.4"
1186+
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
1187+
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
1188+
11051189
[email protected], combined-stream@~1.0.5:
11061190
version "1.0.6"
11071191
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818"
@@ -1502,6 +1586,11 @@ detect-newline@^2.1.0:
15021586
version "2.1.0"
15031587
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
15041588

1589+
diff-sequences@^25.2.6:
1590+
version "25.2.6"
1591+
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd"
1592+
integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==
1593+
15051594
diff@^3.2.0:
15061595
version "3.5.0"
15071596
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
@@ -2060,6 +2149,11 @@ has-flag@^3.0.0:
20602149
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
20612150
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
20622151

2152+
has-flag@^4.0.0:
2153+
version "4.0.0"
2154+
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
2155+
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
2156+
20632157
has-unicode@^2.0.0:
20642158
version "2.0.1"
20652159
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -2632,6 +2726,16 @@ jest-diff@^22.4.3:
26322726
jest-get-type "^22.4.3"
26332727
pretty-format "^22.4.3"
26342728

2729+
jest-diff@^25.2.1:
2730+
version "25.5.0"
2731+
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.5.0.tgz#1dd26ed64f96667c068cef026b677dfa01afcfa9"
2732+
integrity sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==
2733+
dependencies:
2734+
chalk "^3.0.0"
2735+
diff-sequences "^25.2.6"
2736+
jest-get-type "^25.2.6"
2737+
pretty-format "^25.5.0"
2738+
26352739
jest-docblock@^22.4.3:
26362740
version "22.4.3"
26372741
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-22.4.3.tgz#50886f132b42b280c903c592373bb6e93bb68b19"
@@ -2657,6 +2761,11 @@ jest-get-type@^22.4.3:
26572761
version "22.4.3"
26582762
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4"
26592763

2764+
jest-get-type@^25.2.6:
2765+
version "25.2.6"
2766+
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877"
2767+
integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==
2768+
26602769
jest-haste-map@^22.4.3:
26612770
version "22.4.3"
26622771
resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-22.4.3.tgz#25842fa2ba350200767ac27f658d58b9d5c2e20b"
@@ -3764,6 +3873,16 @@ pretty-format@^22.4.3:
37643873
ansi-regex "^3.0.0"
37653874
ansi-styles "^3.2.0"
37663875

3876+
pretty-format@^25.2.1, pretty-format@^25.5.0:
3877+
version "25.5.0"
3878+
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.5.0.tgz#7873c1d774f682c34b8d48b6743a2bf2ac55791a"
3879+
integrity sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==
3880+
dependencies:
3881+
"@jest/types" "^25.5.0"
3882+
ansi-regex "^5.0.0"
3883+
ansi-styles "^4.0.0"
3884+
react-is "^16.12.0"
3885+
37673886
private@^0.1.6, private@^0.1.8:
37683887
version "0.1.8"
37693888
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
@@ -3948,6 +4067,11 @@ rc@^1.2.7:
39484067
minimist "^1.2.0"
39494068
strip-json-comments "~2.0.1"
39504069

4070+
react-is@^16.12.0:
4071+
version "16.13.1"
4072+
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
4073+
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
4074+
39514075
read-pkg-up@^1.0.1:
39524076
version "1.0.1"
39534077
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
@@ -4612,6 +4736,13 @@ supports-color@^6.1.0:
46124736
dependencies:
46134737
has-flag "^3.0.0"
46144738

4739+
supports-color@^7.1.0:
4740+
version "7.1.0"
4741+
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1"
4742+
integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==
4743+
dependencies:
4744+
has-flag "^4.0.0"
4745+
46154746
symbol-tree@^3.2.2:
46164747
version "3.2.2"
46174748
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"

0 commit comments

Comments
 (0)