前端工程化-基于Taro的Web端Monorepo架构改造
前端工程化-Genebox小程序端Monorepo架构改造中介绍了在使用Taro框架下,结合yarn workspace + lerna 来改造Monorepo架构的方式和流程,这篇文章与本篇文章内容有很大关联,未阅读的可以先查看前端工程化-Genebox小程序端Monorepo架构改造。
使用Taro框架来进行小程序开发主要因素为实现多端代码的复用。比如 Web、RN等。如何将当前Monorepo架构下的代码编译到Web端呢?
在Web端的改造中,仍然采用小程序改造下的引用不同lerna模块下的页面路由方式规则
主入口路由命名规则:@pkg/pages/login
分包入口路由命名规则:@pkg/list/index
样式
小程序端采用CSSModule的样式方式编写,为了在原有小程序端基础上支持H5的样式编译,需要在项目的config/index下添加如下代码
h5: {publicPath: '/',staticDirectory: 'static',postcss: {autoprefixer: {enable: true,config: {},},// css modules 功能开关与相关配置cssModules: {enable: true, // 默认为 false,如需使用 css modules 功能,则设为 trueconfig: {namingPattern: 'module', // 转换模式,取值为 global/module,下文详细说明generateScopedName: '[name]__[local]___[hash:base64:5]',},},},},
跨平台开发
Taro 在编译时提供了一些内置的环境变量来帮助用户做一些特殊处理。
process.env.TARO_ENV:用于判断当前的编译平台类型。取值:weapp / swan / alipay / tt / qq / jd / h5 / rn
可以通过这个变量来区分不同环境,从而使用不同的逻辑。在编译阶段,会移除不属于当前编译类型的代码,只保留当前编译类型下的代码,例如:
1. 在微信小程序和 H5 端分别引用不同资源:
if (process.env.TARO_ENV === 'h5') {} else if (process.env.TARO_ENV === 'weapp') {}
不要解构 process.env 来获取环境变量,请直接以完整书写的方式(process.env.TARO_ENV)来进行使用。
2. 多端组件
├── test.js Test 组件默认的形式,编译到微信小程序、百度小程序和 H5 之外的端使用的版本
├── test.weapp.js Test 组件的微信小程序版本
├── test.swan.js Test 组件的百度小程序版本
└── test.h5.js Test 组件的 H5 版本
3. 多端脚本逻辑
原则就是多端文件对外的接口保持一致。例如微信小程序上使用 Taro.setNavigationBarTitle 来设置页面标题,H5 则是使用 document.title。那么我们可以封装一个 setTitle 方法来抹平两个平台的差异。
set_title.weapp.js
import Taro from '@tarojs/taro'
export default function setTitle (title) {Taro.setNavigationBarTitle({title})
}
set_title.h5.js
export default function setTitle (title) {document.title = title
}
import setTitle from '../utils/set_title'setTitle('页面标题')
webpack-runner
在小程序端下,我们通过修改@tarojs/mini-runner目录中的 MiniPlugin.js 源码支持了Monorepo架构下的小程序端代码编译。
为支持在Taro编译到Web端时支持 Lerna 不同模块的引入,同样我们需要通过修改@tarojs/webpack-runner目录中的 MainPlugin.js 源码支持了Monorepo架构下的Web端代码编译。
diff --git a/node_modules/@tarojs/webpack-runner/dist/plugins/MainPlugin.js b/node_modules/@tarojs/webpack-runner/dist/plugins/MainPlugin.js
index ca6f4c5..28f7e72 100644
--- a/node_modules/@tarojs/webpack-runner/dist/plugins/MainPlugin.js
+++ b/node_modules/@tarojs/webpack-runner/dist/plugins/MainPlugin.js
@@ -95,10 +95,15 @@ class MainPlugin {}const { framework } = this.options;this.pages = new Set([
- ...appPages.map(item => ({
- name: item,
- path: helper_1.resolveMainFilePath(path.join(this.options.sourceDir, item), helper_1.FRAMEWORK_EXT_MAP[framework])
- }))
+ ...appPages.map(item => {
+ const pagePath = helper_1.resolveMainFilePath(path.join(this.options.sourceDir, item), helper_1.FRAMEWORK_EXT_MAP[framework]);
+ return {
+ name: item.replace('@pkg/', ''),
+ path: pagePath.includes('@pkg')
+ ? pagePath.replace(/projects\/.*\/src\/@pkg\/pages/, 'packages/pages/src')
+ : pagePath, // 兼容从packages中引用的页面文件
+ };
+ })]);this.getSubPackages();}
@@ -123,8 +128,10 @@ class MainPlugin {if (!hasPageIn) {const pagePath = helper_1.resolveMainFilePath(path.join(this.options.sourceDir, pageItem), helper_1.FRAMEWORK_EXT_MAP[framework]);this.pages.add({
- name: pageItem,
- path: pagePath
+ name: pageItem.replace('@pkg/', ''),
+ path: pagePath.includes('@pkg')
+ ? pagePath.replace(/projects\/.*\/src\/.*\/@pkg/, `packages/pages/src/${root}`) // 分包包名作为寻找路径
+ : pagePath, // 兼容从packages中引用的页面文件});// eslint-disable-next-line no-unused-expressions(_a = this.appConfig.pages) === null || _a === void 0 ? void 0 : _a.push(pageItem);
与小程序端的修改思路大致一样,在解析app.config下的pages时,对命名到文件的路径进行映射。
taro-lodaer
taro-loader中的h5.js文件下主要负责了Web端路由的初始化创建配置和文件之间的引入。同样需要对pages的解析做映射调整,使其能够正确解析Monorepo对应目录下的文件。
diff --git a/node_modules/@tarojs/taro-loader/lib/h5.js b/node_modules/@tarojs/taro-loader/lib/h5.js
index 193413e..e9f6ba5 100644
--- a/node_modules/@tarojs/taro-loader/lib/h5.js
+++ b/node_modules/@tarojs/taro-loader/lib/h5.js
@@ -5,13 +5,30 @@ const path_1 = require("path");const utils_1 = require("./utils");function genResource(path, pages, loaderContext) {const stringify = (s) => loader_utils_1.stringifyRequest(loaderContext, s);
+ // 兼容从packages中引用的页面文件
+ let tempPath = path.replace(/@pkg\//g, ''); // 用于router映射
+ let loadPath = undefined; // 真实文件路径
+ // 此处需要分别处理主包和分包情况
+ const externalModuleTag = path.indexOf("@pkg");
+ if(externalModuleTag > 0) {
+ // 分包模块
+ // report/@pkg => pages/src/report
+ loadPath = path_1.join('', ('pages/src/' + path).replace(/@pkg\//g, ''));
+ } else if (externalModuleTag === 0) {
+ // 主包模块
+ loadPath = path_1.join('', path.replace(/@pkg\/pages/g, 'pages/src'));
+ } else {
+ // 内部工程模块
+ tempPath = path;
+ loadPath = path_1.join(loaderContext.context, tempPath);
+ }return `Object.assign({
- path: '${path}',
+ path: '${tempPath}',load: function() {
- return import(${stringify(path_1.join(loaderContext.context, path))})
+ return import(${stringify(loadPath)})}
- }, require(${stringify(pages.get(path))}).default || {}),
+ }, require(${stringify(pages.get(path.replace(/@pkg\//g, '')))}).default || {}),`;}function default_1() {
前端工程化-基于Taro的Web端Monorepo架构改造相关推荐
- websocket 发送图片_基于WebSocket的web端IM即时通讯应用的开发
基于WebSocket的web端IM即时通讯应用的开发 功能列表: 1.Web端的IM即时通讯应用 2.支持上线.下线.实时在线提醒 3.单聊.群聊的建立 4.普通文字.表情.图片的传输(子定义富文本 ...
- 前端系列——vue2+高德地图web端开发(poi搜索两种方式)
前端系列--vue2+高德地图web端开发(poi搜索) 前言 基础 什么是poi搜索 1. 输入提示结合poi搜索 官方代码 步骤 1.进行plugins插件注册 2.data中编写placeSea ...
- 现代前端工程化-基于 Monorepo 的 lerna 模块(从原理到实战)
本文你能学到什么? 看完本文后希望可以检查一下图中的内容是否都掌握了,文中的例子最好实际操作一下,下面开始正文. 本文是前端工程化系列中的一篇,回不断更新,下篇更新内容可看文末的下期预告!宗旨:工程化 ...
- 前端系列——vue2+高德地图web端开发(使用和引入)
vue2+高德地图web端开发(使用和引入) 前言 基础 准备工作 高德地图的个人开发者注册 高德api网址 1.点击进行注册 2.注册完之后进入控制台 3.创建新应用 4.添加 高德 2.0 新增 ...
- 使用flask实现基于elasticsearch的web端搜索功能
概述 干这个远程实习也有一个月了,感觉还不错,一天200的薪资对于一个在校大学生来讲已经不低了.上一周,领导布置了这一周的新的任务.大致要求就是做一个web端的搜索页面,大致逻辑如下图所示: 首先呢, ...
- 前端系列——vue2+高德地图web端开发(行政区边界绘制)
vue2+高德地图web端开发(行政区边界绘制) 前言 原理 基础 实现步骤 1.eslint设置AMap为全局变量放置报错 2.Search.vue传输给MapContainer.vue数据然后进行 ...
- Deployer php自动部署,基于 deployer 的 Web 端自动部署
命令行端的deployer是无状态,对于每一个项目想要查看发布的记录是一件很难受的一件事,因此有了此项目 效果预览 项目列表 新建服务器 新建任务 新建项目 发布项目 ajax轮询展示项目部署状态 i ...
- web前端新手入门教程:Web 框架的架构模式探讨
在写干货之前,我想先探(qiang)讨(diao)两个问题,模式的局限性?模式有什么用? 最近看到一篇文章对我启发很大,许来西在知乎的回答<哲学和科学有什么关联?>,全篇较长,这里摘录我要 ...
- 架构 | 前后端分离与前端工程化
文章目录 前言 前后端分离 核心 对开发行为和职责的直接影响 前端工程化 本地代理与ngix反向代理 node是什么,有什么特点,与前后端分离,前端工程化的关系 node,npm,package.js ...
最新文章
- 最近喜欢用markdown写笔记,贴个语法说明
- [Android官方API阅读]___Application Fundamentals
- SpingBoot-Thymeleaf-bootstrapTable-分页之H5
- mysql segmentation fault_mysql Segmentation fault的问题,求教
- Maven的个性化定制
- 数据结构为什么那么难?
- 管理和维护RHCS集群
- yum -y list java* 缓存加载不了_Java开发面试宝典:分布式相关篇
- Linux中的文件查找技巧
- 如何通过 Shell 监控异常等待事件和活跃会话
- 分布式mysql 不支持存储过程_分布式数据库VoltDB对存储过程的支持
- lzugis——Arcgis Server for JavaScript API在自己的定义InfoWindow
- java生成word带多级标题,word自动生成多级标题的方法
- MVX Android设计架构浅析-MVP
- Python正态云发生器
- 初识Uniprot API
- 微信中无法直接下载秒借类金融贷款APP的解决方案
- 深度学习入门 (九):卷积层和池化层的实现
- PyCharm安装教程最新版(社区版)
- 005_wz_bbk_-v详细信息,-c生成中间文件,链接次序