使用 CSS-in-JS

linaria

在 React 社区有一个著名的 CSS-in-JS 解决方案: styled-components。但遗憾的是,styled-components 使用 <style> 标签来动态地控制样式,在小程序没有类似的方案。但我们可以通过 linaria 实现同样的功能,linaria 主要提供以下特性:

  • 近似于 styled-components 的 API
  • 完整的 TypeScript 支持
  • 零运行时

使用 linaria 也非常简单,首先通过 NPM 安装依赖:

  1. $ npm i linaria

其次配置项目根目录的 babel.config.js:

babel.config.js

  1. module.exports = {
  2. presets: [
  3. ['taro', {
  4. framework: 'react',
  5. ts: true
  6. }],
  7. 'linaria/babel' // 添加到 babel-preset
  8. ]
  9. }

之后配置 config/index.js

config/index.js

  1. const config = {
  2. mini: {
  3. webpackChain(chain, webpack) {
  4. // linaria/loader 选项详见 https://github.com/callstack/linaria/blob/master/docs/BUNDLERS_INTEGRATION.md#webpack
  5. chain.module
  6. .rule('script')
  7. .use('linariaLoader')
  8. .loader('linaria/loader')
  9. .options({
  10. sourceMap: process.env.NODE_ENV !== 'production',
  11. })
  12. }
  13. },
  14. h5: {
  15. webpackChain(chain, webpack) {
  16. chain.module
  17. .rule('script')
  18. .use('linariaLoader')
  19. .loader('linaria/loader')
  20. .options({
  21. sourceMap: process.env.NODE_ENV !== 'production',
  22. })
  23. }
  24. }
  25. }

最后在项目根目录新建 linaria.config.js

linaria.config.js

  1. // linaria 配置详见 https://github.com/callstack/linaria/blob/master/docs/CONFIGURATION.md#options
  2. module.exports = {
  3. rules: [
  4. {
  5. action: require("linaria/evaluators").shaker,
  6. },
  7. {
  8. test: /node_modules[\/\\](?!@tarojs)/,
  9. action: "ignore"
  10. }
  11. ]
  12. }

在业务代码中我们可以这样使用:

  • JavaScript
  • TypeScript
  1. import React from 'react'
  2. import { View } from '@tarojs/components'
  3. import { styled } from 'linaria/react'
  4. const Title = styled(View)`
  5. color: ${props => props.color}
  6. `;
  7. const Index = () => {
  8. return <Title color='red'>
  9. Hello World!
  10. </Title>
  11. }
  12. export default Index
  1. import React from 'react'
  2. import { View } from '@tarojs/components'
  3. import { styled } from 'linaria/react'
  4. const Title = styled(View)<{ color: string }>`
  5. color: ${props => props.color}
  6. `;
  7. const Index: React.FC = () => {
  8. return <Title color='red'>
  9. Hello World!
  10. </Title>
  11. }
  12. export default Index

Fower

社区还有另一个方案 Fower文档