taro
taro copied to clipboard
两个页面不能共用一个公共组件
相关平台
微信小程序
复现仓库
https://github.com/shide-L/taro 小程序基础库: 2.14.0 使用框架: React
复现步骤
都是微信小程序下
- 2个页面 pageA,pageB,都使用同一个组件的话,另外一个pageB页面会非正常显示,scss没有加载
- demo部分的页面都引入同一个组件,非正常显示了,只要注释其中一个即可
期望结果
能实现组件跨页面复用
实际结果
不能复用,非正常显示或者是打包的时候没有把sacc中的样式
环境信息
Taro CLI 3.0.13 environment info:
System:
OS: macOS 10.14.5
Shell: 5.3 - /bin/zsh
Binaries:
Node: 10.16.3 - /usr/local/bin/node
Yarn: 1.19.1 - /usr/local/bin/yarn
npm: 6.14.8 - /usr/local/bin/npm
npmPackages:
@tarojs/components: 3.0.13 => 3.0.13
@tarojs/mini-runner: 3.0.13 => 3.0.13
@tarojs/react: 3.0.13 => 3.0.13
@tarojs/runtime: 3.0.13 => 3.0.13
@tarojs/taro: 3.0.13 => 3.0.13
@tarojs/webpack-runner: 3.0.13 => 3.0.13
babel-preset-taro: 3.0.13 => 3.0.13
eslint-config-taro: 3.0.13 => 3.0.13
react: ^16.10.0 => 16.14.0
taro-ui: ^3.0.0-alpha.3 => 3.0.0-alpha.3
npmGlobalPackages:
typescript: 3.6.4
同样的问题, 但是我是两个页面元素都不显示, 变成空白页面了 taro3.0.17
@shide-L @myxmxy1234 使用 demo 在 3.0.17 中一开始复现了,后续不断修改若干次代码后突然好了,然后把代码恢复最初,再没有复现了,可以试试重新编译,或重启开发者工具试试。

截图只是把这两处注释取消后运行得出:

