如何使用 react 和 next 处理`module.scss`?

时间:2021-06-12 13:20:06

标签: javascript css reactjs sass next.js

我很失落。

对于上下文,我使用 Next 和 React。

// package.json
  "dependencies": {
    "@netlify/plugin-nextjs": "^3.4.2",
    "next": "^10.0.0",
    "postcss-flexbugs-fixes": "^5.0.2",
    "postcss-preset-env": "^6.7.0",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-onclickoutside": "^6.11.2",
    "react-svg": "14.0.0"
  },
  "devDependencies": {
    "classnames": "^2.2.6",
    "sass": "^1.34.0"
  }

我使用 npx next build && npx next start -p 4000 在本地测试生产。使用 netlify dev -e 在开发中一切正常。

有奇怪的效果。当我有两个 .module.scss 导入时,客户端 javascript 就会停止。

我有一个页面:

// /pages/test.js
import CompA from 'components/comp-a'
import CompB from 'components/comp-b'

还有:

// /components/comp-a.js
import styles from 'components/comp-a.module.scss`

// /components/comp-b.js
import styles from 'components/comp-b.module.scss`

这种情况在视觉上可以正确呈现,但是NO 客户端 javascript 根本没有工作,当然,没有任何错误。我花了一天时间对源代码的每个组件和行进行注释和取消注释,以缩小这种情况。

我尝试在 page 中注释掉,客户端 js 使用一个组件,而不是两个。

我尝试注释掉其中一个组件中的 styles 导入,客户端 js 也能正常工作。

它不起作用的另一种情况是:

// components/comp-a.js
import styles from 'components/comp-a.module.js'
import CompB from 'components/comp-b.module.js'

如果我评论样式或子组件之一,它就会起作用。

而且没有任何意义,因为在页面中,我还导入了 Layout,它确实包含自己的 styles 并且工作正常。

这是怎么回事???

编辑: 继续挖掘,我发现我在做 @extend .class-abc 并在顶部 @import 'style/foo.module'; ,而 .class-abc 包含另一个类:

// /style/foo.module.scss
.class-abc {
  ...
  .bar { 
    ...
  }
}

出于某种原因,注释掉 .bar 可以解决问题。不知道发生了什么。

1 个答案:

答案 0 :(得分:3)

使用 css/scss 模块的主要好处之一是您可以将样式保持在组件附近,并且所有内容都为您指定了命名空间。因此,您通常不会将 component 样式导入您的 page。稍微调整一下应该会有所帮助:

- components/
  - comp-a/
    - index.js
    - index.module.scss
  - comp-b/
    - index.js
    - index.module.scss
- pages
  // If test.js doesn't also have its own styles
  - test.js
  // Or if test.js has its own css/scss modules
  - test
    - index.js
    - index.module.scss

您的组件和页面将如下所示:

// comp-a
import styles from "./index.module.css"

export default function MyCompA() {
  return (<div className={styles.someClass}>I have local comp-a styles</div>)
}

// comp-b
import styles from "./index.module.css"

export default function MyCompB() {
  return (<div className={styles.someClass}>I have local comp-b styles</div>)
}

// test
import MyCompA from "../components/comp-a"
import MyCompB from "../components/comp-b"

// If this also has its own styles
import styles from "./index.module.scss"

export default function MyCompTestPage() {
  return (
    <>
      <p className={styles.someClass}>I have local test page styles</p>
      <MyCompA />
      <MyCompB />
    </>
  )
}

在组件之间共享样式

如果多个组件需要共享相同的样式,您通常希望 (a) 将这些样式提取到全局样式表或 (b) 将该公共代码提取到其自己的组件中或 (c) 在组件之间共享样式表。选项 c 的示例如下所示:

- components/
  - comps-ab/
    - comp-a.js
    - comp-b.js
    - index.module.scss
- pages
  - test.js
// comps-ab/comp-a
import styles from "./index.module.css"

export default function MyCompA() {
  return (<div className={styles.someClass}>I have shared comps-ab styles but still local to these components</div>)
}

// comps-ab/comp-b
import styles from "./index.module.css"

export default function MyCompB() {
  return (<div className={styles.someClass}>I have shared comps-ab styles but still local to these components</div>)
}

// test
import MyCompA from "../components/comps-ab/comp-a"
import MyCompB from "../components/comps-ab/comp-b"

export default function MyCompTestPage() {
  return (
    <>
      <MyCompA />
      <MyCompB />
    </>
  )
}

在这种情况下,您的两个组件从同一个样式表中提取,但它仍然是这两个组件的本地组件,并且不会手动带入 test.js 页面。