Skip to content

Commit 9c1e797

Browse files
authored
feat: support dart-sass as default sass implementation (#3321)
1 parent 9029ad1 commit 9c1e797

File tree

13 files changed

+201
-15
lines changed

13 files changed

+201
-15
lines changed

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ test('default loaders', () => {
6262
})
6363
})
6464
// sass indented syntax
65-
expect(findOptions(config, 'sass', 'sass')).toEqual({ indentedSyntax: true, sourceMap: false })
65+
expect(findOptions(config, 'sass', 'sass')).toMatchObject({ indentedSyntax: true, sourceMap: false })
6666
})
6767

6868
test('production defaults', () => {
@@ -193,8 +193,14 @@ test('css.loaderOptions', () => {
193193
}
194194
})
195195

196-
expect(findOptions(config, 'scss', 'sass')).toEqual({ data, sourceMap: false })
197-
expect(findOptions(config, 'sass', 'sass')).toEqual({ data, indentedSyntax: true, sourceMap: false })
196+
expect(findOptions(config, 'scss', 'sass')).toMatchObject({ data, sourceMap: false })
197+
expect(findOptions(config, 'sass', 'sass')).toMatchObject({ data, indentedSyntax: true, sourceMap: false })
198+
})
199+
200+
test('should use dart sass implementation whenever possible', () => {
201+
const config = genConfig()
202+
expect(findOptions(config, 'scss', 'sass')).toMatchObject({ fiber: require('fibers'), implementation: require('sass') })
203+
expect(findOptions(config, 'sass', 'sass')).toMatchObject({ fiber: require('fibers'), implementation: require('sass') })
198204
})
199205