@Chen-jj , @shide-L 我今天也遇到这个问题的。然后分析了一下:
- 单页面引用组件时,组件的样式会直接被写入到页面的 wxss 中;
- 多页面引用组件时,组件的样式会被抽成公共样式并被放在 common.wxss 中;
然后出现「多页面引用同一组件后,组件样式失效」的原因是「common.wxss」这个文件并不是微信小程序的「公共样式」!!!!微信小程序的公共样式是「app.wxss」。
然后这里的问题来了,为什么 Taro 要把公共样式放在「common.wxss」上,而不是「app.wxss」呢? 这个只能找「Taro之父」聊聊了。
说一下解决怎么解决这个问题的方法其实很简单:在 src 下创建 app.scss ,然后在 app.tsx/app.jsx 中引用这个文件就好了,如下:
// app.jsx
import './app.scss';
// app.scss
.global-app {};
结论与建议
这个问题可能跟开发的习惯有关,有些开发会有引入公共样式的习惯,有些开发没有。如果没有引用公共样式的话,又有代码洁癖的人会把 app.jsx 上引入 的 「import './app.scss」删除,然后问题就会出现。Taro 是在编译后在「app.wxss」用「@import './common.wxss」引入。但是如果我们在 app.jsx 中没有「import './index.scss」,Taro 在编译后也不会生成「app.wxss」,结果就是「common.wxss」也没有被引入了。
建议 Taro 默认都生成一个「app.wxss」避免类似问题
@Chen-jj , @shide-L 我今天也遇到这个问题的。然后分析了一下:
- 单页面引用组件时,组件的样式会直接被写入到页面的 wxss 中;
- 多页面引用组件时,组件的样式会被抽成公共样式并被放在 common.wxss 中;
然后出现「多页面引用同一组件后,组件样式失效」的原因是「common.wxss」这个文件并不是微信小程序的「公共样式」!!!!微信小程序的公共样式是「app.wxss」。
然后这里的问题来了,为什么 Taro 要把公共样式放在「common.wxss」上,而不是「app.wxss」呢? 这个只能找「Taro之父」聊聊了。
说一下解决怎么解决这个问题的方法其实很简单:在 src 下创建 app.scss ,然后在 app.tsx/app.jsx 中引用这个文件就好了,如下:
// app.jsx import './app.scss';// app.scss .global-app {};结论与建议
这个问题可能跟开发的习惯有关,有些开发会有引入公共样式的习惯,有些开发没有。如果没有引用公共样式的话,又有代码洁癖的人会把 app.jsx 上引入 的 「import './app.scss」删除,然后问题就会出现。Taro 是在编译后在「app.wxss」用「@import './common.wxss」引入。但是如果我们在 app.jsx 中没有「import './index.scss」,Taro 在编译后也不会生成「app.wxss」,结果就是「common.wxss」也没有被引入了。
建议 Taro 默认都生成一个「app.wxss」避免类似问题
找了2天样式失效的问题,终于找到了,太坑了 感谢🙏
@Chen-jj , @shide-L 我今天也遇到这个问题的。然后分析了一下:
- 单页面引用组件时,组件的样式会直接被写入到页面的 wxss 中;
- 多页面引用组件时,组件的样式会被抽成公共样式并被放在 common.wxss 中;
然后出现「多页面引用同一组件后,组件样式失效」的原因是「common.wxss」这个文件并不是微信小程序的「公共样式」!!!!微信小程序的公共样式是「app.wxss」。
然后这里的问题来了,为什么 Taro 要把公共样式放在「common.wxss」上,而不是「app.wxss」呢? 这个只能找「Taro之父」聊聊了。
说一下解决怎么解决这个问题的方法其实很简单:在 src 下创建 app.scss ,然后在 app.tsx/app.jsx 中引用这个文件就好了,如下:
// app.jsx import './app.scss';// app.scss .global-app {};结论与建议
这个问题可能跟开发的习惯有关,有些开发会有引入公共样式的习惯,有些开发没有。如果没有引用公共样式的话,又有代码洁癖的人会把 app.jsx 上引入 的 「import './app.scss」删除,然后问题就会出现。Taro 是在编译后在「app.wxss」用「@import './common.wxss」引入。但是如果我们在 app.jsx 中没有「import './index.scss」,Taro 在编译后也不会生成「app.wxss」,结果就是「common.wxss」也没有被引入了。
建议 Taro 默认都生成一个「app.wxss」避免类似问题
使用css modules如何操作呢,这种方法还是不奏效。。
@maroon1 请问一下使用css module如何处理这种情况呢?
@lxsunbin 我使用的是 CSS in JS 方案,所以不确定 CSS Module 方案是否有什么不一样,不过请确保代码中按以下方法做了
在 src 下创建 app.scss ,然后在 app.tsx/app.jsx 中引用这个文件
可以看看代码生成结果中是否正确引用了 common.wxss 以确定我们遇到的是同样问题
@lxsunbin 我使用的是 CSS in JS 方案,所以不确定 CSS Module 方案是否有什么不一样,不过请确保代码中按以下方法做了
在 src 下创建 app.scss ,然后在 app.tsx/app.jsx 中引用这个文件
可以看看代码生成结果中是否正确引用了
common.wxss以确定我们遇到的是同样问题
以确定这些都正常,就是样式没有生效。。
@lxsunbin 最好可以提供一个最小的可复现的代码
我这里遇到Taro混编到支付宝小程序中,多个页面不能用同一个组件的问题。各位大佬有解决吗?
在原生支付宝小程序项目里混编时也遇到了相同的问题。taro 3.4.2
我们的解决方案是在支付宝项目的 app.acss 里引入 taro 的 app.acss
@import "taro/app.acss"
没有使用 common 的方式,只是正常将一个 component 被 2 个 page 引用,就空白了。
写了一个plugin暂时程序添加一下引用,对小程序插件开发影响很大啊,插件根本没有app.wxss- -
const { ConcatSource } = require('webpack-sources')
const Regexp = /(?<=plugin\/(components|pages))\/.+\.wxss/g
class WxssImportPlugin {
apply(compiler) {
compiler.hooks.emit.tapAsync(
'WxssImportPlugin',
(compilation, callback) => {
// Do something async...
// 寻找 plugin/page 文件下 的wxss文件
for (let [name, assets] of Object.entries(compilation.assets)) {
if (Regexp.test(name)) {
// 找路径下有几个/
const times = name.split('/').length - 2
// 创建首行引用语句 @import '../../common.wxss'
const firstLine = `@import '${Array(times).fill('../').join('') + 'common.wxss'}';\n`
compilation.assets[name] = new ConcatSource(firstLine + assets.source())
}
}
callback()
}
);
}
}
module.exports = WxssImportPlugin
同样的问题, 但是我是两个页面元素都不显示, 变成空白页面了 taro3.0.17
同样的问题,请问有解决方案了嘛
Taro v3.6.8 修复:
- buildNativeComp 模式下,为各组件自动引入 common 公共样式
- 当开发者没有全局样式文件时,仍能正确引入 common 公共样式
没有使用 common 的方式,只是正常将一个 component 被 2 个 page 引用,就空白了。
+1 解决了吗
没有使用 common 的方式,只是正常将一个 component 被 2 个 page 引用,就空白了。
已解决。我使用的 less 构建样式表,组件内使用 xxx.less 顶部使用了 @import (once) 'xxx.less' 去掉 once 就可以正常加载了。虽然不知道原因是什么