Skip to content

Commit fc98c13

Browse files
authored
Warn on duplicate Sass deps (#16398)
Fixes #13953
1 parent 3dec500 commit fc98c13

File tree

10 files changed

+82
-0
lines changed

10 files changed

+82
-0
lines changed

errors/duplicate-sass.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Duplicate Sass Dependencies
2+
3+
#### Why This Error Occurred
4+
5+
Your project has a direct dependency on both `sass` and `node-sass`, two
6+
different package that both compile Sass files!
7+
8+
Next.js will only use one of these, so it is suggested you remove one or the
9+
other.
10+
11+
#### Possible Ways to Fix It
12+
13+
The `sass` package is a modern implementation of Sass in JavaScript that
14+
supports all the new features and does not require any native dependencies.
15+
16+
Since `sass` is now the canonical implementation, we suggest removing the older
17+
`node-sass` package, which should speed up your builds and project install time.
18+
19+
**Via npm**
20+
21+
```bash
22+
npm uninstall node-sass
23+
```
24+
25+
**Via Yarn**
26+
27+
```bash
28+
yarn remove node-sass
29+
```
30+
31+
### Useful Links
32+
33+
- [`sass` package documentation](https://github.com/sass/dart-sass)

packages/next/cli/next-dev.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,18 @@ const nextDev: cliCommand = (argv) => {
9191
)
9292
}
9393
}
94+
95+
const [sassVersion, nodeSassVersion] = await Promise.all([
96+
getPackageVersion({ cwd: dir, name: 'sass' }),
97+
getPackageVersion({ cwd: dir, name: 'node-sass' }),
98+
])
99+
if (sassVersion && nodeSassVersion) {
100+
Log.warn(
101+
'Your project has both `sass` and `node-sass` installed as dependencies, but should only use one or the other. ' +
102+
'Please remove the `node-sass` dependency from your project. ' +
103+
' Read more: https://err.sh/next.js/duplicate-sass'
104+
)
105+
}
94106
}
95107

96108
const port = args['--port'] || 3000
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
!node_modules

test/integration/cli/duplicate-sass/node_modules/node-sass/index.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/integration/cli/duplicate-sass/node_modules/node-sass/package.json

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/integration/cli/duplicate-sass/node_modules/sass/index.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/integration/cli/duplicate-sass/node_modules/sass/package.json

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"dependencies": {
3+
"node-sass": "*",
4+
"sass": "*"
5+
}
6+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function Home() {
2+
return <p>Hello</p>
3+
}

test/integration/cli/test/index.test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const dirOldReact = join(__dirname, '../old-react')
1818
const dirOldReactDom = join(__dirname, '../old-react-dom')
1919
const dirExperimentalReact = join(__dirname, '../experimental-react')
2020
const dirExperimentalReactDom = join(__dirname, '../experimental-react-dom')
21+
const dirDuplicateSass = join(__dirname, '../duplicate-sass')
2122

2223
describe('CLI Usage', () => {
2324
describe('no command', () => {
@@ -295,6 +296,22 @@ describe('CLI Usage', () => {
295296

296297
await killApp(instance)
297298
})
299+
300+
test('duplicate sass deps', async () => {
301+
const port = await findPort()
302+
303+
let stderr = ''
304+
let instance = await launchApp(dirDuplicateSass, port, {
305+
stderr: true,
306+
onStderr(msg) {
307+
stderr += msg
308+
},
309+
})
310+
311+
expect(stderr).toMatch('both `sass` and `node-sass` installed')
312+
313+
await killApp(instance)
314+
})
298315
})
299316

300317
describe('export', () => {

0 commit comments

Comments
 (0)