npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

uni-pages-hot-modules

v1.0.3

Published

解决uni-app的pages.json无法模块化的问题,并且解决模块热重载和缓存的问题

Downloads

301

Readme

uni-pages-hot-modules

uni-app的pages.json的模块化及模块热重载

解决uni-app的pages.json无法模块化的问题,并且解决模块热重载和缓存的问题

安装

npm i uni-pages-hot-modules -S

uni-app vite版本(vue3)示例项目
uni-app webpack版本(vue2)示例项目

uniapp 版本分界线说明

vue3 vite版本 使用说明

uniapp vue3 vite版本已不再默认支持pages.js的钩子,所以uni-pages-hot-modules的使用方式转变为直接在pages.json中通过特殊的条件编译命令插入js入口,一种非常cool的使用方式!

{
  "pages": /* #exec hotJs('./page_modules/index.js') */,
  "subPackages": /* #exec hotJs('./subpackage_modules/index.js'') */,
  "globalStyle": {
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "uni-app",
    "navigationBarBackgroundColor": "#F8F8F8",
    "backgroundColor": "#F8F8F8"
  }
}

或者直接将整个pages.json都托管到一个js中,比如托管给pages.js,那么直接将整个pages.json的内容设置成如下的一行注释即可

// #exec hotJs('./pages.js')

然后在pages.json相同的路径下建立pages.js

// /src/pages.js
module.exports = {
    pages: require('./page_modules/index.js'),
    subPackages: require('./subpackage_modules/index.js'),
    globalStyle: {
        navigationBarTextStyle: 'black',
        navigationBarTitleText: 'uni-app',
        navigationBarBackgroundColor: '#F8F8F8',
        backgroundColor: '#F8F8F8'
    }
}

注意!

所有插入pages.json的js(包括这些js依赖的其他js)都必须是commonJs规范
适用于uniapp vue3 vite版本的uni-pages-hot-modules版本要求>=1.0.0
所有插入pages.json的js(包括这些js依赖的其他js)不支持uniapp的条件编译,替代方案是直接通过js判断uniapp的条件编译变量

如何获取uniapp的条件编译变量

// /src/pages.js
// 获取uniapp的条件编译环境变量
const uniContext = require('@dcloudio/uni-cli-shared/dist/preprocess/context').getPreVueContext()
module.exports = {
    pages: require('./page_modules/index.js'),
    subPackages: require('./subpackage_modules/index.js'),
    globalStyle: {
        navigationBarTextStyle: 'black',
        // 判断是否是H5环境
        navigationBarTitleText: uniContext.H5 ? 'H5环境' : '非H5环境',
        navigationBarBackgroundColor: '#F8F8F8',
        // 判断是否是微信小程序环境
        backgroundColor: '#F8F8F8'
    }
}

前置配置

要使pages.json中可以使用特殊的条件编译命令,需要配置项目根目录中的vite.config.js

// vite.config.js
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'

// 引入uni-pages-hot-modules
import uniHot from 'uni-pages-hot-modules'
// 安装条件编译命令,安装之后,uniapp就会支持exec hotJs的条件编译
uniHot.setupHotJs()
// 也可以自定义条件编译的方法名
// 以下执行的结果,在条件编译中将变成exec customJsFun
// uniHot.setupHotJs('customJsFun')

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    uni(),
    // 注册uni-pages-hot-modules的热更新vite插件
    uniHot.createHotVitePlugin(),
  ],
})

API

hotJs (通过条件编译使用在pages.json中,也可以自定义名称)

uniapp的条件编译是借鉴preprocess插件,因此具备#exec命令
hotJs引入的js的module.exports的结果将通过JSON.stringify直接呈现在pages.json中
使用前提条件,必须在vite.config.js中配置完成setupHotJscreateHotVitePlugin

// 在pages.json中可使用
/* #exec hotJs('./other.js') */
// #exec hotJs('./other.js')

require.context (在pages.json依赖的js中使用,见vue2 webpack版本的说明)

模拟webpack的require.context,读取指定路径下符合条件的所有文件


vue2 webpack版本 使用说明

注意!

  • 发现uni-app每次更新对pages.js的支持度会不同,比如某个版本竟然注释掉了对pages.js的热重载依赖,这里做了兼容。只要uni-app不推翻自己的设计,此功能长久有效
  • 使用uni-pages-hot-modules引入模块必须输入全的文件名包括后缀,否则将不会进行热重载

uni-pages-hot-modules做了什么

// 做了非常轻便的事情,相当于
loader.addDependency(modulePath)
delete require.cache[modulePath]
require(modulePath)

uni-app的“彩蛋”

uni-app自带一个webpack loader钩子文件pages.js,在项目src目录下建立pages.js(与pages.json同级)即可生效(pages.json仍然需要存在,作为初始值,建议存放一些和路由无关的配置)。
pages.js要求CommonJS规范,直接通过module.exports输出一个钩子函数。

pages.js输出的函数参数

pagesJson < Object >

pages.json的解析内容

loader < Object > (无需关心)

uni-pages-loader的钩子属性,{ addDependency < Function > }

addDependency (无需关心)

用于手动为uni-pages-loader添加依赖模块

pages.js的模块化

由于是js,就可以实现模块的依赖,如果不考虑模块的热重载问题,可以不使用hot高阶函数
但是大多数情况下,需要依赖的模块也可以通过热重载更新pages.js,由于不是webpack的标准运行依赖,所以需要手动添加依赖项(使用addDependency),并且需要每次清除模块的缓存,因此uni-pages-hot-modules就诞生了

pages.js示例

const { hot } = require('uni-pages-hot-modules')
module.exports = hot((pagesJson) => {
    let basePages = []
    let baseSubPackages = []

    return {
        // 合并pages.json的内容
        ...pagesJson,
        pages:[
            ...basePages,
            ...require('./page_modules/tabbar.js'),
            ...require('./page_modules/component.js'),
            ...require('./page_modules/appPlus.js'),
            ...require('./page_modules/module1.js')
        ],
        subPackages:[
            ...baseSubPackages,
            ...require('./subpackage_modules/api.js'),
            ...require('./subpackage_modules/extUI.js'),
            ...require('./subpackage_modules/template.js')
        ]
    }
})

模块的规范

被加载的模块也是CommonJS规范,通过module.exports输出

module1.js示例

module.exports=[
   {
       "path": "pages/sub/sub",
       "style": {
           "navigationBarTitleText": "sub"
       }
   },
   // 在模块里继续引入其他子模块
   ...require('./some-sub-module1.js')
]

API

context {function}

模拟webpack的require.context
与webpack不同的地方是不会将调用此方法的模块输出,没有id属性,resolve方法返回绝对路径

const files = require.context('.', true, /\.js$/)
const modules = []
files.keys().forEach(key => {
    if (key === './index.js') return
    const item = files(key)
    modules.push(...item)
})
module.exports = modules

缺陷:require.context是模拟的,所以在支持热更新时也有一定缺陷,就是新创建的文件不支持热更新,需要重新编译即可(或者手动触发一次调用require.context的文件的更新也可以达到对新文件的热更新激活),删除和修改原有文件可以很好的支持热更新

其他

不支持条件编译,需要自己通过process.env.VUE_APP_PLATFORM来判断(不建议使用process.env.UNI_PLATFORM,因为在webpack客户端包里无法读取此环境变量,除非设置DefinePlugin),自定义环境的需要自己添加env变量来判断