Skip to content

Commit b156ff1

Browse files
authored
Merge pull request vuejs#4554 from sodatea/sass-loader-8
Support sass-loader v8
2 parents 59adbd6 + 59d6a7c commit b156ff1

File tree

8 files changed

+123
-82
lines changed

8 files changed

+123
-82
lines changed

docs/guide/css.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,17 @@ module.exports = {
133133
// pass options to sass-loader
134134
// @/ is an alias to src/
135135
// so this assumes you have a file named `src/variables.sass`
136+
// Note: this option is named as "data" in sass-loader v7
136137
sass: {
137-
data: `@import "~@/variables.sass"`
138+
prependData: `@import "~@/variables.sass"`
138139
},
139140
// by default the `sass` option will apply to both syntaxes
140141
// because `scss` syntax is also processed by sass-loader underlyingly
141142
// but when configuring the `data` option
142143
// `scss` syntax requires an semicolon at the end of a statement, while `sass` syntax requires none
143144
// in that case, we can target the `scss` syntax separately using the `scss` option
144145
scss: {
145-
data: `@import "~@/variables.scss";`
146+
prependData: `@import "~@/variables.scss";`
146147
},
147148
// pass Less.js Options to less-loader
148149
less:{

docs/zh/guide/css.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,16 @@ module.exports = {
121121
sass: {
122122
// @/ 是 src/ 的别名
123123
// 所以这里假设你有 `src/variables.sass` 这个文件
124-
data: `@import "~@/variables.sass"`
124+
// 注意:在 sass-loader v7 中,这个选项名是 "data"
125+
prependData: `@import "~@/variables.sass"`
125126
},
126127
// 默认情况下 `sass` 选项会同时对 `sass` 和 `scss` 语法同时生效
127128
// 因为 `scss` 语法在内部也是由 sass-loader 处理的
128129
// 但是在配置 `data` 选项的时候
129130
// `scss` 语法会要求语句结尾必须有分号,`sass` 则要求必须没有分号
130131
// 在这种情况下,我们可以使用 `scss` 选项,对 `scss` 语法进行单独配置
131132
scss: {
132-
data: `@import "~@/variables.scss";`
133+
prependData: `@import "~@/variables.scss";`
133134
},
134135
// 给 less-loader 传递 Less.js 相关选项
135136
less:{

packages/@vue/cli-service/__tests__/css.spec.js

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,12 @@ test('default loaders', () => {
6767
})
6868
})
6969
// sass indented syntax
70-
expect(findOptions(config, 'sass', 'sass')).toMatchObject({ indentedSyntax: true, sourceMap: false })
70+
expect(findOptions(config, 'sass', 'sass')).toMatchObject({
71+
sassOptions: {
72+
indentedSyntax: true
73+
},
74+
sourceMap: false
75+
})
7176
})
7277

