@haici/taro-inject-loader

众所周知,小程序中不能定义全局组件,如果我们想自定义一个 modal 弹窗,来替代 wx.showModal 的话,则需要在每个页面手动的引入组件。随着项目越来越大,手动引入组件无疑是繁琐和低效的,因而抽空开发了这个 webpack-loader 代替手动操作。

Usage no npm install needed!

<script type="module">
  import haiciTaroInjectLoader from 'https://cdn.skypack.dev/@haici/taro-inject-loader';
</script>

README

Taro React 小程序注入全局组件

缘由

众所周知,小程序中不能定义全局组件,如果我们想自定义一个 modal 弹窗,来替代 wx.showModal 的话,则需要在每个页面手动的引入组件。随着项目越来越大,手动引入组件无疑是繁琐和低效的,因而抽空开发了这个 webpack-loader 代替手动操作。

作用

为每个页面注入全局组件。支持主包和分包,支持类写法和函数写法。

环境

taro react

安装

npm install taro-inject-component-loader -D

配置

配置项

字段 必填 默认 含义
importPath 导入路径
isPage (path) => /(package-.+/)?pages/.+/index.[tj]sx$/.test(path) 判断当前文件是不是页面

isPage 不传的情况下,默认会将 src/pages/页面名称/index.[tj]sxsrc/package-模块名称/pages/页面名称/index.[tj]sx 这两种情形下的文件识别为页面。

语法支持

下面提到的写法中,都支持注入组件。

// 导出匿名函数
export default function() {
  return <View></View>
}

// 导出具名函数
export default function A() {
  return <View></View>
}

// 导出匿名箭头函数
export default () => {
  return <View></View>
}

export default () => <View></View>

// 导出匿名类
export default class {
  render() {
    return <View></View>
  }
}

// 导出具名类
export default class A {
  render() {
    return <View></View>
  }
}

此外,还可以使用表达式导出

// 导出普通函数
function A() {
  return <View></View>
}

const A = function() {
  return <View></View>
}

// 导出箭头函数
const A = () => {
  return <View></View>
}
const A = () => <View></View>

// 导出类
class A {
  render() {
    return <View></View>
  }
}

const A = class {
  render() {
    return <View></View>
  }
}

const A = class extends Component {
  render() {
    return <View></View>
  }
}

export default A

效果

源代码

页面组件

<!----src/pages/index.tsx----->
import { View } from '@taro/components'

export default function Index() {
  return <View>哈哈哈哈哈</View>
}

要注入的组件

<!----src/components/BaseComponent.tsx----->
import { View } from '@taro/components'

export default function () {
  return <View>WebpackInject</View>
}

进行配置

  webpackChain(chain) {
    chain.merge({
      module: {
        rule: {
          injectBaseComponentLoader: {
            test: /\.tsx$/,
            use: [
              {
                loader: 'taro-inject-component-loader',
                options: {
                  importPath: '@components/BaseComponent',
                  isPage(filePath) {
                    return /(package-.+\/)?pages\/.+\/index\.tsx$/.test(filePath)
                  }
                },
              },
            ],
          },
        },
      },
    });
  },

注入后的代码

会自动注入为页面根节点的最后一个子元素

import { View } from '@taro/components'
import WebpackInject from '@components/BaseComponent'

export default function Index() {
  return (
    <View>
      哈哈哈哈哈
      <WebpackInject />
    </View>
  )
}

注意事项

要注入的组件需要默认导出

import { View } from '@taro/components'

// 默认导出
export default () => <View></View>

跳过代码注入

只要检测到页面里有 importPath 的路径,无论代码中有没有用到该组件,都不会自动注入。

import { View } from '@taro/components'
// 因为检测到了手动从 importPath 路径导入组件, 所以不会注入组件
import WebpackInject from 'importPath'

export default () => <View></View>

代码示例

ts 版本

js 版本