200206
test('skip postcss-loader if no postcss config found', () => {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
const generateWithPlugin = require('@vue/cli-test-utils/generateWithPlugin')
2+
3+
test('node sass (legacy)', async () => {
4+
const { pkg, files } = await generateWithPlugin([
5+
{
6+
id: '@vue/cli-service',
7+
apply: require('../generator'),
8+
options: {
9+
cssPreprocessor: 'sass'
10+
}
11+
}
12+
])
13+
14+
expect(files['src/App.vue']).toMatch('<style lang="scss">')
15+
expect(pkg).toHaveProperty(['devDependencies', 'node-sass'])
16+
})
17+
18+
test('node sass', async () => {
19+
const { pkg, files } = await generateWithPlugin([
20+
{
21+
id: '@vue/cli-service',
22+
apply: require('../generator'),
23+
options: {
24+
cssPreprocessor: 'node-sass'
25+
}
26+
}
27+
])
28+
29+
expect(files['src/App.vue']).toMatch('<style lang="scss">')
30+
expect(pkg).toHaveProperty(['devDependencies', 'node-sass'])
31+
})
32+
33+
test('dart sass', async () => {
34+
const { pkg, files } = await generateWithPlugin([
35+
{
36+
id: '@vue/cli-service',
37+
apply: require('../generator'),
38+
options: {
39+
cssPreprocessor: 'dart-sass'
40+
}
41+
}
42+
])
43+
44+
expect(files['src/App.vue']).toMatch('<style lang="scss">')
45+
expect(pkg).toHaveProperty(['devDependencies', 'sass'])
46+
expect(pkg).toHaveProperty(['devDependencies', 'fibers'])
47+
})

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,14 @@ test('serve with no public dir', async () => {
9393
}
9494
)
9595
})
96+
97+
test('dart sass', async () => {
98+
const project = await create('test-dart-sass', exports.defaultPreset = {
99+
useConfigFiles: false,
100+
cssPreprocessor: 'dart-sass',
101+
plugins: {}
102+
})
103+
104+
// should build successfully
105+
await project.run('vue-cli-service build')
106+
})

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,19 @@ module.exports = (api, options) => {
3636

3737
if (options.cssPreprocessor) {
3838
const deps = {
39+
// TODO: remove 'sass' option in v4 or rename 'dart-sass' to 'sass'
3940
sass: {
4041
'node-sass': '^4.9.0',
41-
'sass-loader': '^7.0.1'
42+
'sass-loader': '^7.1.0'
43+
},
44+
'node-sass': {
45+
'node-sass': '^4.9.0',
46+
'sass-loader': '^7.1.0'
47+
},
48+
'dart-sass': {
49+
fibers: '^3.1.1',
50+
sass: '^1.16.0',
51+
'sass-loader': '^7.1.0'
4252
},
4353
less: {
4454
'less': '^3.0.4',

packages/@vue/cli-service/generator/template/src/App.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export default {
3939
<style<%-
4040
rootOptions.cssPreprocessor
4141
? ` lang="${
42-
rootOptions.cssPreprocessor === 'sass'
42+
rootOptions.cssPreprocessor.includes('sass')
4343
? 'scss'
4444
: rootOptions.cssPreprocessor
4545
}"`

packages/@vue/cli-service/generator/template/src/components/HelloWorld.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export default {
4646
<style scoped<%-
4747
rootOptions.cssPreprocessor
4848
? ` lang="${
49-
rootOptions.cssPreprocessor === 'sass'
49+
rootOptions.cssPreprocessor.includes('sass')
5050
? 'scss'
5151
: rootOptions.cssPreprocessor
5252
}"`

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ module.exports = (api, options) => {
1515
const shadowMode = !!process.env.VUE_CLI_CSS_SHADOW_MODE
1616
const isProd = process.env.NODE_ENV === 'production'
1717

18+
const defaultSassLoaderOptions = {}
19+
try {
20+
defaultSassLoaderOptions.implementation = require('sass')
21+
defaultSassLoaderOptions.fiber = require('fibers')
22+
} catch (e) {}
23+
1824
const {
1925
modules = false,
2026
extract = isProd,
@@ -158,8 +164,8 @@ module.exports = (api, options) => {
158164

159165
createCSSRule('css', /\.css$/)
160166
createCSSRule('postcss', /\.p(ost)?css$/)
161-
createCSSRule('scss', /\.scss$/, 'sass-loader', loaderOptions.sass)
162-
createCSSRule('sass', /\.sass$/, 'sass-loader', Object.assign({
167+
createCSSRule('scss', /\.scss$/, 'sass-loader', Object.assign(defaultSassLoaderOptions, loaderOptions.sass))
168+
createCSSRule('sass', /\.sass$/, 'sass-loader', Object.assign(defaultSassLoaderOptions, {
163169
indentedSyntax: true
164170
}, loaderOptions.sass))
165171
createCSSRule('less', /\.less$/, 'less-loader', loaderOptions.less)

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676
"vue-template-compiler": "^2.0.0"
7777
},
7878
"devDependencies": {
79+
"fibers": "^3.1.1",
80+
"sass": "^1.16.1",
81+
"sass-loader": "^7.1.0",
7982
"vue": "^2.5.21",
8083
"vue-router": "^3.0.1",
8184
"vue-template-compiler": "^2.5.21",

packages/@vue/cli/lib/options.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ const presetSchema = createSchema(joi => joi.object().keys({
1313
router: joi.boolean(),
1414
routerHistoryMode: joi.boolean(),
1515
vuex: joi.boolean(),
16-
cssPreprocessor: joi.string().only(['sass', 'less', 'stylus']),
16+
// TODO: remove 'sass' or make it equivalent to 'dart-sass' in v4
17+
cssPreprocessor: joi.string().only(['sass', 'dart-sass', 'node-sass', 'less', 'stylus']),
1718
plugins: joi.object().required(),
1819
configs: joi.object()
1920
}))

packages/@vue/cli/lib/promptModules/__tests__/cssPreprocessors.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ test('CSS pre-processor ', async () => {
1414
},
1515
{
1616
message: 'Pick a CSS pre-processor',
17-
choices: ['Sass', 'Less', 'Stylus'],
17+
choices: ['Sass/SCSS (with dart-sass)', 'Sass/SCSS (with node-sass)', 'Less', 'Stylus'],
1818
choose: 0
1919
}
2020
]
2121

2222
const expectedOptions = {
23-
cssPreprocessor: 'sass',
23+
cssPreprocessor: 'dart-sass',
2424
plugins: {}
2525
}
2626

0 commit comments

Comments
 (0)