7378
test('production defaults', () => {
@@ -296,21 +301,30 @@ test('css-loader options', () => {
296301
})
297302

298303
test('css.loaderOptions', () => {
299-
const data = '$env: production;'
304+
const prependData = '$env: production;'
300305
const config = genConfig({
301306
vue: {
302307
css: {
303308
loaderOptions: {
304309
sass: {
305-
data
310+
prependData
306311
}
307312
}
308313
}
309314
}
310315
})
311316

312-
expect(findOptions(config, 'scss', 'sass')).toMatchObject({ data, sourceMap: false })
313-
expect(findOptions(config, 'sass', 'sass')).toMatchObject({ data, indentedSyntax: true, sourceMap: false })
317+
expect(findOptions(config, 'scss', 'sass')).toMatchObject({
318+
prependData,
319+
sourceMap: false
320+
})
321+
expect(findOptions(config, 'sass', 'sass')).toMatchObject({
322+
prependData,
323+
sassOptions: {
324+
indentedSyntax: true
325+
},
326+
sourceMap: false
327+
})
314328
})
315329

316330
test('scss loaderOptions', () => {
@@ -322,24 +336,33 @@ test('scss loaderOptions', () => {
322336
css: {
323337
loaderOptions: {
324338
sass: {
325-
sassData
339+
prependData: sassData
326340
},
327341
scss: {
328-
scssData
342+
prependData: scssData
329343
}
330344
}
331345
}
332346
}
333347
})
334348

335-
expect(findOptions(config, 'scss', 'sass')).toMatchObject({ scssData, sourceMap: false })
336-
expect(findOptions(config, 'sass', 'sass')).toMatchObject({ sassData, indentedSyntax: true, sourceMap: false })
349+
expect(findOptions(config, 'scss', 'sass')).toMatchObject({
350+
prependData: scssData,
351+
sourceMap: false
352+
})
353+
expect(findOptions(config, 'sass', 'sass')).toMatchObject({
354+
prependData: sassData,
355+
sassOptions: {
356+
indentedSyntax: true
357+
},
358+
sourceMap: false
359+
})
337360
})
338361

339362
test('should use dart sass implementation whenever possible', () => {
340363
const config = genConfig()
341-
expect(findOptions(config, 'scss', 'sass')).toMatchObject({ fiber: require('fibers'), implementation: require('sass') })
342-
expect(findOptions(config, 'sass', 'sass')).toMatchObject({ fiber: require('fibers'), implementation: require('sass') })
364+
expect(findOptions(config, 'scss', 'sass')).toMatchObject({ implementation: require('sass') })
365+
expect(findOptions(config, 'sass', 'sass')).toMatchObject({ implementation: require('sass') })
343366
})
344367

345368
test('skip postcss-loader if no postcss config found', () => {

packages/@vue/cli-service/generator/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ module.exports = (api, options) => {
2929
const deps = {
3030
sass: {
3131
sass: '^1.19.0',
32-
'sass-loader': '^7.1.0'
32+
'sass-loader': '^8.0.0'
3333
},
3434
'node-sass': {
3535
'node-sass': '^4.12.0',
36-
'sass-loader': '^7.1.0'
36+
'sass-loader': '^8.0.0'
3737
},
3838
'dart-sass': {
3939
sass: '^1.19.0',
40-
'sass-loader': '^7.1.0'
40+
'sass-loader': '^8.0.0'
4141
},
4242
less: {
4343
'less': '^3.0.4',

packages/@vue/cli-service/lib/config/css.js

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
const fs = require('fs')
22
const path = require('path')
3+
const semver = require('semver')
4+
const { warn, pauseSpinner, resumeSpinner } = require('@vue/cli-shared-utils')
35

46
const findExisting = (context, files) => {
57
for (const file of files) {
@@ -15,10 +17,23 @@ module.exports = (api, rootOptions) => {
1517
const shadowMode = !!process.env.VUE_CLI_CSS_SHADOW_MODE
1618
const isProd = process.env.NODE_ENV === 'production'
1719

20+
let sassLoaderVersion
21+
try {
22+
sassLoaderVersion = semver.major(require('sass-loader/package.json').version)
23+
} catch (e) {}
24+
if (sassLoaderVersion < 8) {
25+
pauseSpinner()
26+
warn('A new version of sass-loader is available. Please upgrade for best experience.')
27+
resumeSpinner()
28+
}
29+
1830
const defaultSassLoaderOptions = {}
1931
try {
2032
defaultSassLoaderOptions.implementation = require('sass')
21-
defaultSassLoaderOptions.fiber = require('fibers')
33+
// since sass-loader 8, fibers will be automatically detected and used
34+
if (sassLoaderVersion < 8) {
35+
defaultSassLoaderOptions.fiber = require('fibers')
36+
}
2237
} catch (e) {}
2338

2439
const {
@@ -175,13 +190,28 @@ module.exports = (api, rootOptions) => {
175190
defaultSassLoaderOptions,
176191
loaderOptions.scss || loaderOptions.sass
177192
))
178-
createCSSRule('sass', /\.sass$/, 'sass-loader', Object.assign(
179-
defaultSassLoaderOptions,
180-
{
181-
indentedSyntax: true
182-
},
183-
loaderOptions.sass
184-
))
193+
if (sassLoaderVersion < 8) {
194+
createCSSRule('sass', /\.sass$/, 'sass-loader', Object.assign(
195+
defaultSassLoaderOptions,
196+
{
197+
indentedSyntax: true
198+
},
199+
loaderOptions.sass
200+
))
201+
} else {
202+
createCSSRule('sass', /\.sass$/, 'sass-loader', Object.assign(
203+
defaultSassLoaderOptions,
204+
loaderOptions.sass,
205+
{
206+
sassOptions: Object.assign(
207+
(loaderOptions.sass && loaderOptions.sass.sassOptions) || {},
208+
{
209+
indentedSyntax: true
210+
}
211+
)
212+
}
213+
))
214+
}
185215
createCSSRule('less', /\.less$/, 'less-loader', loaderOptions.less)
186216
createCSSRule('stylus', /\.styl(us)?$/, 'stylus-loader', Object.assign({
187217
preferPathResolver: 'webpack'

packages/@vue/cli-service/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
"devDependencies": {
8686
"fibers": ">= 3.1.1 <5.0.0",
8787
"sass": "^1.19.0",
88-
"sass-loader": "^7.1.0",
88+
"sass-loader": "^8.0.0",
8989
"vue": "^2.6.10",
9090
"vue-router": "^3.0.6",
9191
"vue-template-compiler": "^2.6.10",

packages/@vue/cli-shared-utils/lib/spinner.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const chalk = require('chalk')
33

44
const spinner = ora()
55
let lastMsg = null
6+
let isPaused = false
67

78
exports.logWithSpinner = (symbol, msg) => {
89
if (!msg) {
@@ -36,11 +37,17 @@ exports.stopSpinner = (persist) => {
3637
}
3738

3839
exports.pauseSpinner = () => {
39-
spinner.stop()
40+
if (spinner.isSpinning) {
41+
spinner.stop()
42+
isPaused = true
43+
}
4044
}
4145

4246
exports.resumeSpinner = () => {
43-
spinner.start()
47+
if (isPaused) {
48+
spinner.start()
49+
isPaused = false
50+
}
4451
}
4552

4653
exports.failSpinner = (text) => {

0 commit comments

Comments
 (0)